Il tuo payload exploit finisce sullo stack perché stai sovraccaricando un buffer nello stack, e in questo modo ottieni anche il controllo dell'indirizzo di ritorno.
L'ESP punta direttamente all'inizio del tuo payload (dopo l'esecuzione di ret
nella funzione che stai attaccando) perché metti il payload subito dopo i 4 byte che sovrascrivono l'indirizzo di ritorno nello stack. ret
apre 4 (o 8) byte in EIP, lasciando ESP che punta al payload che segue direttamente.
Ma non sai quale valore ESP avrà a quel punto , a causa dello stack ASLR e perché una diversa profondità dello stack di chiamate che porta fino a questo punto potrebbe cambiare l'indirizzo. Quindi non puoi codificare un indirizzo di ritorno corretto .
Ma se ci sono byte che decodificano come jmp esp
o call esp
ovunque su un indirizzo fisso (non ASLR) nella memoria del processo , puoi specificare che indirizzo come indirizzo di ritorno nel tuo exploit. L'esecuzione andrà lì, quindi al tuo payload.
Questo è spesso il caso: alcune DLL non hanno ASLR abilitato per il loro codice e il codice dell'eseguibile principale potrebbe non essere ASLR.
Codice ASLR per il codice tutto che sconfigge un attacco jmp esp
, a meno che l'autore dell'attacco non possa far filtrare gli indirizzi nel processo di destinazione.
Si noti che per codice a 64 bit è improbabile che si possa utilizzare jmp rsp
per overflow del buffer basato su stringhe, perché gli indirizzi di codice conterranno alcuni 0
di byte iniziali .
Quindi, jmp esp
ti offre un exploit molto più affidabile di quello che indovina ripetutamente un indirizzo di ritorno (con una slitta NOP molto grande).
L'ipotesi ripetuta bloccherà il processo di destinazione ogni volta che sbagli, ma un jmp esp
può darti un'alta probabilità di successo al primo tentativo. Ciò eviterà di lasciare i registri di crash. Potrebbe anche sconfiggere un sistema di rilevamento delle intrusioni che cerca di bloccare i processi del server e blocca le connessioni dal tuo indirizzo IP o simili.
Si noti che l'istruzione a 2 byte che si sta cercando può apparire come parte di un'altra istruzione quando il programma viene eseguito normalmente o come dati statici (in particolare i dati di sola lettura sono spesso in pagine eseguibili). Quindi devi solo cercare la sequenza da 2 byte, non per jmp esp
nello smontaggio del programma. I compilatori non useranno mai jmp esp
, quindi non ne troverai uno in questo modo.
Più in generale , qualsiasi funzione che termina con un puntatore del buffer in qualsiasi registro (ad esempio da memcpy
o soprattutto strcpy
) può consentire un attacco ret2reg , cercando un'istruzione jmp eax
.
Questo può funzionare in modalità 64 bit, dove gli indirizzi hanno alcuni byte zero alti; se lo zero finale di strcpy
scrive quel byte di indirizzo elevato per te, la fine della stringa di exploit potrebbe essere il byte dell'indirizzo diverso da zero che sovrascrive l'indirizzo di ritorno nello stack.
In questo caso, il payload dell'eseguibile andrebbe prima dell'indirizzo di ritorno, nel punto del buffer in cui la funzione lascia un registro che punta. (Tipicamente l'inizio del buffer se ci sono dei puntatori utili al buffer nei registri)