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

8.9 KiB

Unlink Aanval

{% hint style="success" %} Leer & oefen AWS Hack:HackTricks Opleiding AWS Red Team Expert (ARTE)
Leer & oefen GCP Hack: HackTricks Opleiding GCP Red Team Expert (GRTE)

Ondersteun HackTricks
{% endhint %}

Basiese Inligting

Toe hierdie aanval ontdek is, het dit meestal 'n WWW (Write What Where) toegelaat, maar sommige kontroles is bygevoeg wat die nuwe weergawe van die aanval interessanter en meer kompleks en nutteloos maak.

Kodevoorbeeld:

Kode ```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>

* Aanval werk nie as tcaches gebruik word nie (na 2.26)

### Doel

Hierdie aanval maak dit moontlik om **'n aanwyser na 'n blok te verander om 3 adresse voor homself te wys**. As hierdie nuwe ligging (omgewing waar die aanwyser geleë was) interessante dinge bevat, soos ander beheerbare toekenning / stapel..., is dit moontlik om hulle te lees/oor te skryf om 'n groter skade te veroorsaak.

* As hierdie aanwyser in die stapel geleë was, omdat dit nou 3 adresse voor homself wys en die gebruiker dit moontlik kan lees en wysig, sal dit moontlik wees om sensitiewe inligting uit die stapel te lek of selfs die terugkeeradres te wysig (miskien) sonder om die kanarie aan te raak
* In CTF-voorbeelde is hierdie aanwyser geleë in 'n reeks aanwysers na ander toekenning, daarom, deur dit 3 adresse voor te maak en dit te kan lees en skryf, is dit moontlik om die ander aanwysers na ander adresse te laat wys.\
Aangesien die gebruiker moontlik ook die ander toekenning kan lees/skryf, kan hy inligting lek of nuwe adresse in willekeurige ligginge oorskryf (soos in die GOT).

### Vereistes

* Sekere beheer in 'n geheue (bv. stapel) om 'n paar blokke te skep wat waardes aan 'n paar van die eienskappe gee.
* Stapel lek om die aanwysers van die vals blok in te stel.

### Aanval

* Daar is 'n paar blokke (blok1 en blok2)
* Die aanvaller beheer die inhoud van blok1 en die koppe van blok2.
* In blok1 skep die aanvaller die struktuur van 'n vals blok:
* Om beskermings te omseil, maak hy seker dat die veld `grootte` korrek is om die fout te vermy: `korrupte grootte vs. vorige_grootte tydens konsolidasie`
* en velde `fd` en `bk` van die vals blok wys na waar blok1 se aanwyser gestoor word met 'n afstande van -3 en -2 onderskeidelik sodat `vals_blok->fd->bk` en `vals_blok->bk->fd` na 'n posisie in die geheue (stapel) wys waar die werklike blok1-adres geleë is:

<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>

* Die koppe van blok2 word gewysig om aan te dui dat die vorige blok nie gebruik word nie en dat die grootte die grootte van die vals blok bevat.
* Wanneer die tweede blok vrygelaat word, gebeur hierdie vals blok wat ontkoppel:
* `vals_blok->fd->bk` = `vals_blok->bk`
* `vals_blok->bk->fd` = `vals_blok->fd`
* Voorheen is daar gemaak dat `vals_blok->fd->bk` en `vals_blok->bk->fd` na dieselfde plek wys (die ligging in die stapel waar `blok1` gestoor was, sodat dit 'n geldige gekoppelde lys was). Aangesien **beide na dieselfde ligging wys** sal slegs die laaste een (`vals_blok->bk->fd = vals_blok->fd`) **effek** hê.
* Dit sal **die aanwyser na blok1 in die stapel oorskryf na die adres (of bytes) wat 3 adresse voor in die stapel gestoor is**.
* Daarom, as 'n aanvaller die inhoud van blok1 weer kan beheer, sal hy in staat wees om **binne die stapel te skryf** en moontlik die terugkeeradres oorskryf deur die kanarie te vermy en die waardes en punte van plaaslike veranderlikes te wysig. Selfs deur weer die adres van blok1 wat in die stapel gestoor is na 'n ander ligging te wys waar as die aanvaller weer die inhoud van blok1 kan beheer, sal hy oral kan skryf.
* Let daarop dat dit moontlik was omdat die **adresse in die stapel gestoor is**. Die risiko en uitbuiting kan afhang van **waar die adresse na die vals blok gestoor word**.

<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>

## Verwysings

* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* Alhoewel dit vreemd sou wees om 'n ontkoppelingsaanval selfs in 'n CTF te vind, hier is 'n paar skrywes waar hierdie aanval gebruik is:
* CTF-voorbeeld: [https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* In hierdie voorbeeld is daar in plaas van die stapel 'n reeks malloc'ed adresse. Die ontkoppelingsaanval word uitgevoer om 'n blok hier toe te ken, dus om die aanwysers van die reeks malloc'ed adresse te beheer. Dan is daar 'n ander funksionaliteit wat toelaat om die inhoud van blokke in hierdie adresse te wysig, wat toelaat om adresse na die GOT te wys, funksieadresse te wysig om lekke en RCE te kry.
* 'n Ander CTF-voorbeeld: [https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* Net soos in die vorige voorbeeld is daar 'n reeks adresse van toekenning. Dit is moontlik om 'n ontkoppelingsaanval uit te voer om die adres na die eerste toekenning 'n paar posisies voor die begin van die reeks te maak en dan hierdie toekenning in die nuwe posisie te oorskryf. Daarom is dit moontlik om aanwysers van ander toekenning te oorskryf om na die GOT van atoi te wys, dit te druk om 'n libc-lek te kry, en dan atoi GOT met die adres na 'n een gadget te oorskryf.
* CTF-voorbeeld met aangepaste malloc- en vryfunksies wat 'n kwesbaarheid misbruik wat baie soortgelyk is aan die ontkoppelingsaanval: [https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom\_misc\_heap/csaw17\_minesweeper/index.html)
* Daar is 'n oorvloei wat toelaat om die FD- en BK-aanwysers van aangepaste malloc te beheer wat (aangepas) vrygestel sal word. Verder het die heap die uitvoerbit, sodat dit moontlik is om 'n heap-adres te lek en 'n funksie van die GOT na 'n heapblok met 'n skelkode te wys om uit te voer.