Aggiornamento : sembra che ti aspetti più informazioni concrete, quindi ho espanso un po 'il mio post. Per quanto ne so, tuttavia, nessun codice oltre al programma, alle librerie e al codice del kernel viene solitamente mappato alla memoria quando il programma viene eseguito in modalità utente.
Ci sono molti punti in cui puoi reindirizzare il flusso di controllo, nel caso in cui lo stack non sia eseguibile:
-
ret2data : inserisci il codice exploit nella sezione dei dati e quindi indirizza l'indirizzo di ritorno lì. Spesso non è possibile.
-
ret2text : passa al codice esistente nella sezione
.text
del file binario sfruttato. Ciò include il salto a DLL e altre librerie condivise (e teoricamente anche il codice del kernel, senza un cambio di modalità).
-
resi concatenati : una tecnica che può essere utilizzata per combinare diversi metodi. Fondamentalmente, si prepara lo stack in modo che l'istruzione di ritorno della prima funzione salti alla seconda funzione, e così via.
-
resi parziali : un'altra tecnica. Non è necessario saltare all'inizio di una funzione, ma anche saltare a metà o vicino alla fine.
-
ret2syscall : un esempio pratico di ciò che puoi fare. Fondamentalmente, hai un'istruzione
int 0x80
(una chiamata di sistema linux che si aspetta i suoi argomenti nei registri) e qualsiasi funzione che ripulisce lo stack, ad esempio pop eax; pop ecx; pop edx; pop ebx; ret;
Si riempie lo stack con l'indirizzo dell'istruzione pop eax
, quindi i valori dei registri e quindi l'indirizzo di syscall.