Seriøs sikkerhed: GnuTLS følger OpenSSL, retter en fejl med timingangreb

Seriøs sikkerhed: GnuTLS følger OpenSSL, retter en fejl med timingangreb

Kildeknude: 1956368

I sidste uge skrev vi om en masse hukommelseshåndteringsfejl der blev rettet i den seneste sikkerhedsopdatering af det populære OpenSSL-krypteringsbibliotek.

Sammen med disse hukommelsesfejl rapporterede vi også om en fejl dubbet CVE-2022-4304: Timing Oracle i RSA-dekryptering.

I denne fejl affyres den samme krypterede besked igen og igen på en server, men modificere udfyldningen i slutningen af ​​dataene for at gøre dataene ugyldige og dermed fremkalde en form for uforudsigelig adfærd...

... ville ikke tage ensartet tid, forudsat at du var tæt på målet på netværket, at du pålideligt kunne gætte, hvor lang tid dataoverførselsdelen af ​​processen ville tage.

Ikke alle data behandles ens

Hvis du affyrer en anmodning, måler, hvor lang tid svaret tager, og trækker den tid, der forbruges ved afsendelse og modtagelse af netværksdata på lavt niveau, ved du, hvor lang tid det tog serveren at udføre sin interne beregning for at behandle anmodningen .

Selvom du ikke er sikker på, hvor meget tid der er brugt i netværket, kan du se efter variationer i tur-retur-tider ved at affyre masser af anmodninger og indsamle masser af prøver.

Hvis netværket er pålideligt nok til at antage, at netværksomkostningerne stort set er konstante, kan du muligvis bruge statistiske metoder til at udlede, hvilken slags datamodifikation der forårsager, hvilken slags ekstra behandlingsforsinkelse.

Ud fra dette kan du mange udlede noget om strukturen, eller endda indholdet, af de originale ukrypterede data, der formodes at blive holdt hemmelige inden for hver gentagne anmodning.

Selvom du kun kan udtrække én byte af klartekst, så er det ikke meningen, at det skal ske.

Såkaldte timing af angreb af denne slags er altid besværlige, selvom du måske skal sende millioner af falske pakker og time dem alle for at have nogen chance for at gendanne blot én byte af almindelig tekst-data...

…fordi netværk er hurtigere, mere forudsigelige og i stand til at håndtere meget mere belastning, end de var for blot et par år siden.

Du tror måske, at millioner af forræderiske pakker spammet til dig i f.eks. den næste time ville skille sig ud som en slags tommelfinger.

Men "en million pakker i timen mere eller mindre end normalt" er simpelthen ikke en særlig stor variation længere.

Lignende "oracle"-fejl i GnuTLS

Nå, den samme person, der rapporterede fejlen med fixet-at-sidst-tidspunktet i OpenSSL, rapporterede også en lignende fejl i GnuTLS nogenlunde samtidig.

Denne har fejlidentifikationen CVE-2023-0361.

Selvom GnuTLS ikke er helt så populær eller udbredt som OpenSSL, har du sandsynligvis en række programmer i dit it-ejendom, eller endda på din egen computer, der bruger det eller inkluderer det, muligvis inklusive FFmpeg, GnuPG, Mplayer, QEMU , Rdesktop, Samba, Wget og Wireshark.

Ironisk nok dukkede timing-fejlen i GnuTLS op i kode, der skulle logge timing-angrebsfejl i første omgang.

Som du kan se af kodeforskellen (diff) nedenfor, var programmøren klar over, at enhver betinget (if ... then)-operation, der bruges til at kontrollere og håndtere en dekrypteringsfejl, kan give tidsvariationer, fordi CPU'er generelt tager forskellig tid afhængigt af, hvilken vej din kode går efter en "gren"-instruktion.

(Det gælder især for en gren, der ofte går den ene vej og sjældent den anden, fordi CPU'er har en tendens til at huske, eller cache, kode, der kører gentagne gange for at forbedre ydeevnen og dermed få den sjældent taget kode til at køre detekterbart langsommere.)

Kodeforskel af gnutls-3.7.8/lib/auth/rsa.c mod 3.7.9

Men programmøren ønskede stadig at logge på, at et angreb kunne ske, hvilket sker, hvis if (ok) test ovenfor mislykkes og forgrener sig i else { ... } sektion.

På dette tidspunkt kalder koden for _gnutls_debug_log() funktion, som kan tage et stykke tid at udføre sit arbejde.

Derfor indsatte koderen et bevidst opkald til _gnutls_no_log() i then { ... } del af koden, som foregiver at logge et "angreb", når der ikke er et, for at forsøge at udjævne den tid, som koden bruger i begge retninger, som if (ok) filial instruktion kan tage.

Tilsyneladende var de to kodestier dog ikke tilstrækkeligt ens i den tid, de brugte (eller måske _gnutls_debug_log() funktion i sig selv ikke var tilstrækkelig konsistent i håndteringen af ​​forskellige slags fejl), og en angriber kunne begynde at skelne dekrypteringsindikatorer efter en million forsøg eller deromkring.

Hvad skal jeg gøre?

Hvis du er programmør: fejlrettelsen her var enkel og fulgte "less is more"-princippet.

Koden i pink ovenfor, som alligevel blev anset for ikke at give forfærdeligt nyttige data om angrebsdetektering, blev simpelthen slettet med den begrundelse, at kode, der ikke er der, ikke kan kompileres ved en fejl, uanset dine byggeindstillinger...

…og kode, der ikke er kompileret i, kan aldrig køre, hverken ved et uheld eller design.

Hvis du er GnuTLS-bruger: den nyligt udgivne version 3.7.9 og den "nye produktsmag" 3.8.0 har denne rettelse, sammen med forskellige andre, inkluderet.

Hvis du kører en Linux-distro, skal du tjekke for opdateringer til enhver centralt administreret delt biblioteksversion af GnuTLS, du har, samt for apps, der medbringer deres egen version.

På Linux skal du søge efter filer med navnet libgnutls*.so at finde eventuelle delte biblioteker liggende og søge efter gnutls-cli for at finde alle kopier af kommandolinjeværktøjet, der ofte er inkluderet i biblioteket.

Du kan køre gnutls-cli -vv for at finde ud af, hvilken version af libgnutls det er dynamisk knyttet til:

 $ gnutls-cli -vv gnutls-cli 3.7.9 <-- min Linux distro fik opdateringen sidste fredag ​​(2023-02-10)

Tidsstempel:

Mere fra Naked Security