Argomenti trattati Buffer Overflow Attacchi ai servizi di rete Avella Gianluigi Cerqua Pasquale Crucil Sergio D Alessandro Oreste Internet I servizi di rete Buffer Overflow: teoria, esempi Tecniche di protezione Aggirare StackGuard Sicurezza su reti A.A. 2004/2005 Prof. Masucci Barbara In principio era.arpanet e poi venne Internet Internet è una suite di servizi Tutti basati sul protocollo TCP/IP I più importanti attualmente http: web (es. Apache, Tomcat, IIS) ftp: trasferimento file (es. wu-ftp) smtp, pop, imap: posta elettronica (es. sendmail, postfix)
Lo sviluppo di Internet Tecnologie di sicurezza 300.000.000 Tecnologie di sicurezza utilizzate 250.000.000 200.000.000 150.000.000 100.000.000 50.000.000 0 Dicembre 1994 Dicembre 1996 Dicembre 1998 Dicembre 2000 Dicembre 2002 Biometria Chiave pubblica Smart cards - e-token Crittografia dei files Prevenzione intrusioni Accounting utenti Crittografia dati trasmessi IDS ACL Firewall Antivirus 0% 20% 40% 60% 80% 100% Sicurezza Informatica Problemi dovuti alla insicurezza dei servizi informatici Acquisizione illecita di dati. Accesso indebito a un sistema per l elaborazione di dati. Danneggiamento di dati, inclusa la fabbricazione e la messa in circolazione di virus informatici. Conseguimento fraudolento di una prestazione informatica. Attacchi a sistemi informatici di tipo denial of service. Danneggiamento grave delle reti di comunicazione: perturbamento di pubblici servizi Sabotaggio Violazione del sistema Sito w eb "defacciato" Abuso di applicazioni web Frode informatica Accesso non autorizzato Furto di componenti Frode finanziaria Abuso della rete w ireless Abuso della rete interna Furto di informazioni Denial of Service Virus Danni economici Perdite per tipo di attacco (2004) $0 $10 $20 $30 $40 $50 $60 Milioni Milioni di dollari.
Errori nelle configurazioni Introduzione al Buffer overflow Le principali cause della vulnerabilità del software Configurazioni errate Allocazione di tipi differenti di variabili Errata deallocazione della memoria Cicli infiniti Assenza di controllo sulle operazioni e sui puntatori Buffer overflow Conoscenze necessarie Linguaggio Assembler. Registri CPU. Funzionamento a basso livello di un sistema operativo. Funzionamento (in genere) dei linguaggi di programmazione. Conoscenza di un debugger. Nello specifico: Un sistema GNU/Linux Gnu Debugger Linguaggio C Architettura x86 Intel Teoria ed esempio di un attacco Il buffer overflow è un errore di programmazione dovuto all errata gestione dei dati all interno di un programma. In C un buffer viene normalmente associato ad un array. L overflow di un buffer consiste nel riempire oltre il limite tale buffer. Un attacker è in grado di sfruttare questo errore per causare il crash di un servizio remoto o penetrare all'interno di un sistema. Tipi di attacchi dovuti a questo errore: Modifica del flusso di un programma. Iniezione ed esecuzione di codice arbitrario. Modifica di un puntatore a funzione. Modifica dei dati passati ad una funzione.
Scenari Scenario domestico Attacco locale Server Web FTP SSH Attacco a client di servizi remoti. Internet Explorer è probabilmente il client più buggato che si ricordi. Un processo in memoria Ogni processo caricato in memoria, viene diviso in tre parti. Segmento testo Segmento dati Stack Lo stack è una struttura dati cruciale per il funzionamento di un processo. Funzionamento di tipo LIFO PUSH e POP ( Operazioni ) Indirizzi di memoria bassi Segmento testo Segmento dati Stack Indirizzi di memoria alti main(){ foo(buffer); foo(char *buffer){ char a [ 5 ]; strcpy(a,buffer); Funzionamento dello stack call 0x80483a9 <foo> push %ebp Record di mov %esp,%ebp attivazione sub $0x18,%esp sub $0x8,%esp Registri del processore EIP = Indirizzo dell istruzione successiva EBP = Base pointer ESP = Top dello Stack ESP a [ 0 ] a [ 1 ] a [ 2 ] a [ 3 ] a [ 4 ] SFP RET BP
main(){ foo(buffer); Funzionamento dello stack foo(char *buffer){ char a [ 5 ]; strcpy(a,buffer); add $0x10,%esp leave ret Registri del processore EIP = Indirizzo dell istruzione successiva EBP = Base pointer ESP = Top dello Stack EBP EIP ESP a [ 0 ] a [ 1 ] a [ 2 ] a [ 3 ] a [ 4 ] SFP RET BP Smashing the stack Se il buffer passato alla funzione foo() è più di 5 caratteri. Es: bbbbbbbbbbbbbbb foo(char *buffer){ a[ 5 ]; strcpy(a,buffer); I caratteri che eccedono il buffer hanno sovrascritto l indirizzo di ritorno. EIP adesso punta ad una locazione di memoria non valida. a [ 0 ] a [ 1 ] a [ 2 ] a [ 3 ] a [ 4 ] SFP RET Segmentation Fault Ghost in the shell Un esempio A questo punto il programma è andato in crash! Ma un attacker potrebbe confezionare un array da passare alla funzione foo() in modo tale che venga dirottata l esecuzione del programma stesso. Ma nella maggior parte dei casi questo bug viene sfruttato per costringere il programma ad eseguire codice arbitrario! Nop Nop \x8b \xeb \x1f (\bin/sh) 0x0809ff34 No operation Codice arbitrario Shellcode Puntatore Inizio del buffer Codice esempio #include <stdio.h> main(int argc, char **argv){ char buffer[10]; if(argc!=2){ printf("usage:./esempio qualcosa\n"); exit(0); strcpy(buffer,argv[1]); foo(){ printf("corso di sicurezza su reti\n"); exit(0); #include <stdio.h> main() { int i; char buffer[33]; for(i=0;i<28;i++) buffer[i]=0x61; *(long *)&buffer[28] =0x0804843d; execl("./esempio","esempio",buffer,null); Codice exploit
Analisi del problema - 1 Modifica del flusso di un programma. Analisi del problema - 2 Firewall ed antivirus sono impotenti! Iniezione di codice arbitrario. Danni economici elevati. Un attacker può prendere pieno possesso della macchina vittima. Metà degli advisory del Cert, sono su problemi legati al Buffer Overflow. Difesa dal Buffer Overflow Come difendersi Programmi modulari e facili da debuggare. Testing. Stack non eseguibile. Controllo della dimensione degli array. Utilizzo di linguaggi tipizzati. Controllo dell integrità sui puntatori. Utilizzo di tool specifici. Pregare.
Tool di difesa StackGuard, StackShield, FlawFinder automatizzano alcuni dei suddetti metodi di prevenzione. Sono programmi open source. Disponibili unicamente per il mondo Unix. StackGuard e StackShield non richiedono aggiunte al codice esistente, ma non tutti i programmi possono essere ricompilati. StackGuard StackGuard è una patch per gcc. La prima versione prevedeva la protezione da scrittura della word RET. (Memguard) Interviene nel prologo e nell epilogo di ogni funzione. Canary Utilizza una canary word nel record di attivazione. Un tentativo di sovrascrivere il RET provocherebbe il canto del canarino. SFP RET Metodi difensivi di StackGuard L attacker potrebbe leggere la word canary Quindi tre metodi di difesa Terminator Canary La word è scelta come combinazione di caratteri nulli, ritorno a capo e fine linea. Random Canary La word è scelta in modo random a run-time. Esiste una variante chiamata XOR random canary. Null Canary La word e una serie di caratteri nulli Es. 0x00000000 StackShield StackShield è un software simile a StackGuard. Protegge il valore RET da attacchi ti tipo Buffer Overflow. Aggiunge codice assembly al prologo ed all epilogo di ogni funzione. Utilizza tre metodi di funzionamento Global Ret Stack Ret range check. Modalità speciale ( attacchi contro puntatori a funzione ). Non richiede al programmatore di aggiungere codice.
Global Ret Stack La prima tecnica di protezione prevede l utilizzo di un array di 256 elementi (Retarray) da trattare come uno stack dove verranno salvati gli indirizzi di ritorno. Si utilizzano due puntatori speciali Retptr ( puntatore alla prima locazione libera di Retarray). Rettop ( puntatore all ultimo elemento dell array.) Funzionamento del Global Ret Stack Nel prologo di ogni funzione, Retptr viene confrontato con Rettop. Se Retptr è <= di Rettop, l indirizzo viene memorizzato nell array e Retptr viene incrementato. Altrimenti l indirizzo di ritorno non viene salvato ma Retptr viene incrementato comunque per sincronizzazione. Nell epilogo avviene nuovamente il controllo e se Retptr è <= di Rettop l indirizzo salvato viene ripristinato e Retptr decrementato. 0x00 0x01 Retptr Retarray Rettop Esempio di funzionamento main(){ Rettop foo(); foo(){ foo2(); foo2(){.. 0x02 Retptr 0x01 Retarray Global Ret Stack In questo modo anche se un buffer overflow sovrascrive il RET, questo viene ripristinato all epilogo. La dimensione di Retarray può essere aumentata. L attacco viene inibito ma non segnalato. Esiste una modalità alternativa in cui il RET viene confrontato con il suo clone nel Retarray.
Ret Range check Modalità Speciale Gli attacchi basati sul buffer overflow, tentano di dirottare il flusso del programma verso il buffer contenete lo shellcode e quindi verso lo stack. Il Ret range check rende lo stack non eseguibile. R A N G E V A L I D O Segmento testo Segmento dati Stack Un puntatore a funzione viene allocato in una zona di memoria in modo casuale. ( stack, heap, segmento dati). Se viene allocato nello stack, l attacker cerca di corrompere il puntatore tramite l overflow di un buffer. StackShield inizializza un variabile casuale e controlla che non si trovi al di fuori del segmento dati, poiché anche il puntatore verrà allocato nei pressi della variabile. Flaw Finder Flaw Finder E un tool di sviluppo a supporto dei programmatori. È capace di analizzare codice sorgente C/C++. È un semplice parser. Produce in output solo una lista con un grado di potenziale pericolosità delle funzioni. Il database del programma (ruleset) contiene informazioni su operazioni comuni che possono manifestare problemi concernenti la sicurezza. La Ruleset è aggiornabile. Ogni elemento è costituito dalla tupla (Hook, Level, Warning, Suggestion, Category, URL, Other). Per ogni match si propone al programmatore una soluzione.
Analisi dei metodi di difesa Stackguard e StackShield aggiungono codice e soprattutto controlli ai programmi aumentando sensibilmente l overhead. Ma attenzione.non sono infallibili! Attacchi a StackGuard Falle di StackGuard Vantaggio offerto da StackGuard: Protezione dell indirizzo di ritorno (RET) Non basta. Infatti: L overflow viene scoperto al termine della funzione Non protegge nessun altro indirizzo (saved frame pointer ) canary può essere aggirato Falle di StackGuard Inefficienze Un overflow su un buffer situato prima di una o più variabili locali permette di sovrascrivere anche queste ultime. Se vi è la possibilità di manipolare un puntatore si possono alterare importanti sezioni di memoria (fnlist, GOT, frame pointer).
Attacchi a StackGuard - 1 Attacchi a StackGuard - 1 Attacco Emsi: sostituzioni nella fnlist fnlist contiene gli indirizzi delle funzioni registrate attraverso atexit() (gdb) b main Breakpoint 1 at 0x8048790 (gdb) r Starting program: /root/stackguard/c/stackguard/vul Breakpoint 1, 0x8048790 in main () (gdb) x/10x &fnlist 0x400eed78 <fnlist>: 0x00000000 0x00000002 0x00000003 0x4000b8c0 0x400eed88 <fnlist+16>: 0x00000000 0x00000003 0x08048c20 0x00000000 0x400eed98 <fnlist+32>: 0x00000000 0x00000000 È possibile con un debugger scoprirne l indirizzo e, avendo un puntatore a disposizione nel programma, alterare la registrazione delle funzioni da eseguire all invocazione di exit(). Nemmeno StackShield attacco è immune a questo Attacchi a StackGuard - 2 Sostituzioni nella Global Offset Table (GOT) Simile al precendente attacco: l obiettivo è alterare l ordine dell invocazione delle funzioni. GOT contiene la corrispondenza indirizzo funzione. Avendo la possibilità di manipolare un puntatore è possibile cambiare l indirizzo associato a una funzione utilizzata. Attacchi a StackGuard - 2 oredal@homer:~/src/sg/tests$ cc -o sg1 sg1.c oredal@homer:~/src/sg/tests$ readelf S sg1 grep got [ 8].rel.got REL 08048358 etc... [20].got PROGBITS 08049888 etc... Come risultato una printf() potrebbe invocare invece una system(). L attacco riesce anche se SG è utilizzato in combinazione con StackPatch (rende lo stack non eseguibile).
Attacchi a StackGuard - 3 Alterazione del frame pointer La combinazione d uso di SG con un terminator canary (valore fisso 0x000aff0d) permette di arrivare alla sovrascrittura del frame pointer (e di non sovrascrivere il canary) attraverso le comuni funzioni di manipolazione delle stringhe. In questo modo è possibile ottenere il controllo completo delle variabili locali e degli argomenti delle funzioni. Il frame pointer non è utilizzato nei programmi compilati con l opzione fomit-frame-pointer That s all folk! Buffer Overflow: attacco ai servizi di rete Progetto realizzato da: Avella Gianluigi Cerqua Pasquale Crucil Sergio D Alessandro Oreste