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

10 KiB

Atak Unlink

{% hint style="success" %} Dowiedz się i praktykuj Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Dowiedz się i praktykuj Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Wesprzyj HackTricks
{% endhint %}

Podstawowe informacje

Kiedy ten atak został odkryty, głównie pozwalał na WWW (Write What Where), jednak dodano sprawdzenia, co sprawia, że nowa wersja ataku jest bardziej interesująca, ale 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 na blok tak, aby wskazywał 3 adresy przed samym sobą**. Jeśli nowa lokalizacja (otoczenie, gdzie znajdował się wskaźnik) zawiera interesujące informacje, 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ą, a użytkownik potencjalnie może go odczytać i zmodyfikować, będzie możliwe wyciekanie poufnych informacji ze stosu lub nawet modyfikacja 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ż potencjalnie użytkownik może również czytać/zapisywać inne alokacje, może wyciekać informacje lub nadpisywać nowe adresy w dowolnych lokalizacjach (np. w GOT).

### Wymagania

* Pewna kontrola pamięci (np. stos) w celu utworzenia kilku bloków, przypisując wartości do niektórych atrybutów.
* Wyciek stosu w celu ustawienia wskaźników fałszywego bloku.

### Atak

* Istnieją dwa bloki (blok1 i blok2)
* Atakujący kontroluje zawartość bloku1 oraz nagłówki bloku2.
* W bloku1 atakujący tworzy strukturę fałszywego bloku:
* 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 bloku wskazują tam, gdzie wskaźnik bloku1 jest przechowywany 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 bloku1:

<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 bloku2 są modyfikowane w taki sposób, aby wskazywały, że poprzedni blok nie jest używany, a rozmiar to rozmiar zawartego fałszywego bloku.
* Gdy drugi blok zostanie zwolniony, to następuje odłączenie tego fałszywego bloku:
* `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->bk->fd` wskazują na to samo miejsce (lokalizację na stosie, gdzie przechowywany jest `blok1`, 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 bloku1 na stosie adresem (lub bajtami) przechowywanym 3 adresy wcześniej na stosie**.
* Dlatego jeśli atakujący mógłby ponownie kontrolować zawartość bloku1, będzie mógł **pisać wewnątrz stosu**, mając potencjalnie możliwość nadpisania adresu powrotu, pomijając canary, oraz modyfikacji wartości i wskaźników zmiennych lokalnych. Nawet ponownie modyfikując adres bloku1 przechowywany na stosie na inną lokalizację, jeśli atakujący mógłby ponownie kontrolować zawartość bloku1, będzie mógł pisać w dowolnym miejscu.
* Należy zauważyć, że było to możliwe, ponieważ **adresy są przechowywane na stosie**. Ryzyko i eksploatacja mogą zależeć od **miejsca, gdzie są przechowywane adresy do fałszywego bloku**.

<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 zaalokowanych za pomocą malloc. Atak unlink jest wykonywany, aby móc zaalokować tutaj blok, umożliwiając kontrolowanie wskaźników tablicy zaalokowanych adresów. Następnie istnieje inna funkcjonalność, która pozwala modyfikować zawartość bloków w tych adresach, co pozwala wskazywać adresy na GOT, modyfikować adresy funkcji w celu uzyskania wycieków i RCE.
* Kolejny przykład CTF: [https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* Podobnie 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. Dzięki temu 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.

{% hint style="success" %}
Dowiedz się i ćwicz Hacking AWS:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Dowiedz się i ćwicz Hacking GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)

<details>

<summary>Wesprzyj HackTricks</summary>

* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **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)**.**
* **Dziel się trikami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>
{% endhint %}