Heap Overflow
Reading time: 5 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.
Informazioni di base
Un heap overflow è simile a un stack overflow ma nell'heap. Fondamentalmente significa che è stato riservato dello spazio nell'heap per memorizzare dei dati e i dati memorizzati erano più grandi dello spazio riservato.
Negli stack overflow sappiamo che alcuni registri come il puntatore di istruzione o il frame dello stack verranno ripristinati dallo stack e potrebbe essere possibile abusarne. Nel caso degli heap overflow, non ci sono informazioni sensibili memorizzate per impostazione predefinita nel chunk dell'heap che può essere sovrascritto. Tuttavia, potrebbero esserci informazioni sensibili o puntatori, quindi la criticità di questa vulnerabilità dipende da quali dati potrebbero essere sovrascritti e da come un attaccante potrebbe abusarne.
tip
Per trovare gli offset di overflow puoi utilizzare gli stessi schemi degli stack overflow.
Stack Overflows vs Heap Overflows
Negli stack overflow l'organizzazione e i dati che saranno presenti nello stack al momento in cui la vulnerabilità può essere attivata sono abbastanza affidabili. Questo perché lo stack è lineare, sempre in aumento in memoria collidente, in specifici punti dell'esecuzione del programma la memoria dello stack di solito memorizza un tipo simile di dati e ha una struttura specifica con alcuni puntatori alla fine della parte dello stack utilizzata da ciascuna funzione.
Tuttavia, nel caso di un heap overflow, la memoria utilizzata non è lineare ma i chunk allocati sono solitamente in posizioni separate della memoria (non uno accanto all'altro) a causa di bins e zone che separano le allocazioni per dimensione e perché la memoria precedentemente liberata viene utilizzata prima di allocare nuovi chunk. È complicato sapere quale oggetto andrà a collidere con quello vulnerabile a un heap overflow. Quindi, quando viene trovato un heap overflow, è necessario trovare un modo affidabile per fare in modo che l'oggetto desiderato sia il prossimo in memoria rispetto a quello che può essere sovrascritto.
Una delle tecniche utilizzate per questo è Heap Grooming che viene utilizzata ad esempio in questo post. Nel post viene spiegato come quando nel kernel iOS una zona esaurisce la memoria per memorizzare chunk di memoria, essa si espande di una pagina del kernel, e questa pagina viene suddivisa in chunk delle dimensioni previste che verrebbero utilizzate in ordine (fino alla versione 9.2 di iOS, poi questi chunk vengono utilizzati in modo randomizzato per rendere più difficile l'esploitazione di questi attacchi).
Pertanto, nel post precedente in cui si verifica un heap overflow, per forzare l'oggetto sovrascritto a collidere con un oggetto vittima, vengono forzati diversi kallocs
da diversi thread per cercare di garantire che tutti i chunk liberi siano riempiti e che venga creata una nuova pagina.
Per forzare questo riempimento con oggetti di una dimensione specifica, l'allocazione out-of-line associata a un mach port iOS è un candidato ideale. Modificando la dimensione del messaggio, è possibile specificare esattamente la dimensione dell'allocazione kalloc
e quando il corrispondente mach port viene distrutto, l'allocazione corrispondente verrà immediatamente rilasciata a kfree
.
Quindi, alcuni di questi segnaposto possono essere liberati. La lista libera kalloc.4096
rilascia elementi in ordine last-in-first-out, il che significa fondamentalmente che se alcuni segnaposto vengono liberati e l'exploit tenta di allocare diversi oggetti vittima mentre cerca di allocare l'oggetto vulnerabile all'overflow, è probabile che questo oggetto sarà seguito da un oggetto vittima.
Esempio libc
In questa pagina è possibile trovare un'emulazione di base di Heap overflow che mostra come sovrascrivere il bit prev in uso del chunk successivo e la posizione della dimensione prev è possibile consolidare un chunk utilizzato (facendolo pensare non utilizzato) e poi allocarlo di nuovo potendo sovrascrivere dati che vengono utilizzati in un puntatore diverso.
Un altro esempio da protostar heap 0 mostra un esempio molto basilare di un CTF in cui un heap overflow può essere abusato per chiamare la funzione vincitrice per ottenere la flag.
Nell'esempio protostar heap 1 è possibile vedere come abusando di un buffer overflow è possibile sovrascrivere in un chunk vicino un indirizzo dove dati arbitrari dell'utente verranno scritti.
Esempio ARM64
Nella pagina https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ puoi trovare un esempio di heap overflow dove un comando che verrà eseguito è memorizzato nel chunk successivo al chunk sovrascritto. Quindi, è possibile modificare il comando eseguito sovrascrivendolo con un exploit semplice come:
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
Altri esempi
- Auth-or-out. Hack The Box
- Utilizziamo una vulnerabilità di Integer Overflow per ottenere un Heap Overflow.
- Corrompiamo i puntatori a una funzione all'interno di un
struct
del chunk sovrascritto per impostare una funzione comesystem
e ottenere l'esecuzione del codice.
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.