Unsorted Bin Attack
Reading time: 7 minutes
tip
Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.
Basic Information
Per ulteriori informazioni su cosa sia un unsorted bin, controlla questa pagina:
{{#ref}} bins-and-memory-allocations.md {{#endref}}
Le liste non ordinate possono scrivere l'indirizzo in unsorted_chunks (av)
nell'indirizzo bk
del chunk. Pertanto, se un attaccante può modificare l'indirizzo del puntatore bk
in un chunk all'interno dell'unsorted bin, potrebbe essere in grado di scrivere quell'indirizzo in un indirizzo arbitrario, il che potrebbe essere utile per rivelare indirizzi Glibc o bypassare alcune difese.
Quindi, fondamentalmente, questo attacco consente di impostare un grande numero in un indirizzo arbitrario. Questo grande numero è un indirizzo, che potrebbe essere un indirizzo heap o un indirizzo Glibc. Un obiettivo tipico è global_max_fast
per consentire di creare fast bin con dimensioni maggiori (e passare da un attacco unsorted bin a un attacco fast bin).
tip
Dare un'occhiata all'esempio fornito in https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle e utilizzare 0x4000 e 0x5000 invece di 0x400 e 0x500 come dimensioni dei chunk (per evitare Tcache) è possibile vedere che oggigiorno l'errore malloc(): unsorted double linked list corrupted
viene attivato.
Pertanto, questo attacco unsorted bin ora (tra i vari controlli) richiede anche di essere in grado di riparare la lista doppiamente collegata in modo che venga bypassato victim->bk->fd == victim
o non victim->fd == av (arena)
, il che significa che l'indirizzo in cui vogliamo scrivere deve avere l'indirizzo del fake chunk nella sua posizione fd
e che il fake chunk fd
punta all'arena.
caution
Nota che questo attacco corrompe l'unsorted bin (quindi anche small e large). Quindi possiamo solo utilizzare allocazioni dal fast bin ora (un programma più complesso potrebbe fare altre allocazioni e andare in crash), e per attivare questo dobbiamo allocare la stessa dimensione o il programma andrà in crash.
Nota che sovrascrivere global_max_fast
potrebbe aiutare in questo caso fidandosi che il fast bin sarà in grado di gestire tutte le altre allocazioni fino al completamento dell'exploit.
Il codice di guyinatuxedo lo spiega molto bene, anche se se modifichi i malloc per allocare memoria abbastanza grande da non finire in un Tcache puoi vedere che l'errore precedentemente menzionato appare impedendo questa tecnica: malloc(): unsorted double linked list corrupted
Unsorted Bin Infoleak Attack
Questo è in realtà un concetto molto basilare. I chunk nell'unsorted bin avranno puntatori. Il primo chunk nell'unsorted bin avrà effettivamente i link fd
e bk
che puntano a una parte dell'arena principale (Glibc).
Pertanto, se puoi mettere un chunk all'interno di un unsorted bin e leggerlo (use after free) o allocarlo di nuovo senza sovrascrivere almeno 1 dei puntatori per poi leggerlo, puoi avere una Glibc info leak.
Un simile attacco usato in questo writeup è stato quello di abusare di una struttura di 4 chunk (A, B, C e D - D serve solo a prevenire la consolidazione con il top chunk) quindi un overflow di byte nullo in B è stato utilizzato per far indicare a C che B era inutilizzato. Inoltre, in B i dati prev_size
sono stati modificati in modo che la dimensione invece di essere la dimensione di B fosse A+B.
Poi C è stato deallocato e consolidato con A+B (ma B era ancora in uso). Un nuovo chunk di dimensione A è stato allocato e poi gli indirizzi di libc sono stati scritti in B da dove sono stati rivelati.
References & Other examples
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
- L'obiettivo è sovrascrivere una variabile globale con un valore maggiore di 4869 in modo da poter ottenere il flag e PIE non è abilitato.
- È possibile generare chunk di dimensioni arbitrarie e c'è un overflow heap con la dimensione desiderata.
- L'attacco inizia creando 3 chunk: chunk0 per abusare dell'overflow, chunk1 per essere sovrascritto e chunk2 affinché il top chunk non consolidi i precedenti.
- Poi, chunk1 viene liberato e chunk0 viene sovrascritto in modo che il puntatore
bk
di chunk1 punti a:bk = magic - 0x10
- Poi, chunk3 viene allocato con la stessa dimensione di chunk1, il che attiverà l'attacco unsorted bin e modificherà il valore della variabile globale, rendendo possibile ottenere il flag.
- https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
- La funzione di merge è vulnerabile perché se entrambi gli indici passati sono lo stesso verrà realloc su di esso e poi liberato ma restituendo un puntatore a quella regione liberata che può essere utilizzata.
- Pertanto, vengono creati 2 chunk: chunk0 che verrà unito con se stesso e chunk1 per prevenire la consolidazione con il top chunk. Poi, la funzione di merge viene chiamata con chunk0 due volte, il che causerà un use after free.
- Poi, la funzione
view
viene chiamata con l'indice 2 (che è l'indice del chunk use after free), il che rivelerà un indirizzo libc. - Poiché il binario ha protezioni per allocare solo dimensioni maggiori di
global_max_fast
, quindi non viene utilizzato alcun fastbin, verrà utilizzato un attacco unsorted bin per sovrascrivere la variabile globaleglobal_max_fast
. - Poi, è possibile chiamare la funzione di modifica con l'indice 2 (il puntatore use after free) e sovrascrivere il puntatore
bk
per puntare ap64(global_max_fast-0x10)
. Poi, creando un nuovo chunk utilizzerà l'indirizzo liberato precedentemente compromesso (0x20) che attiverà l'attacco unsorted bin sovrascrivendo ilglobal_max_fast
con un valore molto grande, consentendo ora di creare chunk nei fast bin. - Ora viene eseguito un attacco fast bin:
- Prima di tutto, si scopre che è possibile lavorare con fast chunk di dimensione 200 nella posizione
__free_hook
: gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59 0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200 0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
- Se riusciamo a ottenere un fast chunk di dimensione 0x200 in questa posizione, sarà possibile sovrascrivere un puntatore di funzione che verrà eseguito
- Per questo, viene creato un nuovo chunk di dimensione
0xfc
e la funzione di merge viene chiamata con quel puntatore due volte, in questo modo otteniamo un puntatore a un chunk liberato di dimensione0xfc*2 = 0x1f8
nel fast bin. - Poi, la funzione di modifica viene chiamata in questo chunk per modificare l'indirizzo
fd
di questo fast bin per puntare alla precedente funzione__free_hook
. - Poi, viene creato un chunk di dimensione
0x1f8
per recuperare dal fast bin il chunk precedente inutile, quindi viene creato un altro chunk di dimensione0x1f8
per ottenere un fast bin chunk nella__free_hook
che viene sovrascritto con l'indirizzo della funzionesystem
. - E infine, un chunk contenente la stringa
/bin/sh\x00
viene liberato chiamando la funzione di eliminazione, attivando la funzione__free_hook
che punta a system con/bin/sh\x00
come parametro. - CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
- Un altro esempio di abuso di un overflow di 1B per consolidare chunk nell'unsorted bin e ottenere una libc infoleak e poi eseguire un attacco fast bin per sovrascrivere malloc hook con un indirizzo one gadget
- Robot Factory. BlackHat MEA CTF 2022
- Possiamo solo allocare chunk di dimensione maggiore di
0x100
. - Sovrascrivere
global_max_fast
utilizzando un attacco Unsorted Bin (funziona 1/16 volte a causa di ASLR, perché dobbiamo modificare 12 bit, ma dobbiamo modificare 16 bit). - Attacco Fast Bin per modificare un array globale di chunk. Questo fornisce una primitiva di lettura/scrittura arbitraria, che consente di modificare il GOT e impostare alcune funzioni per puntare a
system
.
tip
Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.