Heap Overflow

Sostieni HackTricks

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 alcuni dati e che i dati memorizzati erano più grandi dello spazio riservato.

Nei stack overflows 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 overflows, non vi è alcuna informazione sensibile memorizzata per impostazione predefinita nel chunk dell'heap che può essere sovraffollato. 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.

Per trovare gli offset degli overflow è possibile utilizzare gli stessi schemi dei stack overflows.

Stack Overflows vs Heap Overflows

Nei stack overflows, l'organizzazione e i dati che saranno presenti nello stack nel momento in cui la vulnerabilità può essere attivata sono piuttosto affidabili. Ciò è dovuto al fatto che lo stack è lineare, aumenta sempre in memoria in collisione, in specifici punti dell'esecuzione del programma la memoria dello stack di solito memorizza tipi di dati simili 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 di solito in posizioni separate della memoria (non uno accanto all'altro) a causa di bin 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à in collisione con quello vulnerabile a un heap overflow. Quindi, quando viene trovato un heap overflow, è necessario trovare un modo affidabile per far sì che l'oggetto desiderato sia il successivo in memoria rispetto a quello che può essere sovraffollato.

Una delle tecniche utilizzate per questo è il Heap Grooming che viene utilizzato ad esempio in questo post. Nel post viene spiegato come nel kernel iOS quando una zona esaurisce la memoria per memorizzare chunk di memoria, la espande di una pagina del kernel, e questa pagina viene divisa in chunk delle dimensioni previste che verranno utilizzati in ordine (fino alla versione iOS 9.2, poi questi chunk vengono utilizzati in modo randomizzato per rendere più difficile lo sfruttamento di questi attacchi).

Pertanto, nel post precedente in cui si verifica un heap overflow, per forzare l'oggetto sovraccaricato a collidere con un ordine vittima, diversi kallocs sono forzati da diversi thread per cercare di garantire che tutti i chunk liberi siano riempiti e che venga creato una nuova pagina.

Per forzare questo riempimento con oggetti di una dimensione specifica, l'allocazione fuori linea associata a una porta mach iOS è un candidato ideale. Creando la dimensione del messaggio, è possibile specificare esattamente la dimensione dell'allocazione kalloc e quando la porta mach corrispondente viene distrutta, l'allocazione corrispondente verrà immediatamente rilasciata a kfree.

Quindi, alcuni di questi segnaposto possono essere liberati. La lista di liberazione kalloc.4096 rilascia gli elementi in ordine di ultimo entrato, primo uscito, il che significa fondamentalmente che se alcuni segnaposto vengono liberati e l'exploit prova a allocare diversi oggetti vittime 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 un Heap overflow che mostra come sovrascrivendo il bit prev in uso del chunk successivo e la posizione della dimensione prev sia possibile consolidare un chunk utilizzato (facendogli credere che non sia in uso) e poi allocarlo nuovamente potendo sovrascrivere dati che vengono utilizzati in un diverso puntatore.

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 e ottenere la flag.

Nel protostar heap 1 esempio è possibile vedere come abusando di un buffer overflow sia possibile sovrascrivere in un chunk vicino un indirizzo dove verrà scritto un dato arbitrario dall'utente.

Esempio ARM64

Nella pagina https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ è possibile trovare un esempio di heap overflow in cui un comando che verrà eseguito è memorizzato nel chunk successivo a quello sovraccaricato. Quindi, è possibile modificare il comando eseguito sovrascribendolo con un exploit semplice come:

python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt

Altri esempi

  • Utilizziamo una vulnerabilità di Integer Overflow per ottenere un Heap Overflow.

  • Corrompiamo i puntatori a una funzione all'interno di una struct del blocco sovraccaricato per impostare una funzione come system ed ottenere l'esecuzione del codice.

Sostieni HackTricks

Last updated