hacktricks/binary-exploitation/heap/unlink-attack.md

10 KiB

Atak Unlink

Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Podstawowe informacje

Kiedy ten atak został odkryty, głównie pozwalał na WWW (Write What Where), jednak dodano sprawdzenia, co sprawiło, że nowa wersja ataku stała się bardziej interesująca, ale również bardziej złożona i bezużyteczna.

Przykład kodu:

Kod ```c #include #include #include #include

// Altered from d778318b6a/assets/files/unlink_exploit.c to make it work

struct chunk_structure { size_t prev_size; size_t size; struct chunk_structure *fd; struct chunk_structure *bk; char buf[10]; // padding };

int main() { unsigned long long *chunk1, *chunk2; struct chunk_structure *fake_chunk, *chunk2_hdr; char data[20];

// First grab two chunks (non fast) chunk1 = malloc(0x8000); chunk2 = malloc(0x8000); printf("Stack pointer to chunk1: %p\n", &chunk1); printf("Chunk1: %p\n", chunk1); printf("Chunk2: %p\n", chunk2);

// Assuming attacker has control over chunk1's contents // Overflow the heap, override chunk2's header

// First forge a fake chunk starting at chunk1 // Need to setup fd and bk pointers to pass the unlink security check fake_chunk = (struct chunk_structure *)chunk1; fake_chunk->size = 0x8000; fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P

// Next modify the header of chunk2 to pass all security checks chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); chunk2_hdr->prev_size = 0x8000; // chunk1's data region size chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit

// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' // This results in chunk1 pointer pointing to chunk1 - 3 // i.e. chunk1[3] now contains chunk1 itself. // We then make chunk1 point to some victim's data free(chunk2); printf("Chunk1: %p\n", chunk1); printf("Chunk1[3]: %x\n", chunk1[3]);

chunk1[3] = (unsigned long long)data;

strcpy(data, "Victim's data");

// Overwrite victim's data using chunk1 chunk1[0] = 0x002164656b636168LL;

printf("%s\n", data);

return 0; }

</details>

* Atak nie działa, jeśli są używane tcaches (po wersji 2.26)

### Cel

Ten atak pozwala **zmienić wskaźnik do fragmentu tak, aby wskazywał 3 adresy przed samym sobą**. Jeśli nowa lokalizacja (otoczenie, gdzie znajdował się wskaźnik) zawiera interesujące rzeczy, takie jak inne kontrolowalne alokacje / stos..., możliwe jest odczytanie/nadpisanie ich w celu spowodowania większej szkody.

* Jeśli ten wskaźnik znajdował się na stosie, ponieważ teraz wskazuje 3 adresy przed samym sobą i użytkownik potencjalnie może go odczytać i zmodyfikować, będzie możliwe wyciekanie poufnych informacji ze stosu lub nawet modyfikowanie adresu powrotu (może) bez dotykania canary
* W przykładach CTF ten wskaźnik znajduje się w tablicy wskaźników do innych alokacji, dlatego, ustawiając go 3 adresy przed i mając możliwość odczytu i zapisu, można sprawić, że inne wskaźniki wskazują na inne adresy.\
Ponieważ użytkownik potencjalnie może odczytywać/zapisywać również inne alokacje, może wyciekać informacje lub nadpisywać nowe adresy w dowolnych lokalizacjach (np. w GOT).

### Wymagania

* Pewna kontrola w pamięci (np. stosie), aby utworzyć kilka fragmentów, nadając wartości niektórym atrybutom.
* Wyciek stosu w celu ustawienia wskaźników fałszywego fragmentu.

### Atak

* Istnieją dwa fragmenty (fragment1 i fragment2)
* Atakujący kontroluje zawartość fragmentu1 i nagłówki fragmentu2.
* W fragmencie1 atakujący tworzy strukturę fałszywego fragmentu:
* Aby ominąć zabezpieczenia, upewnia się, że pole `size` jest poprawne, aby uniknąć błędu: `corrupted size vs. prev_size while consolidating`
* a pola `fd` i `bk` fałszywego fragmentu wskazują tam, gdzie przechowywany jest wskaźnik fragmentu1 z przesunięciami odpowiednio -3 i -2, więc `fake_chunk->fd->bk` i `fake_chunk->bk->fd` wskazują na pozycję w pamięci (stosie), gdzie znajduje się rzeczywisty adres fragmentu1:

<figure><img src="../../.gitbook/assets/image (1245).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>

* Nagłówki fragmentu2 są modyfikowane, aby wskazywać, że poprzedni fragment nie jest używany i że rozmiar to rozmiar zawartego fałszywego fragmentu.
* Gdy drugi fragment zostanie zwolniony, to następuje odłączenie tego fałszywego fragmentu:
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* Wcześniej sprawiono, że `fake_chunk->fd->bk` i `fake_chunk->fd->bk` wskazują na to samo miejsce (lokalizację na stosie, gdzie przechowywany jest `fragment1`), więc był to poprawny lista połączona. Ponieważ **oba wskazują na tę samą lokalizację**, tylko ostatni (`fake_chunk->bk->fd = fake_chunk->fd`) będzie **działać**.
* Spowoduje to **nadpisanie wskaźnika do fragmentu1 na stosie adresem (lub bajtami) przechowywanym 3 adresy wcześniej na stosie**.
* Dlatego jeśli atakujący mógłby ponownie kontrolować zawartość fragmentu1, będzie mógł **pisać wewnątrz stosu**, mając potencjalnie możliwość nadpisania adresu powrotu, pomijając canary, oraz modyfikowania wartości i wskaźników zmiennych lokalnych. Nawet ponownie modyfikując adres fragmentu1 przechowywany na stosie na inną lokalizację, jeśli atakujący mógłby ponownie kontrolować zawartość fragmentu1, będzie mógł pisać w dowolnym miejscu.
* Należy zauważyć, że to było możliwe, ponieważ **adresy są przechowywane na stosie**. Ryzyko i eksploatacja mogą zależeć od **miejsca, gdzie są przechowywane adresy do fałszywego fragmentu**.

<figure><img src="../../.gitbook/assets/image (1246).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>

## Referencje

* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* Chociaż byłoby dziwne znalezienie ataku unlink nawet w CTF, tutaj znajdziesz kilka rozwiązań, gdzie ten atak był używany:
* Przykład CTF: [https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* W tym przykładzie zamiast stosu jest tablica adresów przydzielonych dynamicznie. Atak unlink jest wykonywany, aby możliwe było zaalokowanie fragmentu tutaj, umożliwiając kontrolowanie wskaźników tablicy adresów przydzielonych dynamicznie. Następnie istnieje inna funkcjonalność, która pozwala modyfikować zawartość fragmentów w tych adresach, co pozwala wskazywać adresy na GOT, modyfikować adresy funkcji w celu uzyskania wycieków i RCE.
* Inny przykład CTF: [https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* Tak jak w poprzednim przykładzie, istnieje tablica adresów alokacji. Możliwe jest wykonanie ataku unlink, aby sprawić, że adres pierwszej alokacji wskazuje kilka pozycji przed rozpoczęciem tablicy, a następnie nadpisać tę alokację na nowej pozycji. Dlatego możliwe jest nadpisanie wskaźników innych alokacji, aby wskazywały na GOT atoi, uzyskać wyciek libc, a następnie nadpisać atoi GOT adresem do jednego gadżetu.
* Przykład CTF z niestandardowymi funkcjami malloc i free, które wykorzystują podatność bardzo podobną do ataku unlink: [https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html)
* Istnieje przepełnienie, które pozwala kontrolować wskaźniki FD i BK niestandardowego malloc, które zostaną (niestandardowo) zwolnione. Ponadto sterta ma ustawiony bit exec, więc możliwe jest wyciekanie adresu sterty i wskazywanie funkcji z GOT na kawałek sterty z shellcodem do wykonania.

<details>

<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

Inne sposoby wsparcia HackTricks:

* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF** sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
* **Dołącz do** 💬 [**Grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>