Nuova vulnerabilità denial-of-service nel protocollo TLS, basata sull'abbassare le sessioni degli altri utenti?

22

Penso di avere un nuovo attacco denial-of-service su TLS e vorrei che verificassi se si tratta di una vera vulnerabilità.

Recentemente ho appreso il modo corretto di abbandonare una sessione client autenticata (vedi questa domanda ). In base a RFC 5246 & RFC 5077 questo viene fatto inviando un avviso fatale. Ma non viene detto nulla sulla reale necessità di una ripresa completa della sessione per tale dropping o meno, il che significa che in realtà qualsiasi client può eliminare sessioni autenticate di qualsiasi altro client, conoscendo solo il sessionID.

I passaggi sono:

  • connettersi al server e inviare client_hello con ID sessione di destinazione
  • attendi la risposta del server, che includerà server_hello, change_cipher_spec & finito
  • invia un avviso fatale NON CONCENTRATO con qualsiasi valore

RFC 5246 dice ( §7.2.2 ):

Upon transmission or receipt of a fatal alert message, both parties immediately close the connection. Servers and clients MUST forget any session-identifiers, keys, and secrets associated with a failed connection. Thus, any connection terminated with a fatal alert MUST NOT be resumed.

Funziona perfettamente con qualsiasi connessione & stato di cifratura, incluso NULL.

Ho appena controllato l'effettiva implementazione di OpenSSL. La vulnerabilità (se si tratta di una vulnerabilità) è presente. Cosa direbbe la comunità? Devo spingere questo problema come vera vulnerabilità o è proprio come dovrebbe essere e niente di cui preoccuparsi?

    
posta Trueblacker 03.09.2015 - 11:52
fonte

3 risposte

37

Per riassumere:

  • Potrebbe funzionare, o meno, a seconda di come il server gestisce la cache per i parametri di sessione.
  • Le RFC non sono coerenti.
  • Non è una vulnerabilità "reale".

Le sessioni TLS erano inizialmente pensate come un'ottimizzazione, per evitare che client e server eseguissero l'intera stretta di mano con la sua "pesante crittografia asimmetrica" per ogni connessione (il costo effettivo di tale crittografia è spesso sopravvalutato ma non è questo il punto). I client e i server esistenti e distribuiti tendono a ricordare le sessioni per un po 'di tempo, quindi le dimenticano quando diventa problematico continuare a ricordare (in genere, sul lato server, quando il buffer RAM dedicato a tale spazio di archiviazione è pieno, le vecchie sessioni vengono sfrattate). L'idea è che il client e il server possano ancora fare una stretta di mano completa, in modo trasparente, quando necessario; la ripresa della sessione è opportunistica.

Alcuni sistemi distribuiti si basano sulla ripresa della sessione per funzionare in modo un po 'più affidabile; in particolare, applicazioni basate sul Web con autenticazione client con smart card: l'uso della smart card implica la firma con la carta, che ha un piccolo costo computazionale (diciamo 1 secondo) e un costo utente elevato (l'utente umano potrebbe dover digita un codice PIN). Tuttavia, anche in questi casi, è chiaro che i parametri di sessione sono memorizzati solo nella RAM, quindi se il browser client viene chiuso e quindi riaperto, non verrà ripresa alcuna sessione e verrà eseguito un handshake completo.

RFC 5246 , in sezione 7.2.2 , contiene questo paragrafo:

Error handling in the TLS Handshake protocol is very simple. When an error is detected, the detecting party sends a message to the other party. Upon transmission or receipt of a fatal alert message, both parties immediately close the connection. Servers and clients MUST forget any session-identifiers, keys, and secrets associated with a failed connection. Thus, any connection terminated with a fatal alert MUST NOT be resumed.

Questa è una dichiarazione generica intesa, in modo informale, a dissuadere alcuni attacchi di forza bruta ancora non specificati che fanno affidamento sull'attaccante che "prova" molte riprese di sessione. Ci sono alcuni punti illuminanti che devono essere fatti su quella prescrizione:

  1. Storicamente, anche le sessioni dovevano essere "dimenticate" quando una connessione non era chiusa correttamente (con un esplicito close_notify ). Tuttavia, i server Web esistenti interrompono bruscamente la connessione, quindi i browser Web si sono adattati mantenendo le sessioni "vere" anche quando sono state terminate in un modo in cui TLS-1.0 avrebbe disapprovato.

  2. Questa nozione di dimenticare la sessione su un avviso fatale non funziona sul server quando vengono utilizzati ticket di sessione , dal momento che , per definizione, un server con ticket di sessione non gestisce la propria memoria. A tale riguardo, RFC 5077 e RFC 5246 non sono coerenti: questo "NON DEVE essere ripreso" non può essere applicato da un server che utilizza ticket di sessione.

    Accade così che la maggior parte delle implementazioni SSL siano riluttanti a violare le leggi della fisica per conformarsi a RFC.

  3. Anche senza inviare un avviso, una "condizione fatale" può sempre essere forzata da un utente malintenzionato: è sufficiente che l'attaccante apra una connessione da solo, riutilizzando lo stesso ID sessione come una connessione utilizzata dal client originale. Il server proverà a riprendere la sessione ( ServerHello , ChangeCipherSpec , Finished ) quindi aspettarsi il ChangeCipherSpec e Finished dal client. Poiché il client è l'autore dell'attacco e l'autore dell'attacco non conosce la chiave principale per la sessione che intende riprendere, il suo messaggio Finished non verrà decrittografato correttamente, provocando un bad_record_mac dal server. Se la sezione 7.2.2 deve essere seguita, il server dovrebbe quindi dimenticare la sessione.

    Si sottolinea che l'attacco "kill the session by failed Finished " espresso nel paragrafo precedente può essere più facile da estrarre rispetto a quello che stai descrivendo, poiché coinvolge solo osservando una connessione autentica (per ottenere l'ID di sessione), non che modifica quella connessione.

Il terzo punto sopra è importante perché mostra che fino a quando non ha ricevuto un messaggio Finished correttamente crittografato e MAC dal client, il server non ha alcuna prova che stia davvero parlando con il vero client. Probabilmente, la sessione non viene "ripresa" fino a quel momento, e quindi non dovrebbe essere "invalidata" per qualsiasi condizione errata che si verifichi prima di quel punto (sia un avviso esplicito dal client, o un errore MAC, o qualsiasi altra cosa). Tuttavia, anche l'RFC non è chiaro su questo, quindi ciò che realmente accade dipende in realtà da come il server gestisce la sua cache, ai capricci del server implementor.

La vulnerabilità non è "reale" in quanto qualsiasi attaccante che è in grado di trafficare con le connessioni client può già fare molto più danno, ad esempio rispondendo al messaggio ClientHello del client con un messaggio sintetico di allerta o semplicemente spazzatura casuale che convincerà il cliente che non c'è un server SSL / TLS funzionante dall'altra parte - un denial-of-service molto più completo del semplice fatto che server e client passano un paio di millisecondi di CPU per un intero handshake.

    
risposta data 03.09.2015 - 14:57
fonte
12

Se hai verificato empiricamente che funziona come proposto *, dovresti notificare al team di sicurezza di OpenSSL .

L'impatto di questo bug potrebbe essere sullo spettro Denial-of-Service; in pratica, è possibile forzare una coppia client / server ad eseguire ogni volta trattative complete, il che richiede più risorse del server (... che è il motivo per cui la ripresa esiste in primo luogo). E, sulla scala di disponibilità, questo probabilmente non è enorme: riduce semplicemente le prestazioni al livello base previsto quando non viene utilizzata la ripresa, che è lo scenario peggiore accettato **.

Al momento non vedo una minaccia per Confidenzialità o Integrità (anche se la storia è piena di esempi di problemi minori X e problemi minori Y che combinano per rendere il problema principale Z).

Come descritto finora, questo potrebbe essere un problema di implementazione o potrebbe essere un problema di protocollo. Come dici tu, "non viene detto nulla [nelle RFC] in merito alla reale necessità di una ripresa completa della sessione per tale dropping o meno". Quindi varie implementazioni SSL potrebbero gestire questo caso in modo diverso. Dato che stai già guardando OpenSSL, continuerei su quelle righe e, quando hai codice di proof-of-concept, puoi testare altre implementazioni SSL per vedere come gestiscono.

Se si rivela un problema di protocollo più ampio e stai già lavorando con il team di sicurezza di OpenSSL, allora chiederei il loro consiglio su come ampliare l'advisory.

* Ti consiglio di escogitare un *** proof-of-concept prima di intensificarlo. In primo luogo, ti assicurerai di avere effettivamente un problema! In secondo luogo, il problema verrà trattato con maggiore attenzione se si dispone di un codice di exploit per consentire loro di riprodurre il problema. Non è chiaro cosa intendi per "Ho appena controllato l'effettiva implementazione di OpenSSL", quindi suppongo che tu abbia appena fatto una revisione del codice in questo momento.

** La gravità di questo bug è piuttosto bassa; forse "degrado del servizio" sarebbe un termine migliore di "rifiuto del servizio". Per questo motivo, non mi preoccuperei di aver divulgato pubblicamente questo problema ... non è abbastanza di impatto da richiedere la segretezza o passare attraverso i cauti passaggi di " divulgazione etica ". (Non per minimizzare il problema, sembra essere un posto affascinante in cui alcune ambiguità nel linguaggio dello standard hanno permesso di insinuarsi in un comportamento indesiderabile.)

*** @Trueblacker ha creato un proof-of-concept e ha aperto un problema per il team di OpenSSL - documentando qui poiché i commenti sono effimeri.

    
risposta data 03.09.2015 - 12:38
fonte
0

No. Non è una vera vulnerabilità. Il divario nel tuo piano di attacco è: come pensi di apprendere l'ID di sessione usato da qualche altro utente?

Gli ID di sessione sono difficili da indovinare, quindi non puoi solo prevedere o indovinare quale ID di sessione verrà utilizzato da un altro utente. Senza conoscere un ID di sessione, non puoi fare l'attacco. Quindi, non è chiaro come un attaccante possa effettivamente effettuare questo attacco nella pratica.

In particolare, un attaccante fuori percorso non può vedere l'ID della sessione e non può indovinarlo, quindi probabilmente non può eseguire questo attacco. Se stai pensando ad un attacco man-in-the-middle o alle intercettazioni, se l'avversario è in grado di farlo, ci sono ben peggiori attacchi alla disponibilità che sono possibili - quindi lo scenario non è molto interessante; un simile attacco sarebbe probabilmente ritenuto insignificante.

    
risposta data 03.09.2015 - 23:21
fonte

Leggi altre domande sui tag