[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa - 2003
-
Upload
ultrauploader -
Category
Documents
-
view
18 -
download
1
Transcript of [Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa - 2003
Introduzione alle tecniche diExploit
IFOA24 Luglio 2003
Luigi MoriNetwork Security [email protected]
Agenda
• Memory layout di un processoWin2000
• Stack Frame• Exploit• Shellcode• Note finali
Processo Win2000
• Lo spazio di indirizzamento è flat• Suddiviso in due regioni principali
– System space (Kernel)– User space (Programma e DLL)
• All’interno dello user space la memoriapuò essere suddivisa in ulteriori sezioni– Codice– Stack– Dati inizializzati– Dati non inizializzati
Memory layout
User Space(Programma, DLL, Dati, Stack,
Ambiente)
System Space(Kernel, Executive, Driver)
0x80000000
L’interfaccia fra i due spazi è la NTDLL.DLL
User Space
• Diviso in una serie di regioni• Ogni regione ha dei permessi di
accesso– codice: XR– dati non inizializzati: RWX– dati inizializzati: RX– stack: RWX
Esempio User Space
stack code datiinit dati code dati
init dati
prova.exe NTDLL.DLL
Stack Frame di una funzione C
int
f(char *s)
{
char c[16];
int i;
i = 1;
…
return i;
}
push ebp
mov ebp, esp
sub esp,20h
mov [ebp-20],1
...
Stack Frame di una funzione C
Registri salvati
Variabili locali
Frame ptrRet Address
Argomenti
• Registri Salvati. Sono i registrisalvati dalla calling convusata
• Frame pointer. E’ il valoresalvato del registro usatoper indirizzare le variabililocali (EBP)
• Ret Address. Indirizzo diritorno
• Argomeni. Argomentipassati
Stack Frame di f
s
Ret Address
Frame ptr
c
i• Nessun registro salvato• Le variabili locali sono
contigue
Agenda Exploit
• Buffer overflow– classico– frame pointer– heap
• Format String Vulnerabilities• Integer overflow
Buffer overflow classico
• Il padre di tutti i buffer overflow• Ideato da Aleph1 nell’articolo
“Smashing the stack for fun andprofit” nella e-zine Phrack #49
Funzione f
intf(char *s){
char c[16];int i;i = 1;strcpy(c,s);return i;
}
• La funzione strcpy copia idati da s in c senzacontrollare la dimensione
• Se la stringa puntata da sè più lunga di 16 byte cisono dei problemi
Problemi per f
• Se s è abbastanzalunga può andare asovrascrivere framepointer, return addresse altro ancora
• Questo può esseresfruttato da unattaccantea
Ret Address
Frame ptr
c
i
Problemi per f
• Se s è abbastanzalunga può andare asovrascrivere framepointer, return addresse altro ancora
• Questo può esseresfruttato da unattaccantea
Ret Address
Frame ptr
c
i
s
Attacco ad f
• Posso costruire s inmodo che la parteche va a sovrascriverel’indirizzo di ritornopunti all’interno deidati iniettati
• Quando f finsice il suolavoro invece disaltare indietro nellafunzione chiamantesalta nel buffer
a
Ret Address
Frame ptr
c
i
Attacco ad f
• Posso costruire s inmodo che la parteche va a sovrascriverel’indirizzo di ritornopunti all’interno deidati iniettati
• Quando f finsice il suolavoro invece disaltare indietro nellafunzione chiamantesalta nel buffer
a
Ret Address
Frame ptr
c
i
s
Nuovo ret
Anatomia di un exploit
Cuscino di NOP
Addr codice
payloada
Ret Address
Frame ptr
c
i
Anatomia di un exploit
• Il cuscino di NOP iniziale serve pernon dover essere eccessivamenteprecisi nello specificare l’indirizzo dijump
• Il creatore dell’exploit deve prestareattenzione ai check fatti sull’input(alfanumerico, solo 7bit, …)
• Il payload è la parte dell’exploit checompie l’azione vera e propria
Frame pointer overflow
• Buffer overflow in cui è possibilesovrascrivere solo il primo byte delframe pointer
• Vengono detti off-by-one• Spesso sono dovuti a differenti
implementazioni di una funzione supiù piattaforme (strncpy su Linux,Win32, …)
Frame pointer overflow
• Solamente un byte delframe pointer vienesovrascritto
• Dovuti ad errori nelcontrollo della lunghezza(<= invece di un < stretto)
Registri salvati
Variabili locali
Frame ptrRet Address
Argomenti
Frame pointer overflow
• Solamente un byte delframe pointer vienesovrascritto
• Dovuti ad errori nelcontrollo della lunghezza(<= invece di un < stretto)
Registri salvati
Variabili locali
Frame ptrRet Address
Argomenti
Come è possibile ?
g(){
…f();…
}
• La funzione f è attaccabile• Molte funzioni hanno all’inizio un
codice del tipo:
• Al termine invece:
• Se dentro f il frame pointer vienecambiato al termine di g vienemodificato lo stack pointer
push ebp
mov ebp, esp
mov esp, ebp
pop ebp
Difese da attacchi allo stack
• Stack non eseguibile– Al segmento di stack vengono rimossi i
diritti di esecuzione, i dati presenti sullostack non possono essere eseguiti
– Alcuni compilatori usano lo stack percreare trampolini verso altro codice
– Il codice per l’exploit potrebbe giàtrovarsi all’interno del programma èsufficiente passargli i dati giusti
Difese da attacchi allo stack
• Canarino– Il compilatore viene modificato in
modo da inserire un valore tra FramePointer e variabili in entrata ad ognifunzione
– All’uscita da ogni funzione si controllase il canarino è ancora vivo (intatto)
– Il canarino può essere un valorecasuale oppure semplicemente 0
Difendersi con il canarino
• Il canarino viene inserito inentrata alla funzione
• Viene controllato in uscita• Se non è intatto significa
che è stato sovrascritto el’esecuzione viene interrotta
• Si evita di eseguire il codicedell’exploit
Registri salvati
Variabili locali
Frame ptrRet Address
Argomenti
Canarino
Heap-based overflow
• Fino ad ora abbiamo visto soloattacchi allo stack
• E’ possibile anche attaccare bufferpresenti nell’area dati (heap)
Heap-based overflow
• Una volta sovrascritto ilbuffer è necessariotrovare un modo persaltarci dentro
• L’idea è disovrascrivere unpuntatore al codice inmodo da farlo puntaredentro al buffer
buffer
altre variabili
codice
Heap-based overflow
• Una volta sovrascritto ilbuffer è necessariotrovare un modo persaltarci dentro
• L’idea è disovrascrivere unpuntatore al codice inmodo da farlo puntaredentro al buffer
buffer
altre variabili
codice
exploit
Esempio di programma affetto
voidg(){}
voidmain(int argc, char **argv){
static struct {char buffer[10];void (*f)();
} s;
s.f = g;argv++;strcpy(&s.buffer,*argv);printf("%08x %08x\n",
&s.f, &s.buffer);s.f();
}
• Dando unargomentoabbastanza lungoè possibilesovrascrivere ilpuntatore afunzione f edirettore il flussodel programma
Situazioni tipiche di exploit
• Classi C++ (mix di puntatori afunzioni e dati)
• Funzioni di libreria che contengonopuntatori statici a funzioni (atexit, …)
• ...
Format String Exploits
• Sfruttano funzioni tipo printf
• Quando la format string può essereinfluenzata dall’utente è possibileche sia presente una Format StringVulnerability
printf(format_string, arg1, arg2, ….)
Format String Functions
• Le funzioni tipo printf accettano unaformat string ed un numero variabiledi argomenti
• In output viene generata unaversione trasformate della formatstring
Esempio
voidf(){ int i;
i = 5; printf(“prova %d %08x\n”, i, &i);}
output
prova 5 00130000
Format functions stack frame
• Il chiamante conosce ilnumero di argomentipassati, il chiamato no
• Il primo argomento è laformat string
• Il chiamato deduce dallaformat string il numero diargomenti
Registri salvati
Variabili locali
Frame ptrRet Address
Arg1Frmat str addr
...
Esempio funzione vulnerabile
voidf(char *s){
char buff[512];char outbuff[512];sprintf(buff,”Err: %s”,s);sprintf(outbuff,buff);
}
• Con il primo sprintfviene creata laformat string per ilsecondo
• Passando allafunzione una stringache funzioni daformat stringpossiamosovrascrivere lo stack
Esempio diformat string exploit
• Passo alla funzione f una stringa tipo“%s%s%s%s”
• Dopo il primo sprintf ho nel bufferbuff la stringa
• Nel secondo sprintf questa stringaviene usata come format string
“Err: %s%s%s%s”
Esempio di format stringexploit
• La funzione sprintf si aspettadi trovare 4 argomenti sullostack (uno per ogni %s)
• Quando cerca di accederea questi argomenti va atoccare il frame dellafunzione chiamante, inquesto caso f
• sprintf andrà a stamparevalori “casuali” dellamemoria del processo. Crashdel programma
Registri salvati
Variabili locali
Frame ptrRet Address
Frmat str addr
Frame di f
Eseguire codice arbitrario
• Sfruttando una format stringvulnerability è possibile anche fareseguire codice arbitrario alprocesso
• Il procedimento è abbastanzadelicato ma lo scopo ultimo èsempre lo stesso: far saltarel’esecuzione all’interno del bufferriempito con il codice dell’exploit
Integer overflow
• Sono gli errori più difficili da sfruttare• Sfruttano una delle caratteristiche
fondamentali dell’aritmetica deicalcolatori
Interi e linguaggio C
• Nel linguaggio ci sono diversi tipi di interi• Ogni tipo di intero è rappresentato da
una variabile con un certo numero di bit• Esempio su piattaforma Win32
– int è un intero a 32 bit– short è un intero a 16 bit
• Ogni intero può avere un valore massimopari a 2^(dimensione in bit)-1
Esempio di funzionevulnerabile
intcatvars(char *buf1, char *buf2, int len1, int len2){
char buff[256];
if ((len1+len2) > 256) return -1;
memcpy(buff,buf1,len1);memcpy(buff+len1,buf2,len2);
…return 0;
}
Il controllo (len1+len2) nontiene conto di un possibileinteger overflow. Al memcpyè quindi possibilesovrascrivere lo stack e siricade nel classico stack-based buffer overflow
Idea base degli exploit
• Tutti le tecniche di exploit che abbiamovisto si dividono in due parti:– iniezione del codice arbitrario in un buffer– dirottamento del programma verso quel
buffer
• E’ il dirottamento la parte più delicata eche differenzia una tecnica dall’altra
Codice iniettato
• Viene detto il payload dell’exploit• E’ il codice che ha il compito di
compromettere il sistema• Scrivere questo codice è complesso
e delicato• In genere il suo obbiettivo è quello
di aprire una porta di accesso alsistema (shellcode)
Come funziona ?
• Uno scrittore di shellcode deveaffrontare diversi problemi
• Il principale è la differenza tra levarie versioni del sistema operativo
• Il secondo è ottenere tutte lefunzioni che servono per svolgere illavoro
Sotto Win32
• Sotto Win32 le funzioni di sistemasono suddivisi in librerie caricatedinamicamente dal programma(DLL)
• Gli indirizzi delle funzioni all’internodelle librerie cambiano da versionea versione
Import & Export Tables
foo.exe kernel32.dll
import table di foo.exe import table di kernel32.dll
export table di kernel32.dll
Import & Export Tables
• In ogni eseguibile sotto Win32 (PE) cisono una import ed una exporttable
• Nella Import Table ci sono le libreriee le funzioni necessarie alfunzionamento del programma
• Nella Export Table ci sono gli indirizzidelle funzioni dell’eseguibileaccessibili agli altri programmi
Import & Export Table
• Al momento dell’esecuzione illoader di Win32 si occupa dicaricare tutte le DLL necessarie
• Completa quindi la Import Table deivari componenti con il contenutodelle altre Export Table
Accesso alle funzioni run-time
• Il codice iniettato deve avere un modoper accedere alle funzioni run-time
• Non può usare un indirizzo fisso perchépotrebbe cambiare da versione aversione
• Può utilizzare le funzioni GetProcAddress eLoadLibrary
• Con queste chiamate può avereaccesso a tutte le altre funzioni
• Per usarle però deve trovare il loroindirizzo
Shellcode Win32(IAT scanning)
• Per prima cosa il payload scandiscela IAT del suo eseguibile per trovarele chiamate LoadLibrary eGetProcAddress
• Sfrutta quindi queste due funzioniper ottenere l’indirizzo di tutte quelleche gli servono
Altre tecniche
• Ci sono altre tecniche usate dagliscrittori di exploit:– PEB– SEH
• Il problema che devono risolvere èsempre lo stesso: trovare unacostante tra le varie versioni delsistema operativo
Riflessioni
• Abbiamo visto una serie di attacchiche possono essere portati versoprogrammi con errori diprogrammazione
• Il problema è che questi errori nonsono macroscopici ma spesso sonoinezie
• Basta poco per rendere unprogramma vulnerabile
Sistemi di Tipi
• Il Tipo di una variabile definiscel’insieme dei valori che può assumeredurante l’esecuzione
• I linguaggi di programmazione sipossono classificare in base al lorosistema di tipi e alle sue caratteristiche
Language Safety
• Gli errori run-time possono essere distintiin due classi– trapped errors. Gli errori che vengono
rilevati– untrapped errors. Errori che non vengono
rilevati
• Un buon sistema di tipi può eliminarecompletamente la seconda classe dierrori rendendo il linguaggio safe
Exploit e sistemi di tipi
• Un exploit che sfrutta un qualcheoverflow genera un untrapped error
• E’ possibile eliminare questo tipo dierrori utilizzando linguaggi diprogrammazione safe
• Il linguaggio C non è safe
Bibliografia
• Memory layout Win2000– Solomon, Russanovich “Inside Microsoft Windows 2000”, Microsoft
Press– Articoli di Matt Pietrek su MSJ
• Stack overflow– Aleph1 “Smashing the stack for fun and profit”, Phrack Magazine
49– Dark Spyrit “Win32 Buffer Overflows”, Phrack Magazine 55– Dark Spyrit “Klog - The Frame Pointer overwrite, Phrack Magazine
55
• Heap overflow– Matt Conover “Heap overflows”
• Sistemi di tipi– Luca Cardelli “Type Systems”