2. “
2
(...) i sistemi hanno proprietá emergenti, ossia sono in grado di es-
eguire operazioni che non possono essere previste né dagli utenti né dai
Progettisti.
(...)tutti i sistemi hanno dei bug, ossia dei difetti. (...) i bug sono di-
versi dai guasti. Quando un sistema si guasta, smette di funzionare. Un
sistema difettoso, invece, si comporta in modo insolito in determinate
circostanze, in genere irripetibili e quasi sempre inspiegabili. I bug sono
una caratteristica unica dei sistemi. Le macchine possono rompersi o
non funzionare, ma solo un sistema puó avere un bug.
* Bruce Schneier, Sicurezza Digitale: Miti da sfatare, strategie da adottare p.10
3. “
3
Pazzesco
●
OpenSSL: progetto OpenSource che implementa il protocollo
SSL/TLS
●
SSL/TLS: protocollo di sicurezza che garantisce la privacy
della comunicazione
●
Insicurezza più totale!
Affascinante
●
Dati utente, user/password, chat private, email, cookie, ...
●
Private Key del Server
Salvatore Lentini (Degree Thesis – 29/07/2016, University of Catania)
4. 4
Heartbeat
Extension
RFC 4366 introduce il concetto di “Estensione”
per il protocollo SSL/TLS
Aggiunge dei campi alla fine dei messaggi
di Client Hello e Server Hello
A che servono queste “Estensioni”?
●
A negoziare ulteriori funzionalità
●
Quindi, il “se” e il “come” ingaggiare un
certo protocollo
Nell’immagine d’esempio è esplicitato il concetto:
l’estensione Heartbeat sancisce se
client e server vogliono usare un altro
protocollo che si chiama “Heartbeat”
5. 5
Heartbeat
Protocol
E’ un nuovo sotto-protocollo per SSL/TLS in aggiunta a quelli già presenti (1)
●
Serve a mantenere attiva la connessione senza dover rinegoziare l’handshake
SSL/TLS (nei momenti di inattività)
●
Nel record header, il campo CONTENT TYPE è impostato a 24 (0x18)
●
Definito nell’ RFC6520 nel 2012
●
Consta di due messaggi:
➢
Heartbeat Request il client manda al server
➢
Heartbeat Response il server manda al client
1
SSL and TLS: Theory and Practice, Second Edition - Rolf Oppliger (pag. 129)
7. 7
La nuova “feature” TLS Heartbeat venne inserita da
Robin Seggelmann
nel 2012 con la versione 1.0.1 di OpenSSL.
⊡ Momenti di inattività (e.g. Lettura di un quotidiano online)
⊡ Mantenere fresca la connessione: evitare di rinegoziare i
parametri stabiliti durante l’handshake.
⊡ Il client invia periodicamente dei pacchetti (battiti cardiaci) con
contenuto casuale al server e quest’ultimo se attivo risponde
rimandandoli al client
⊡ Il client capisce che il server è ancora attivo ed in stato di
“pronto” per ricevere le successive richieste
Heartbeat
Protocol
8. 8
Length > Length string ?
Il server riceve il pacchetto e salva il suo contenuto all’interno di un’area di
memoria della lunghezza pari a quella passata nel pacchetto. A questo
punto, il server risponderà al client mandando il contenuto di quest’area di
memoria… mandando tutti i dati contigui alla stringa, nei limiti di
quell’area di memoria
L’attaccante è in grado di leggere dump di memoria per un massimo di 64KB per volta
10. 10
⊡ Impostando il campo length (di 2 byte = 16 bit) dell’Heartbeat Message,
un attaccante è in grado di leggere 216
indirizzi di memoria. Poichè ogni
indirizzo di memoria è di 1 byte, l’attaccante riuscirà ad estrarre
65536byte (64KB) massimo per volta.
⊡ Bug scoperto dall’ingegnere di Google Neel Metha insieme al gruppo
Codenomicon. Essi resero pubblico il bug il 7 Aprile del 2014
⊡ Dichiarazione di Seggelman: “una svista”da parte mia e da parte
dell’intero team di sviluppo di OpenSSL.
⊡ Alcuni sistemi embedded, hardware e mobile,
che usano OpenSSL, che non possono essere
aggiornati, non riceveranno mai
l’aggiornamento!
Bug
Heartbleed
11. 11
Nelle festività divertiti, non lavorare!
“Robin Seggelmann alle 23:59 pm del 31 Dicembre
2011, Germania, caricava la nuova feature Heartbeat su
OpenSSL Project”
12. 12
“61 minuti dopo la mezzanotte,
il codice bug-gato riceveva il
commit”
15. 15
Comprensione
Il server risponde inviando 65536 byte di dati (invece che soli 5 byte)
In questo modo, l’attaccante riceve dei dati che stanno in un’area di memoria
contigua alla sua precedente richiesta. Questi dati sono dati sensibili.
L’attaccante invia un payload di dati di 5 byteL’attaccante invia un payload di dati di 5 byte
falsificando la lunghezza e impostandofalsificando la lunghezza e impostando
tutti I 2 bytetutti I 2 byte
16. 16
IL CODICE INSANGUINATO
I pacchetti Heartbeat
prendono il nome di
HeartbeatMessage
Il pacchetto inviato dal
client al server è un
HeartbeatRequest
Il pacchetto inviato dal
server al client, in risposta
a quest’ultimo, prende il
nome di
HeartbeatResponse
Mancato controllo della lunghezza
del payload, prima della funzione
memcpy che effettua una copia
binaria dei dati da una sorgente
ad una destinazione
(HeartbeatRequest, Buffer di
memoria del server)
Codice in C
17. 17
Struttura messaggio
Heartbeat
Un generico Heartbeat Message, in accordo all’RFC6250 ha la
seguente forma:
Type:tipologia di messaggio (heartbeatRequest oppure heartbeatResponse). Campo di lunghezza 1 byte
payload_length:indica la lunghezza del payload. Campo di lunghezza 2 byte
Cioè il payload corrispondente dovrebbe essere di 2bit_length byte
payload: contiene il payload di dati inviato (Massimo di 65536 byte)
padding: dati random di riempimento che il ricevente dovrà ignorare. Secondo le specifiche, il mittente dovrà inviare un padding di
almeno 16 byte.
18. 18
Struttura SSL3_RECORD
Un Heartbeat Message è inviato tramite un SSL3_RECORD strutturato
in questo modo:
length: lunghezza dell'HeartbeatMessage
data: un puntatore che punta all'HeartbeatMessage
19. 19
IL CODICE INSANGUINATO
Il bug è presente in entrambe le funzioni in OpenSSL:
●
dtls1_process_heartbeat() (ssl/d1_both.c)
●
tls1_process_heartbeat() (ssl/t1_lib.c)
Nella struttura dati rrec.data viene salvata l’HeartbeatMessage. Viene fatto puntare il puntatore p al
primo byte di essa.
●
hbtype è una variabile che conterrà la tipologia del messaggio Heartbeat ricevuto
●
pl è una variabile che punterà al punto di inizio del payload (Heartbeat data)
●
payload è una variabile che conterrà il campo lunghezza dell’Heartbeat Message
●
padding indica quanti byte di padding si stanno usando. Come è possibile osservare, si usa la
quantità minima di padding secondo quanto espresso nell’RFC 6520
20. 20
IL CODICE INSANGUINATO
In hbtype viene messo il primo byte della richiesta, cioè la tipologia di
HeartbeatMessage. A quel punto p viene incrementato di un indirizzo di memoria.
Tramite la macro n2s vengono spostati due byte da p e messi in payload. Questi
byte sono la lunghezza del payload nell’Heartbeat Message.
Nota Importante: la lunghezza nell’SSL Record non viene controllata/verificata.
Essa indicherebbe la reale lunghezza di tutto l’heartbeat Message
La variabile pl punta all’heartbeat data, la quale è stata inviata dal client.
21. 21
IL CODICE INSANGUINATO
Se l’heartbeat Message è una REQUEST:
●
Alloca un buffer di memoria usando la
funzione malloc di OpenSSL.
Quindi, prepara un area di memoria della
dimensione dell’Heartbeat Message
[type, length, payload, padding]
Nota: OpenSSL è multipiattaforma, esso deve funzionare su diversi sistemi operativi.
●
Mentre malloc può allocare porzioni di memoria precedentemente non utilizzate da altri processi
o utilizzate da altri processi e da questi rese libere per il riutilizzo, OPENSSL_malloc riutilizza
memoria pre-allocata dalla libreria stessa (OpenSSL) e mantiene una sua lista delle allocazioni
per far funzionare bene OPENSSL_free (liberare porzioni di memoria).
Lavorando in questo modo, OPENSSL bypassa I meccanismi di ASLR (Address Space Layout
Randomization) messi in atto dal kernel del Sistema Operativo per ridurre certi errori di programmazione.
22. 22
IL CODICE INSANGUINATO
Dopo OPENSSL_malloc, bp punta all’inizio del
buffer appena allocato.
●
Il primo byte di questo buffer riceverà il byte
relativo alla tipologia, che stavolta indica una
RESPONSE poichè stiamo costruendo il
pacchetto di risposta.
●
bp dopo l’assegnazione viene incrementato
di un indirizzo.
●
Tramite la macro s2n vengono copiati i due
byte da payload in bp
●
Senza alcun precedente controllo, a questo punto, la funzione memcpy() copierà
un “numero payload di byte” da pl a bp.
Non essendoci nessun controllo sulla lunghezza del payload e avendo implementato in quel
modo malloc, il payload nel messaggio di risposta conterrà dati sensibili trattati ultimamente
da OpenSSL.
24. 24
FIX CODE
Il fix consiste nell’aggiungere dei controlli
mancanti alla dimensione del buffer.
Senza di essi l’attaccante poteva:
●
Inviare una richiesta con “stringa payload”
vuota ma lunghezza del payload fino a
64KB (2 byte completamente impostati)
●
Inviare una richiesta in cui la lunghezza del
payload non corrisponde effettivamente al
payload trasportato (che sarà inferiore).
Primo if: controlla che il payload inviato non sia nullo. In questo modo si evita che il client
invii un payload nullo con lunghezza significativa.
Secondo if: risolve il problema di avere una lunghezza payload che non rispecchia
il reale payload trasportato. Questo avviene confrontando in byte la dimensione
dell’area di memoria che si vorrebbe allocare (per il pacchetto di risposta) con la
dimensione del messaggio heartbeat (perchè in rrec viene salvato l’intero heartbeatmessage).
30. 30
DIFESA
●
Individuare che il proprio server sia vulnerabile. {Script,
siti di Vulnerability Assessment per Heartbleed, controllando la
versione di OpenSSL installata nel server}.
●
DEVE ESSERE UN OPERAZIONE ATOMICA!
●
I) Revoca dei certificati e della PK presso la propria CA
●
II) Aggiornamento di OpenSSL alla versione >= 1.0.1g
Perche se revochi soltanto, continui ad avere un versione vulnerabile e
quindi l’attaccante può nuovamente trovare le nuove PK. Se invece
aggiorni ma non revoci, le vecchie PK potevano essere state attaccate
e quindi essere state esposte.
if (OpenSSLVersion < 1.0.1g && OpenSSLVersion>=1.0.1)if (OpenSSLVersion < 1.0.1g && OpenSSLVersion>=1.0.1)
Your Server is Vulnerable! :DYour Server is Vulnerable! :D
31. 31
Problema:
L’attacco non viene salvato nei log di sistema.
Questo vuol dire che non sapremo mai con certezza numerica quanti e quali
server siano stati attaccati e soprattutto quali dati siano stati rubati. Si può
dare soltanto una stima: il 17% (circa mezzo milione) dei server sicuri
certificati e i 2/3 dei web server in Internet (66%). I web Server attaccati
che usavano OpenSSL di default erano Apache e Nginx.
Heartbleed is a catastrophic bug in OpenSSL (...)
”Catastrophic” is the right word. On the scale of 1 to 10, this is an 11. (…)
Bruce Schneier