GnuTLS corregge il bug di cattiva gestione della memoria: aggiorna ora!

Nodo di origine: 1603833

La libreria crittografica più conosciuta nel mondo open-source è quasi sicuramente OpenSSL.

Innanzitutto, è uno dei più utilizzati, al punto che la maggior parte degli sviluppatori sulla maggior parte delle piattaforme ne ha sentito parlare anche se non lo ha utilizzato direttamente.

In secondo luogo, è probabilmente il più ampiamente pubblicizzato, purtroppo a causa di un bug piuttosto brutto noto come heartbleed scoperto più di otto anni fa.

Nonostante sia stato corretto tempestivamente (e nonostante soluzioni alternative affidabili esistenti per gli sviluppatori che non potevano o non volevano aggiornare rapidamente le loro versioni vulnerabili di OpenSSL), Heartbleed rimane una sorta di bug "mostra", anche perché è stato uno dei primi bug ad essere trasformato in un aggressivo veicolo di pubbliche relazioni dai suoi scopritori.

Con un nome impressionante, un logo tutto suo e un sito Web dedicato, Heartbleed è diventato rapidamente una sicurezza informatica globale superstoria, e, nel bene e nel male, divenne indissolubilmente legato alle menzioni del nome OpenSSL, come se il pericolo del bug persistesse anche dopo che era stato eliminato dal codice.

La vita oltre OpenSSL

Ma ci sono molte altre librerie crittografiche open source che sono ampiamente utilizzate oltre o al posto di OpenSSL, in particolare tra cui Mozilla's NSS (Corto per Servizi di sicurezza di rete) e del progetto GNU gnuTLS biblioteca.

A quanto pare, GnuTLS ha appena corretto un bug noto come CVE-2022-2509, riportato nel progetto consulenza sulla sicurezza GNUTLS-SA-2022-07-07.

Questa patch risolve un errore di cattiva gestione della memoria noto come a doppio libero.

Spiegazione doppiamente gratuita

In poche parole, viene creata una doppia vulnerabilità quando un programmatore chiede al sistema operativo di allocare un blocco di memoria da utilizzare temporaneamente...

...e lo restituisce in modo che possa essere cancellato dall'elenco dei blocchi prestati per essere liberato per essere utilizzato da altre parti del programma...

...e poi chiede accidentalmente al sistema di liberare di nuovo lo stesso blocco di memoria.

Idealmente, il software di allocazione della memoria rileverà che il blocco non appartiene più alla parte del programma che lo sta "restituendo", scoprirà che il blocco incriminato è già stato riciclato e non lo dealloca una seconda volta, aggirando così i rischi di “liberarlo” di nuovo.

Trattare delicatamente con un double-free rilevato in modo proattivo è un problema complicato. La funzione C che restituisce la memoria è stata prototipata come void free(void *ptr); in modo da passare l'indirizzo di un blocco che vuoi liberare, ma non ottenere un codice di ritorno. (funzione AC con a void il valore restituito è ciò che altri linguaggi di programmazione chiamano a procedure: fa qualcosa per te, ma non ha modo di riportare un risultato.) Quindi anche il codice C scritto con cura non ha un modo standard per rilevare che qualcosa è andato storto in free(), e quindi non c'è modo di gestire l'errore tentando di spegnersi in modo regolare. La cessazione unilaterale del programma incriminato è l'unica soluzione sicura per il sistema.

Ma se l'allocatore di memoria non si rende conto (forse perché quello stesso blocco è stato poi distribuito a un'altra parte dello stesso programma, quindi è tornato nell'elenco dei "prestiti" esattamente nella stessa forma di prima) , allora è probabile che accadano cose brutte.

In particolare, il gestore della memoria potrebbe inavvertitamente e inaspettatamente "sequestrare" il blocco doppiamente liberato dal codice che ora lo sta legittimamente utilizzando e riassegnarlo a un'altra parte del programma, forse anche codice dannoso che un utente malintenzionato ha programmato con attenzione per trarne vantaggio della cattiva gestione.

Quindi, potresti finire con due parti dello stesso programma che manipolano lo stesso blocco di memoria.

Una parte del programma presume di potersi fidare implicitamente del contenuto della memoria, perché si considera il legittimo "proprietario" del blocco.

Allo stesso tempo, un'altra parte del programma sa che può pasticciare con i dati (o può essere indotto con l'inganno a pasticciare con loro) per inciampare deliberatamente nella prima parte.

Fare la cosa sbagliata fa la cosa giusta

Ironia della sorte, il bug CVE-2022-2509 esiste nel codice di verifica del certificato in GnuTLS.

(L'ironia, nel caso te lo stia chiedendo, è che il software che non è sicuro in generale perché non si preoccupa di controllare connessioni TLS affidabili è immune da questo specifico bug di sicurezza.)

Ad esempio, quando visiti un sito Web (o un altro tipo di server) protetto con TLS, l'altra estremità in genere ti invierà un certificato Web che afferma che il server è effettivamente di proprietà e gestito dall'organizzazione che ti aspetti.

Ovviamente, dato che chiunque può creare un certificato con il nome che preferisce, un certificato non elaborato da solo non ti dice molto, quindi il proprietario del certificato di solito lo fa firmare digitalmente da un'azienda di cui il tuo browser si fida già.

In pratica, i certificati sono solitamente firmati da un certificato che è, a sua volta, firmato da un certificato considerato attendibile dal tuo browser, ma il risultato finale è quello che viene chiamato un catena di fiducia che può essere ricondotto in modo sicuro a un certificato già installato in un elenco di cosiddetti Autorità fidate, conosciuto anche come Roots, che è gestito dal tuo browser o dal tuo sistema operativo.

Per semplificare e accelerare il processo di convalida della catena di certificati, molti server non inviano semplicemente il proprio certificato e lo lasciano al browser per "inseguire la catena" a una radice affidabile.

Il server in genere include la catena di fiducia su cui si basa, che deve costruire solo una volta, in modo che il tuo browser, o qualsiasi altro software stia verificando il certificato, possa semplicemente verificare che la catena sia valida digitalmente e quindi verificare che l'ultimo certificato nella catena corrisponde a uno che è già attendibile.

In tal caso, GnuTLS convaliderà correttamente e in sicurezza il certificato fornito, prima di liberare il blocco di memoria appena utilizzato per archiviarlo.

Ma se l'altra estremità non fornisce una catena di certificati pregenerata, lasciando così GnuTLS a creare e controllare la catena da solo, il codice GnuTLS libera accidentalmente la memoria utilizzata per memorizzare il certificato fornito prima di avviare la catena- processo di verifica...

…e poi lo libera di nuovo al termine del controllo.

Ciò provoca un doppio incidente, che potrebbe portare a un danneggiamento della memoria, seguito da un arresto anomalo del programma.

Gestire un crash per impiantare malware

Di solito, o almeno spesso, gli arresti anomali causano un comportamento così ribelle che il sistema operativo rileva che il programma incriminato ha perso il controllo del flusso di esecuzione del programma, ad esempio se il programma salta a un indirizzo di memoria casuale e tenta di eseguire codice da un blocco di memoria che non è stato affatto allocato.

In questo caso, il crash provocherebbe un errore di sistema, e sebbene questo tipo di bug possa essere abusato per quello che viene chiamato un Denial of Service (DoS), in cui l'intero obiettivo è semplicemente quello di interrompere il programma che viene attaccato, non porta a Esecuzione di codice in modalità remota (RCE), dove invece viene attivato il codice software non attendibile e indesiderato.

Ma ogni volta che si verifica un arresto anomalo del programma che gli aggressori possono provocare a piacimento, sulla base di dati non attendibili che hanno fornito loro stessi, c'è sempre il rischio che l'arresto anomalo possa essere guidato in modo tale da indirizzare erroneamente il programma in crash in modo che salti nel codice eseguibile fornito dagli aggressori.

Come puoi immaginare, gli aggressori possono spesso sfruttare tali vulnerabilità per impiantare malware, temporaneamente o permanentemente, dato che riescono a iniettare codice non attendibile nel tuo computer senza produrre avvisi popup che richiedono prima l'autorizzazione.

Cosa fare?

Aggiorna al ultima versione di GnuTLS, che è 3.7.7 al momento della scrittura.

(Apparentemente questo bug è stato introdotto in GnuTLS 3.6.0 ed esiste in ogni versione da allora, fino alla 3.7.6 inclusa.)

Nota che molte applicazioni popolari e toolkit di programmazione includono o possono essere creati per utilizzare GnuTLS, anche se potresti non esserne a conoscenza, inclusi ma non limitati a: FFmpeg, GnuPG, Mplayer, QEMU, Rdesktop, Samba, Wget, Wireshark e Zlib.

Molti pacchetti Linux o *BSD che utilizzano GnuTLS si basano su una versione centrale gestita dalla tua distribuzione stessa, quindi assicurati di aggiornare non appena la tua distribuzione ha questa versione disponibile.

Buona rappezzatura!


Timestamp:

Di più da Sicurezza nuda