Buffer Overflow - Dipartimento di Informatica

Transcript

Buffer Overflow - Dipartimento di Informatica
Argomenti trattati
Internet
„ I servizi di rete
„ Buffer Overflow: teoria, esempi
„ Tecniche di protezione
„ Aggirare StackGuard
„
Buffer Overflow
Attacchi ai servizi di rete
Avella Gianluigi
Cerqua Pasquale
Crucil Sergio
D’Alessandro Oreste
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
Tecnologie di sicurezza utilizzate
300.000.000
250.000.000
Biometria
Chiave pubblica
Smart cards - e-token
Crittografia dei files
Prevenzione intrusioni
Accounting utenti
Crittografia dati trasmessi
IDS
ACL
Firewall
Antivirus
200.000.000
150.000.000
100.000.000
50.000.000
0
Dicembre
1994
Dicembre
1996
Dicembre
1998
Dicembre
2000
Dicembre
2002
0%
20%
40%
60%
80%
100%
Danni economici
Sicurezza Informatica
Problemi dovuti alla “insicurezza” dei servizi informatici
Perdite per tipo di attacco (2004)
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
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 w eb
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
$0
$10
$20
$30
$40
$50
$60
Milioni
Milioni di dollari.
Introduzione al Buffer overflow
Errori nelle configurazioni
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.
…
Scenario “domestico”
Scenari
ƒ
Attacco a client di
servizi remoti.
ƒ Internet
Explorer è
probabilmente il
client
più buggato che si
ricordi.
Server
Attacco locale
Web
FTP
SSH
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
Funzionamento dello stack
main(){
//codice
foo(buffer);
//codice
}
ESP
call 0x80483a9 <foo>
foo(char *buffer){
char a [ 5 ];
strcpy(a,buffer);
}
push
mov
sub
sub
Record di
%ebp
attivazione
%esp,%ebp
$0x18,%esp
$0x8,%esp
a[0]
a[1]
a[2]
a[3]
a[4]
SFP
RET
Registri del processore
EIP = Indirizzo dell’istruzione successiva
Indirizzi di memoria alti
EBP = Base pointer
ESP = Top dello Stack
BP
Smashing the stack
Funzionamento dello stack
main(){
//codice
foo(buffer);
//codice
}
ESP
a[0]
a[1]
a[2]
a[3]
a[4]
SFP
RET
add $0x10,%esp
leave
ret
foo(char *buffer){
char a [ 5 ];
strcpy(a,buffer);
}
EBP
EIP
Se il buffer passato alla funzione
foo() è più di 5 caratteri….
Es: “bbbbbbbbbbbbbbb”
a[0]
a[1]
a[2]
foo(char *buffer){
a[ 5 ];
strcpy(a,buffer);
}
a[3]
a[4]
SFP
RET
Registri del processore
EIP = Indirizzo dell’istruzione successiva
EBP = Base pointer
BP
ESP = Top dello Stack
I caratteri che eccedono il buffer hanno
sovrascritto l’indirizzo di ritorno.
EIP adesso punta ad una locazione di
memoria non valida.
Ghost in the shell
„
„
„
Nop Nop
No operation
\x8b
\x1f
“Shellcode”
Codice esempio
(\bin/sh) 0x0809ff34
Codice arbitrario
Fault
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!
\xeb
Segmentation
Puntatore Inizio
del buffer
Codice exploit
#include <stdio.h>
#include <stdio.h>
main(int argc, char **argv){
main() {
char buffer[10];
int i;
char buffer[33];
if(argc!=2){
printf("Usage:./esempio qualcosa\n");
exit(0);
}
strcpy(buffer,argv[1]);
}
foo(){
printf("Corso di sicurezza su reti\n");
exit(0);
}
for(i=0;i<28;i++)
buffer[i]=0x61;
*(long *)&buffer[28] =0x0804843d;
execl("./esempio","esempio",buffer,NULL);
}
Analisi del problema - 1
Analisi del problema - 2
„
Modifica del flusso di un
programma.
„
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.
Metodi difensivi di StackGuard
L’attacker potrebbe leggere la word canary
„ Quindi tre metodi di difesa
„
… Terminator
¾
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
Canary
La word e una serie di caratteri nulli
Es. 0x00000000
SFP
RET
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
Funzionamento del 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.)
„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
……………………………
Retarray
Retptr
Global Ret Stack
Esempio di funzionamento
main(){
foo();
//codice
………..
foo(){
Retarray
foo2();
//codice
}
foo2(){
0x02
//codice
}
Retptr
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.
„
Rettop
//codice
}
0x01
Rettop
Modalità Speciale
Ret Range check
Gli attacchi basati sul buffer
overflow, tentano di dirottare
A
N
G
E
il flusso del programma verso
il buffer contenete lo shellcode
V
Segmento testo
A
L
I
e quindi verso lo stack.
D
O
Il Ret range check rende lo
Segmento dati
stack non eseguibile.
Stack
Flaw Finder
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
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.
„
R
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.
Flaw Finder
Analisi dei metodi di difesa
Attacchi a StackGuard
Stackguard e StackShield aggiungono
codice e soprattutto “controlli” ai
programmi aumentando sensibilmente
l’overhead.
„ Ma attenzione….non sono infallibili!
„
Falle di StackGuard
„
Inefficienze
Vantaggio offerto da StackGuard:
¾
¾
„
Falle di StackGuard
Protezione dell’indirizzo di ritorno (RET)
…
„
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).
Non basta. Infatti:
¾
¾
¾
L’overflow viene scoperto al termine della funzione
Non protegge nessun altro indirizzo
(saved frame pointer…)
canary può essere aggirato
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
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 - 1
È 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 è immune a questo
attacco
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()
invocare invece una system().
potrebbe
L’attacco riesce anche se SG è utilizzato in
combinazione con StackPatch (rende lo stack
non eseguibile).
That’s all folk!
Attacchi a StackGuard - 3
Buffer Overflow: attacco ai servizi di rete
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
Progetto realizzato da:
„
„
„
„
Avella Gianluigi
Cerqua Pasquale
Crucil Sergio
D’Alessandro Oreste