giovedì 28 giugno 2012

Buffer Overflow, analisi di un programma buggato su windows.

Senza andare a scrivere un PDF intero, vorrei cercare di far capire, in modo molto pratico, in cosa consiste il buffer overflow, andando ad analizzare un programma buggato e creato ad HOC in C, per questo scopo.

L'obbiettivo di questo articolo è SPIEGARE NEL MODO PIU' SEMPLICE POSSIBILE questa tecnica, che ad occhi inesperti può sembrare abbastanza ostica.

I requisiti sono una conoscenza basilare del C e un po di manualità con l'analisi di un software (cosa che, se avete seguito il mio blog nelle mie guide sul reversing, avrete).
Andremo quindi a exploitare un nostro sorgente e lo analizzeremo durante il buffer overflow. Andremo quindi a vedere come sfruttare il bug e infine come toglierlo.

Veniamo subito al dunque andando a creare il nostro programma buggato:

Code:

#include <string.h>
#include <stdio.h>
void func_bugged (char *input) {
     char loal[5];
     strcpy (loal, input);
}
int main () {
    char asd[100];
    printf ("Inserisci una parola -> ");
    scanf ("%s", &asd);
     func_bugged (asd);
}

Bene, adesso compilatelo con il vostro compilatore, ed analizziamolo un secondo guardo il source; viene chiesto all'utente di inserire una parola e questa viene data alla variabile "asd", che a sua volta viene data alla funzione buggata che copia, tramite la "strcpy" questa nella variabile char "loal", che ha un buffer di 5 caratteri. Può sembrare un errore ridicolo, ma un programmatore inesperto che si trova davanti a centinaia, se non migliaia di righe di codice, può benissimo commetterlo; inoltre, l'errore spesso è commesso quando si inizializzano buffer anche molto più grandi.

Passiamo quindi all'analisi del codice tramite il nostro buon OllyDBG.
Come prima cosa, mettiamo il breackpoint sulla strcpy, così possiamo vedere, una volta elaborata la call, cosa succede nei registri, se andiamo a superare il buffer (overflow).
Quindi inseriamo, quando il programma ce lo chiede, una stringa, ad esempio io ho messo "wsasdLK".
Olly, breckerà, e proseguiamo di uno step per vedere che cosa è successo, premendo F8.
Guardate adesso i registri, a me risultano così:



Adesso vi invito a guardare con attenzione il registro EDX, che ha come valore 004B4C64, che sembra un indirizzo molto insolito, ma in realtà non è altro che la versione esadecimale dei caratteri ascii "dLK", come sempre, capovolti rispetto all'hex view.

Infatti:

1-  "d" = 100 decimale = 64h.
2- "L" = 76 decimale = 4Ch.
3- "K" = 75 decimale = 4Bh.
ECX = 004B4C64

Come avete visto, tramite questa tecnica riusciamo a modificare la memoria. Per la fortuna del nabbissimo programmatore che ha fatto questo sorgente (io...LOL), la vulnerabilità, in questo programma, non è sfruttabile, in quanto il registro EDX viene, poco dopo, sostituito con un indirizzo tramite l'istruzione MOV, e comunque il programma termina, ma in programmi dove dopo la funzione buggata ce ne sono altre, il registro manipolato, può essere di grande importanza e la sua modifica può permettere all'attaccante una code injection a volte disastrosa.
Ad esempio se ci fosse stata una "Call ECX", avendo il controllo sulla IAT e sul registro avremmo potuto modificare l'intero flusso del programma, senza andare a toccare nulla a livello di codice...fantastico no?? LOL...

Se siete arrivati a questo punto, comprendendo bene ogni singolo punto della guida, dovreste riuscire ad intuire il come togliere nel programma, la vulnerabilità; comunque sia, lo dico per chi pensa che ci vogliano chissà quali righe di codice, basta un:

if (strlen(asd)>= 5) {
        printf("Loal, tentato BoF");
}

Spero che in questa guida, molto approssimativa e concisa, io sia riuscito a farvi comprendere il funzionamento generale del buffer overflow. Per approfondimenti, vi rimando alla vasta mole di materiale che è presente sul web, buono studio.

Nessun commento:

Posta un commento

Ti potrebbero anche interessare

Related Posts Plugin for WordPress, Blogger...