Heartbleed

by heartbleed.comHeartbleed è il nome di una vulnerabilità molto seria scoperta sulla libreria OpenSSL dalla versione 1.0.1 alla 1.0.1f incluse.

OpenSSL è utilizzata per il traffico https da molti software, tra cui Apache e nginx che da soli costituiscono il 66% dei server web, anche se bisogna rilevare che non tutti i server web hanno https abilitato.

Microsoft Internet Information Server non è interessato da questo problema.

I prodotti Apple non sono interessati dal problema, con l’eccezione dell’AirPort per cui è disponibile un aggiornamento.

Tutto è cominciato nel 2012 con la release di OpenSSL 1.0.1 che introduce il supporto di RFC6520 e implementa l’heartbeat sulle connessioni TLS. Questa funzione serve a mantenere il canale aperto e impedire, quindi, che client e server debbano rinegoziare la connessione in caso di temporanea inattività. L’espediente dell’heartbeat o keep-alive è utilizzato in molti contesti in cui si invia un pacchetto dati senza informazioni con il solo scopo di resettare eventuali contatori di inattività.

Il problema di OpenSSL è che una riposta al’heartbeat modificata ad arte può rivelare all’attaccante informazioni di vario tipo. Non è possibile utilizzare questa vulnerabilità per eseguire codice sul server remoto, ma questo non è certo un fattore mitigante, vediamo perché.

RFC6520 prescrive che il pacchetto di heartbeat sia al massimo di 16k (214 byte), ma OpenSSL genera pacchetti molto più piccoli.

Il protocollo prevede che il client invii un pacchetto di heartbeat e il server risponda copiando quello che ha ricevuto dal client nella risposta in modo tale che il client riconosca come legittima la risposta. Il pacchetto di heartbeat di OpenSSL ha questo formato:

  • 0x01 costante che denota TLS1_HB_REQUEST
  • due byte con la dimensione del pacchetto codificata a 16 bit
  • due byte codificati a 16 bit con il numero di sequenza del pacchetto
  • 16 byte di dati casuali
  • altri 16 byte di dati casuali richiesti dallo standard RFC6250

Nella risposta il server copia i dati ricevuti e li rispedisce al client usando questo codice:

/* Allocate memory for the response, size is 1 byte
 * message type, plus 2 bytes payload length, plus
 * payload, plus padding
 */
buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
/* Enter response type, length and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);

Nel codice sopra payload è la dimensione del pacchetto dichiarata dal mittente (non calcolata dal server). Se il mittente anziché dichiarare la vera dimensione del pacchetto mettesse 0xffff (il numero massimo esprimibile con due byte senza segno) il destinatario copierebbe i 34 byte del pacchetto vero e gli altri 65501 byte che si trovano in memoria dopo il pacchetto legittimo e li invierebbe al mittente.

Non è possibile stabilire in maniera deterministica cosa contengono quei 65501 byte, verosimilmente sono dati utilizzati da OpenSSL. Alcuni test hanno rivelato che in risposta OpenSSL può fornire molti dati sensibili, tra cui anche la chiave privata che il server utilizza per cifrare le comunicazioni.

Molti siti commerciali presentano questo baco pericoloso e i tecnici sono (si spera) al lavoro per aggiornare le librerie OpenSSL.

Il baco è stato scoperto da Neel Mehta di Google Security, molti enti hanno emesso delle note in merito (CERT FI e US-CERT) ed è anche disponibile un sito dedicato.

Aggiornamento: Con questo script Python è possibile verificare se un sito è vulnerabile. Consiglio caldamente di usare script sui propri computer anziché servizi online per evitare di rivelare a terzi l’esistenza di siti vulnerabili.

L’autore della modifica rovinosa è Robin Seggelmann e questo è il checkin del codice bacato.

Elric: As I look at you, Ambassador Mollari, I see a great hand reaching out of the stars. The hand is your hand. And I hear sounds – the sounds of billions of people calling your name.

Londo: My followers?

Elric: Your victims.

(Babylon 5, The Geometry of Shadows)


Articolo modificato dopo la pubblicazione iniziale:

Autore: Luigi Rosa

Consulente IT, sviluppatore, SysAdmin, cazzaro, e, ovviamente, geek.

22 pensieri riguardo “Heartbleed”

    1. Il problema non sono i sistemi che si possono aggiornare, ma quelli non aggiornabili, come (a puro titolo di esempio) quelli integrati che usano librerie OpenSSL

  1. Usa OpnSSL e come in tutte le installazioni di OpenSSL la versione la ottieni scrivendo
    openssl version
    dalla command line se entri in ssh con le credenziali di admin (o equivalente)

    Ho appena provato da un cliente e la versione riportata e’ “OpenSSL 1.0.1e 11 Feb 2013”, ma non ho nessun QNAP esposto a Internet.

    1. Si ho provato con “openssl version”, e mi dava un errore.
      Ho appena terminato di aggiornare il firmware (avevo la 4.0.2 ora la 4.0.5) e ora mi da questa versione:

      OpenSSL 1.0.1e 11 Feb 2013

      Quindi sono vulnerabile…
      Spero che rilascino presto una patch…

        1. Il fatto che tu debba suggerire di *disabilitare* https e` la dimostrazione di quanto sia grave questo bug 🙁 🙁 🙁

  2. Mi spiegate una cosa? A cosa diavolo serve rimandare indietro un payload tale e quale, anche lunghetto, in un pacchetto il cui scopo principale (unico?) è quello di tenere aperta la sessione?
    Se proprio fosse indispensabile metterei un progressivo, anche a 64 bit, ma perché andare oltre in un protocollo così importante?

    1. Il progressivo c’e’ gia’, rimandare indietro il payload serve a scopo di test per vedere che effettivamente e’ il pacchetto che hai inviato tu. Anche l’utility PING funziona cosi’. Probabilmente un pacchetto grande a piacere serve anche per evitare di prestare il fianco ad una decodifica per forza bruta: se sai (o immagini) il contenuto e’ piu’ facile attaccare un testo cifrato.
      Se il “pong” avesse risposto solo con il progressivo probabilmente saremmo qui a discutere di una vulnerabilita’ causata da un pacchetto troppo facile da decodificare 😉

Spazio per un commento