Stack overflow: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica
Nessun oggetto della modifica
Riga 1:
Uno stack overflow è la scrittura al di fuori dei limiti della memoria assegnata allo stack che si va a sostituire alle istruzioni del programma in esecuzione. Si immagini l'utilizzo di una allocazione di memoria dedicata all'esecuzione di un programma come una pila. Mentre le istruzioni vengono allocate in quell'area partendo dall'alto verso il basso della pila, lo stack, utilizzando la sua organizzazione LIFO, crescerà dal basso verso l'alto di questa seguendo quanto indicato dallo stack pointer, un registro dedicato delle CPU. Se ad ogni operazione di push nello stack non corrisponde un opportuno numero di operazioni di pop questo può continuare a lievitare fino a giungere a sovrascrivere le informazioni del programma. Opportunamente sfruttato questo tipo di overflow può far si che un utente malintenzionato sfrutti questa vulnerabilità per l'esecuzione di codice arbitrario che si va a sostituire a quello del programma in esecuzione.
Uno "[[stack]] overflow" (inteso come "attacco" informatico) è una delle tecniche base di [[exploit]] più semplici, dalla quale esistono vari tipi di protezione (vedi [[PaX]]). Lo stack, nella [[memoria]], è l'area dedicata alle informazioni relative all'esecuzione delle [[funzioni]] e alla manipolazione dei dati tra e dentro di esse. Esso è limitato dal registro ESP (stack pointer) ed è suddiviso in vari "[[frame]]", così arrangiati: ad ogni chiamata di funzione, viene eseguito un ''push'' nello stack degli argomenti di quest'ultima, seguito da una copia del registro EIP (il puntatore alle istruzioni) e da una copia del registro EBP (il puntatore alla base dello stack-frame corrente - vedi [[IA32]]), al quale si fa puntare il nuovo EBP. A questo punto, nella funzione chiamata, il sistema alloca staticamente la memoria per le nuove [[variabili]] locali; se una di queste variabili può essere "riempita" con dati provenienti - direttamente o indirettamente - da un "[[input]]" sul quale non vi sono '''controlli sulla dimensione''', è possibile sovrascrivere i dati che stanno nelle locazioni di memoria inferiori, ovvero, in ordine, eventuali altre variabili locali, la copia del vecchio base pointer (EBP) e, quindi, la copia del vecchio instruction pointer. L'obiettivo è quello di inserirvi l'indirizzo di un altro segmento di [[codice]]. Si ha quindi la possibilità di esecuzione di codice arbitrario al momento del ritorno alla funzione chiamante; tale codice girerà sulla macchina con i diritti del [[processo]] che lo ha avviato (il programma vulnerabile).