Determinazione dell'indirizzo di destinazione in un overflow dell'heap

1

Affinché si verifichi un overflow dell'heap e che venga eseguito un codice arbitrario, la funzione free() esegue il passaggio:

hdr->next->next->prev = hdr->next->prev

Capisco che l'indirizzo di hdr->next->next->prev sia calcolato come hdr->next->next + 4 . Abbastanza chiaro.

Ora, questo valore verrà sovrascritto dall'indirizzo hdr- > next- > prev che è controllato dall'hacker e che contiene il codice della shell probabilmente nell'heap stesso (supponendo che sia eseguibile)

L'indirizzo di destinazione, ad esempio, il valore in hdr->next->next in un overflow di heap vaniglia dovrebbe essere l'indirizzo nello stack che memorizza l'indirizzo di ritorno dopo che free() ha completato il suo lavoro.

Q1. In che modo un utente malintenzionato determina l'indirizzo Esatto del puntatore di ritorno di free() nello stack?

Q2. L'intero motivo per cui ciò si verifica è perché il puntatore aggiunge 4 al valore hdr->next->next per scrivere il puntatore prev . È stato risolto o è ancora uno dei motivi per gli overflow di heap correnti. (Il motivo per cui sto chiedendo questo è, sono a conoscenza di altri exploit di heap come double free e così via, voglio solo assicurarmi che la ragione primitiva sia stata corretta)

    
posta sudhacker 29.09.2012 - 20:01
fonte

1 risposta

2

Una risorsa eccezionale e approfondita su un attacco di overflow del buffer è Smashing the Stack tutorial di Aleph One. Mentre overflow dello stack e overflow dell'heap sono leggermente diversi, le tecniche sono simili / correlate.

Felix "FX" Lindner scrive un eccellente articolo (2006) su The H Security che descrive il tuo exploit in profondità. Versione condensata di seguito; consigliamo vivamente l'articolo completo per chiarezza.

In risposta a Q1, determinare il puntatore dell'indirizzo esatto per lo stack è il catch. Spesso, a causa dell'allocazione dello stack, della durata variabile del programma e dei dati, ecc., Non è possibile rilevare la posizione esatta senza una conoscenza significativa del layout della memoria. Invece, una tecnica comune è quella di eseguire una serie di istruzioni attorno al codice del payload nel tentativo di "colpire" il puntatore dello stack. Una serie di istruzioni NOP viene scritta prima del codice del payload in modo che "se" l'SP viene catturato nel buffer overflow risultante, l'SP avanza fino a quando non esegue il payload. Nel caso in cui l'SP sia "dopo" il tuo codice payload, potresti scrivere una serie di istruzioni JMP che puntano tutte al capo del payload. (Vedi il tutorial: Aleph copre questo processo in dettaglio).

L'obiettivo di questo overflow dell'heap consiste nel corrompere i metadati dell'heap record appena prima dell'operazione "write" implicita nell'assegnazione di hdr->next->prev a hdr->next->next->prev . Con la lista collegata corrotta, è possibile sovrascrivere l'indirizzo di ritorno utilizzato dalla fine di free sullo stack.

In risposta a Q2, presumo che tu stia chiedendo dell'implementazione GNU Libc di free() . Altre implementazioni avranno probabilmente un codice diverso. Esistono ora più controlli di integrità per impedire che oggetti di dimensioni non valide e doppie siano esenti, ecc. (Vedi _int_free() e funzioni correlate in Git ). Questo non vuol dire (in modo definitivo) che il vettore sia impossibile con altri mezzi, ma ora è più difficile.

Una terza fonte d'informazione su questo argomento è un white paper di Justin Ferguson: Capire l'ammasso rompendolo

    
risposta data 06.02.2013 - 16:56
fonte

Leggi altre domande sui tag