Prerequisiti:
conoscienza minimale di come funziona asm(senza saperlo scrivere, giusto leggere poco poco)

Fra tutti i bug informatici il più famoso è senza dubbio il buffer overflow, in soldoni esso consiste nel mandare in input una stringa sufficientemente grande da superare il buffer in cui dovrebbero andare i caratteri previsti e quelli che avanzano andare ad eseguire codice arbitrario.
Per comprendere al meglio si dovrebbero spiegare alcuni componenti essenziali della memoria del pc:

La struttura dati fondamentale è lo stack, in questo spazio verranno contenuti i dati del programma, chi sa programmare indubbiamente avrà un idea di come funziona questa struttura ad alto e medio livello, anche a basso livello funziona in maniera simile, c'è un puntatore che punta all'inizio di questa "pila" e un altro che permette di scorrerla.
Utilizzando assembler x86 questi due puntatori sono rispettivamente rappresentati dai registri EBP(inizio) ed ESP(scorre).
Un altro registro importantissimo è EIP, esso contiene l'offset dell'istruzione successiva.

Quello che bisogna capire dopo è che il buffer overflow scatta quando termina la funzione in cui è contenuto l'errore, ad alto e medio livello credo che tutti sappiano come funzioni una funzione(gioco di parole scusate), in assembler funziona così:
si chiama CALL(un comando asm x86 non un registro) che farà fare alla cpu essenzialmente due cose:

- Salva il valore attuale di EIP(se non ricordate sarebbe l'istruzione dopo, quindi quella  sucessiva alla CALL)
- Modifica EIP col offset passatogli e va ad eseguire la funzione

ad esempio

CALL 00123456

EIP punta a dopo CALL e si salva questo indirizzo, gli verrà dato il valore 00123456 per andare ad eseguire le funzione che iniziarà in quel indirizzo.

Anche EBP viene salvato, impostato all'inizio, e lo spazio fra i due registri servirà come contenitore di variabili.

Alla fine del codice della funzione per ritornare al codice che l'ha chiamata si usa il comando RET che riassegna ai registri i valori salvati precedentemente da CALL, quindi dopo RET, EIP avrà il valore sucessivo alla CALL(l'indirizzo prima salvato).
Ed è proprio quando si chiama RET che, con un exploit, si può impostare il valore dei registri a piacimento per eseguire il codice che abbiamo passato :asd:

Se volete un esempio di questo bug trovate una funzione che ne è affetta(in C):

void bufferOverFlow(void) {
char buffer[5];
<b>gets</b>(buffer); // funzione da deprecare dalla libreria ANSI :-)
}

Quella funzione che i manuali scongiurano di dimenticare se la usiamo cmq nel caso l'input dell'utente superi le dimensioni del buffer andrà a modificare EBP ed EIP ed aggiungerà il codice arbitrario, il così detto shell-code.

Ecco una rappresentazione grafica del problema:
BUFFER
EBP
EIP

Se si passa la stringa "ciao" (più INVIO che diventa n e che gets converte in un bytes NULL che rispetta le dimensioni del buffer) avremo:

63 69 61 6f 00 = ciao + carattere null
indirizzo = quello di EBP
indirizzo = quello di EIP

Nel nostro caso la nostra funzione bufferOverFlow ha una dimensione di:

5 bytes del buffer +
4 bytes di EBP +
4 bytes di EIP =
--------------------
13 bytes

Per completezza, se alla funzione aggiungessimo qualche int, qualche long e altri char bisognerebbe contare anche loro, quindi 4 bytes per il long, 1 per il char ecc... ecco una tabella con le dimensioni di ogni tipo:

char             1 byte
short            2 byte
int                4 byte
long             4 byte
float             4 byte
double         8 byte
long double   8 byte

In conclusione se noi inserissimo una stringa di 13 caratteri oltre che riempire il buffer sovrascriveremo anche i registri.

Naturalmente non è che qualsiasi stringa faccia danni, se inserissimo 13 caratteri del tipo "1234567898765" al 99% l'OS darà un bel segment fault dato che non trova nessuna cella di memoria associata all'eseguibile con quel indirizzo, se si inserisse però una stringa adatta(detta shellcode) potremmo far eseguire quello che vogliamo...

Prima puntata finita, se mi capiterà di approfondire l'argomento alla prossima.