14.06.2013 Views

Buffer Overflow - Dipartimento di Informatica ed Applicazioni

Buffer Overflow - Dipartimento di Informatica ed Applicazioni

Buffer Overflow - Dipartimento di Informatica ed Applicazioni

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Buffer</strong> <strong>Overflow</strong><br />

Attacchi ai servizi <strong>di</strong> rete<br />

Avella Gianluigi<br />

Cerqua Pasquale<br />

Crucil Sergio<br />

D’Alessandro Oreste<br />

Sicurezza su reti A.A. 2004/2005<br />

Prof. Masucci Barbara<br />

Argomenti trattati<br />

Internet<br />

I servizi <strong>di</strong> rete<br />

<strong>Buffer</strong> <strong>Overflow</strong>: teoria, esempi<br />

Tecniche <strong>di</strong> protezione<br />

Aggirare StackGuard<br />

In principio era….Arpanet ……e poi venne Internet<br />

Internet è una suite <strong>di</strong> servizi<br />

Tutti basati sul protocollo TCP/IP<br />

I più importanti attualmente<br />

http: web (es. Apache, Tomcat, IIS)<br />

ftp: trasferimento file (es. wu-ftp)<br />

smtp, pop, imap: posta elettronica (es. sendmail,<br />

postfix)


300.000.000<br />

250.000.000<br />

200.000.000<br />

150.000.000<br />

100.000.000<br />

50.000.000<br />

Lo sviluppo <strong>di</strong> Internet<br />

0<br />

Dicembre<br />

1994<br />

Dicembre<br />

1996<br />

Dicembre<br />

1998<br />

Dicembre<br />

2000<br />

Sicurezza <strong>Informatica</strong><br />

Problemi dovuti alla “insicurezza” dei servizi informatici<br />

Dicembre<br />

2002<br />

Acquisizione illecita <strong>di</strong> dati.<br />

Accesso indebito a un sistema per l’elaborazione <strong>di</strong><br />

dati.<br />

Danneggiamento <strong>di</strong> dati, inclusa la fabbricazione e<br />

la messa in circolazione <strong>di</strong> virus informatici.<br />

Conseguimento fraudolento <strong>di</strong> una prestazione<br />

informatica.<br />

Attacchi a sistemi informatici <strong>di</strong> tipo “denial of<br />

service“.<br />

Danneggiamento grave delle reti <strong>di</strong> comunicazione:<br />

perturbamento <strong>di</strong> pubblici servizi<br />

Tecnologie <strong>di</strong> sicurezza<br />

Tecnologie <strong>di</strong> sicurezza utilizzate<br />

Biometria<br />

Chiave pubblica<br />

Smart cards - e-token<br />

Crittografia dei files<br />

Prevenzione intrusioni<br />

Accounting utenti<br />

Crittografia dati trasmessi<br />

IDS<br />

ACL<br />

Firewall<br />

Antivirus<br />

0% 20% 40% 60% 80% 100%<br />

Sabotaggio<br />

Violazione del sistema<br />

Sito w eb "defacciato"<br />

Abuso <strong>di</strong> applicazioni w eb<br />

Frode informatica<br />

Accesso non autorizzato<br />

Furto <strong>di</strong> componenti<br />

Frode finanziaria<br />

Abuso della rete w ireless<br />

Abuso della rete interna<br />

Furto <strong>di</strong> informazioni<br />

Denial of Service<br />

Virus<br />

Danni economici<br />

Per<strong>di</strong>te per tipo <strong>di</strong> attacco (2004)<br />

$0 $10 $20 $30 $40 $50 $60<br />

Milioni<br />

Milioni <strong>di</strong> dollari.


Errori nelle configurazioni<br />

Le principali cause della vulnerabilità del software<br />

Configurazioni errate<br />

Allocazione <strong>di</strong> tipi <strong>di</strong>fferenti <strong>di</strong> variabili<br />

Errata deallocazione della memoria<br />

Cicli infiniti<br />

Assenza <strong>di</strong> controllo sulle operazioni e sui<br />

puntatori<br />

<strong>Buffer</strong> overflow<br />

Conoscenze necessarie<br />

Linguaggio Assembler.<br />

Registri CPU.<br />

Funzionamento a basso livello <strong>di</strong> un<br />

sistema operativo.<br />

Funzionamento (in genere) dei<br />

linguaggi <strong>di</strong> programmazione.<br />

Conoscenza <strong>di</strong> un debugger.<br />

Nello specifico:<br />

Un sistema GNU/Linux<br />

Gnu Debugger<br />

Linguaggio C<br />

Architettura x86 Intel<br />

Introduzione al <strong>Buffer</strong> overflow<br />

Teoria <strong>ed</strong> esempio <strong>di</strong> un attacco<br />

Il buffer overflow è un errore <strong>di</strong> programmazione dovuto<br />

all’errata gestione dei dati all’interno <strong>di</strong> un programma.<br />

In C un buffer viene normalmente associato ad un array.<br />

L’overflow <strong>di</strong> un buffer consiste nel riempire oltre il limite<br />

tale buffer.<br />

Un attacker è in grado <strong>di</strong> sfruttare questo errore per<br />

causare il crash <strong>di</strong> un servizio remoto o penetrare<br />

all'interno <strong>di</strong> un sistema.<br />

Tipi <strong>di</strong> attacchi dovuti a questo errore:<br />

Mo<strong>di</strong>fica del flusso <strong>di</strong> un programma.<br />

Iniezione <strong>ed</strong> esecuzione <strong>di</strong> co<strong>di</strong>ce arbitrario.<br />

Mo<strong>di</strong>fica <strong>di</strong> un puntatore a funzione.<br />

Mo<strong>di</strong>fica dei dati passati ad una funzione.


Scenari<br />

Server<br />

Attacco locale Web<br />

Un processo in memoria<br />

Ogni processo caricato in<br />

memoria, viene <strong>di</strong>viso in tre<br />

parti.<br />

Segmento testo<br />

Segmento dati<br />

Stack<br />

Lo stack è una struttura dati<br />

cruciale per il<br />

funzionamento <strong>di</strong> un<br />

processo.<br />

Funzionamento <strong>di</strong> tipo LIFO<br />

PUSH e POP ( Operazioni )<br />

FTP SSH<br />

In<strong>di</strong>rizzi <strong>di</strong> memoria bassi<br />

Segmento<br />

testo<br />

Segmento dati<br />

Stack<br />

In<strong>di</strong>rizzi <strong>di</strong> memoria alti<br />

Attacco a client <strong>di</strong><br />

servizi remoti.<br />

Internet Explorer è<br />

probabilmente il<br />

client<br />

più buggato che si<br />

ricor<strong>di</strong>.<br />

main(){<br />

//co<strong>di</strong>ce<br />

foo(buffer);<br />

//co<strong>di</strong>ce<br />

}<br />

foo(char *buffer){<br />

char a [ 5 ];<br />

strcpy(a,buffer);<br />

}<br />

Scenario “domestico”<br />

Funzionamento dello stack<br />

call 0x80483a9 <br />

push %ebp Record <strong>di</strong><br />

mov %esp,%ebp<br />

attivazione<br />

sub $0x18,%esp<br />

sub $0x8,%esp<br />

Registri del processore<br />

EIP = In<strong>di</strong>rizzo dell’istruzione successiva<br />

EBP = Base pointer<br />

ESP = Top dello Stack<br />

ESP<br />

a [ 0 ]<br />

a [ 1 ]<br />

a [ 2 ]<br />

a [ 3 ]<br />

a [ 4 ]<br />

SFP<br />

RET<br />

BP


main(){<br />

//co<strong>di</strong>ce<br />

foo(buffer);<br />

//co<strong>di</strong>ce<br />

}<br />

Funzionamento dello stack<br />

foo(char *buffer){<br />

char a [ 5 ];<br />

strcpy(a,buffer);<br />

}<br />

add $0x10,%esp<br />

leave<br />

ret<br />

Registri del processore<br />

EIP = In<strong>di</strong>rizzo dell’istruzione successiva<br />

EBP = Base pointer<br />

ESP = Top dello Stack<br />

EBP<br />

EIP<br />

Ghost in the shell<br />

A questo punto il programma è andato in crash!<br />

Ma un attacker potrebbe “confezionare” un array da<br />

passare alla funzione foo() in modo tale che venga<br />

<strong>di</strong>rottata l’esecuzione del programma stesso.<br />

Ma nella maggior parte dei casi questo bug viene<br />

sfruttato per costringere il programma ad eseguire<br />

co<strong>di</strong>ce arbitrario!<br />

ESP<br />

a [ 0 ]<br />

a [ 1 ]<br />

a [ 2 ]<br />

a [ 3 ]<br />

a [ 4 ]<br />

SFP<br />

RET<br />

Nop Nop \x8b \xeb \x1f (\bin/sh) 0x0809ff34<br />

No operation Co<strong>di</strong>ce arbitrario<br />

“Shellcode”<br />

BP<br />

Puntatore Inizio<br />

del buffer<br />

Smashing the stack<br />

Se il buffer passato alla funzione<br />

foo() è più <strong>di</strong> 5 caratteri….<br />

Es: “bbbbbbbbbbbbbbb”<br />

foo(char *buffer){<br />

a[ 5 ];<br />

strcpy(a,buffer);<br />

}<br />

I caratteri che ecc<strong>ed</strong>ono il buffer hanno<br />

sovrascritto l’in<strong>di</strong>rizzo <strong>di</strong> ritorno.<br />

EIP adesso punta ad una locazione <strong>di</strong><br />

memoria non valida.<br />

Un esempio<br />

a [ 0 ]<br />

a [ 1 ]<br />

a [ 2 ]<br />

a [ 3 ]<br />

a [ 4 ]<br />

SFP<br />

RET<br />

Segmentation<br />

Fault<br />

Co<strong>di</strong>ce esempio Co<strong>di</strong>ce exploit<br />

#include <br />

#include <br />

main(int argc, char **argv){<br />

char buffer[10];<br />

if(argc!=2){<br />

printf("Usage:./esempio qualcosa\n");<br />

exit(0);<br />

}<br />

strcpy(buffer,argv[1]);<br />

}<br />

foo(){<br />

printf("Corso <strong>di</strong> sicurezza su reti\n");<br />

exit(0);<br />

}<br />

main() {<br />

int i;<br />

char buffer[33];<br />

for(i=0;i


Analisi del problema - 1<br />

Mo<strong>di</strong>fica del flusso <strong>di</strong> un<br />

programma.<br />

“Iniezione” <strong>di</strong> co<strong>di</strong>ce arbitrario.<br />

Un attacker può prendere pieno<br />

possesso della macchina “vittima”.<br />

Analisi del problema - 2<br />

Firewall <strong>ed</strong> antivirus sono<br />

impotenti!<br />

Danni economici elevati.<br />

Metà degli advisory del Cert, sono<br />

su problemi legati al <strong>Buffer</strong><br />

<strong>Overflow</strong>.<br />

Difesa dal <strong>Buffer</strong> <strong>Overflow</strong> Come <strong>di</strong>fendersi<br />

Programmi modulari e facili da debuggare.<br />

Testing.<br />

Stack non eseguibile.<br />

Controllo della <strong>di</strong>mensione degli array.<br />

Utilizzo <strong>di</strong> linguaggi “tipizzati”.<br />

Controllo dell’integrità sui puntatori.<br />

Utilizzo <strong>di</strong> tool specifici.<br />

Pregare….


Tool <strong>di</strong> <strong>di</strong>fesa<br />

StackGuard, StackShield, FlawFinder<br />

automatizzano alcuni dei suddetti meto<strong>di</strong><br />

<strong>di</strong> prevenzione.<br />

Sono programmi open source.<br />

Disponibili unicamente per il mondo Unix.<br />

StackGuard e StackShield non<br />

richi<strong>ed</strong>ono aggiunte al co<strong>di</strong>ce esistente,<br />

ma non tutti i programmi possono essere<br />

ricompilati.<br />

Meto<strong>di</strong> <strong>di</strong>fensivi <strong>di</strong> StackGuard<br />

L’attacker potrebbe leggere la word canary<br />

Quin<strong>di</strong> tre meto<strong>di</strong> <strong>di</strong> <strong>di</strong>fesa<br />

Terminator Canary<br />

La word è scelta come combinazione <strong>di</strong> caratteri nulli, ritorno<br />

a capo e fine linea.<br />

Random Canary<br />

La word è scelta in modo random a run-time.<br />

Esiste una variante chiamata XOR random canary.<br />

Null Canary<br />

La word e una serie <strong>di</strong> caratteri nulli<br />

Es. 0x00000000<br />

StackGuard<br />

StackGuard è una “patch” per gcc.<br />

La prima versione prev<strong>ed</strong>eva la<br />

protezione da scrittura della word<br />

RET. (Memguard)<br />

Interviene nel<br />

prologo e nell’epilogo<br />

<strong>di</strong> ogni funzione.<br />

Utilizza una “canary” word<br />

nel record <strong>di</strong> attivazione.<br />

Un tentativo <strong>di</strong> sovrascrivere il RET<br />

provocherebbe “il canto” del canarino.<br />

StackShield<br />

SFP<br />

Canary RET<br />

StackShield è un software simile a StackGuard.<br />

Protegge il valore RET da attacchi ti tipo<br />

<strong>Buffer</strong> <strong>Overflow</strong>.<br />

Aggiunge co<strong>di</strong>ce assembly al prologo <strong>ed</strong><br />

all’epilogo <strong>di</strong> ogni funzione.<br />

Utilizza tre meto<strong>di</strong> <strong>di</strong> funzionamento<br />

Global Ret Stack<br />

Ret range check.<br />

Modalità speciale ( attacchi contro puntatori a funzione ).<br />

Non richi<strong>ed</strong>e al programmatore <strong>di</strong> aggiungere co<strong>di</strong>ce.


Global Ret Stack<br />

La prima tecnica <strong>di</strong> protezione prev<strong>ed</strong>e<br />

l’utilizzo <strong>di</strong> un array <strong>di</strong> 256 elementi<br />

(Retarray) da trattare come uno stack<br />

dove verranno salvati gli in<strong>di</strong>rizzi <strong>di</strong> ritorno.<br />

Si utilizzano due puntatori speciali<br />

Retptr ( puntatore alla prima locazione libera<br />

<strong>di</strong> Retarray).<br />

Rettop ( puntatore all’ultimo elemento<br />

dell’array.)<br />

main(){<br />

//co<strong>di</strong>ce<br />

foo();<br />

//co<strong>di</strong>ce<br />

}<br />

foo(){<br />

foo2();<br />

//co<strong>di</strong>ce<br />

}<br />

foo2(){<br />

//co<strong>di</strong>ce<br />

}<br />

Esempio <strong>di</strong> funzionamento<br />

Rettop<br />

Retptr<br />

………..<br />

0x02<br />

0x01<br />

Retarray<br />

Funzionamento del Global Ret Stack<br />

Nel prologo <strong>di</strong> ogni funzione, Retptr viene confrontato con Rettop.<br />

Se Retptr è


Ret Range check<br />

Gli attacchi basati sul buffer<br />

overflow, tentano <strong>di</strong> <strong>di</strong>rottare<br />

il flusso del programma verso<br />

il buffer contenete lo shellcode<br />

e quin<strong>di</strong> verso lo stack.<br />

Il Ret range check rende lo<br />

stack non eseguibile.<br />

R<br />

A<br />

N<br />

G<br />

E<br />

V<br />

A<br />

L<br />

I<br />

D<br />

O<br />

Flaw Finder<br />

Segmento testo<br />

Segmento dati<br />

Stack<br />

E’ un tool <strong>di</strong> sviluppo a supporto dei programmatori.<br />

È capace <strong>di</strong> analizzare co<strong>di</strong>ce sorgente C/C++.<br />

È un semplice parser. Produce in output solo una lista con<br />

un grado <strong>di</strong> potenziale pericolosità delle funzioni.<br />

Il database del programma (ruleset) contiene informazioni<br />

su operazioni comuni che possono manifestare problemi<br />

concernenti la sicurezza.<br />

La Ruleset è aggiornabile. Ogni elemento è costituito dalla<br />

tupla (Hook, Level, Warning, Suggestion, Category, URL,<br />

Other).<br />

Per ogni match si propone al programmatore una<br />

soluzione.<br />

Modalità Speciale<br />

Un puntatore a funzione viene allocato in<br />

una zona <strong>di</strong> memoria in modo casuale.<br />

( stack, heap, segmento dati).<br />

Se viene allocato nello stack, l’attacker<br />

cerca <strong>di</strong> corrompere il puntatore tramite<br />

l’overflow <strong>di</strong> un buffer.<br />

StackShield inizializza un variabile<br />

casuale e controlla che non si trovi al <strong>di</strong><br />

fuori del segmento dati, poiché anche il<br />

puntatore verrà allocato nei pressi della<br />

variabile.<br />

Flaw Finder


Analisi dei meto<strong>di</strong> <strong>di</strong> <strong>di</strong>fesa<br />

Stackguard e StackShield aggiungono<br />

co<strong>di</strong>ce e soprattutto “controlli” ai<br />

programmi aumentando sensibilmente<br />

l’overhead.<br />

Ma attenzione….non sono infallibili!<br />

Falle <strong>di</strong> StackGuard<br />

Vantaggio offerto da StackGuard:<br />

Protezione dell’in<strong>di</strong>rizzo <strong>di</strong> ritorno (RET)<br />

…<br />

Non basta. Infatti:<br />

L’overflow viene scoperto al termine della funzione<br />

Non protegge nessun altro in<strong>di</strong>rizzo<br />

(sav<strong>ed</strong> frame pointer…)<br />

canary può essere aggirato<br />

Attacchi a StackGuard<br />

Falle <strong>di</strong> StackGuard<br />

Inefficienze<br />

Un overflow su un<br />

buffer situato prima <strong>di</strong><br />

una o più variabili locali<br />

permette <strong>di</strong><br />

sovrascrivere anche<br />

queste ultime.<br />

Se vi è la possibilità <strong>di</strong> manipolare un puntatore si<br />

possono alterare importanti sezioni <strong>di</strong> memoria (fnlist,<br />

GOT, frame pointer).


Attacchi a StackGuard - 1<br />

Attacco Emsi: sostituzioni nella fnlist<br />

fnlist contiene gli in<strong>di</strong>rizzi delle funzioni registrate<br />

attraverso atexit()<br />

(gdb) b main<br />

Breakpoint 1 at 0x8048790<br />

(gdb) r<br />

Starting program: /root/StackGuard/c/StackGuard/vul<br />

Breakpoint 1, 0x8048790 in main ()<br />

(gdb) x/10x &fnlist<br />

0x400e<strong>ed</strong>78 : 0x00000000 0x00000002 0x00000003 0x4000b8c0<br />

0x400e<strong>ed</strong>88 : 0x00000000 0x00000003 0x08048c20 0x00000000<br />

0x400e<strong>ed</strong>98 : 0x00000000 0x00000000<br />

Attacchi a StackGuard - 2<br />

Sostituzioni nella Global Offset Table (GOT)<br />

Simile al precendente attacco: l’obiettivo è<br />

alterare l’or<strong>di</strong>ne dell’invocazione delle funzioni.<br />

GOT contiene la corrispondenza in<strong>di</strong>rizzo –<br />

funzione.<br />

Avendo la possibilità <strong>di</strong> manipolare un puntatore<br />

è possibile cambiare l’in<strong>di</strong>rizzo associato a una<br />

funzione utilizzata.<br />

Attacchi a StackGuard - 1<br />

È possibile con un debugger scoprirne l’in<strong>di</strong>rizzo<br />

e, avendo un puntatore a <strong>di</strong>sposizione nel<br />

programma, alterare la registrazione delle<br />

funzioni da eseguire all’invocazione <strong>di</strong> exit().<br />

Nemmeno StackShield è immune a questo<br />

attacco<br />

Attacchi a StackGuard - 2<br />

or<strong>ed</strong>al@Homer:~/src/sg/tests$ cc -o sg1 sg1.c<br />

or<strong>ed</strong>al@Homer:~/src/sg/tests$ readelf –S sg1|grep got<br />

[ 8] .rel.got REL 08048358 etc...<br />

[20] .got PROGBITS 08049888 etc...<br />

Come risultato una printf() potrebbe<br />

invocare invece una system().<br />

L’attacco riesce anche se SG è utilizzato in<br />

combinazione con StackPatch (rende lo stack<br />

non eseguibile).


Attacchi a StackGuard - 3<br />

Alterazione del frame pointer<br />

La combinazione d’uso <strong>di</strong> SG con un terminator canary (valore fisso<br />

0x000aff0d) permette <strong>di</strong> arrivare alla sovrascrittura del frame pointer<br />

(e <strong>di</strong> non sovrascrivere il canary) attraverso le comuni funzioni <strong>di</strong><br />

manipolazione delle stringhe.<br />

In questo modo è possibile ottenere il controllo completo delle<br />

variabili locali e degli argomenti delle funzioni.<br />

Il frame pointer non è utilizzato nei programmi compilati con<br />

l’opzione –fomit-frame-pointer<br />

That’s all folk!<br />

<strong>Buffer</strong> <strong>Overflow</strong>: attacco ai servizi <strong>di</strong> rete<br />

Avella Gianluigi<br />

Cerqua Pasquale<br />

Crucil Sergio<br />

D’Alessandro Oreste<br />

Progetto realizzato da:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!