Chrome zero-day: „Acest exploit este în sălbăticie”, așa că verificați-vă versiunea acum

Chrome zero-day: „Acest exploit este în sălbăticie”, așa că verificați-vă versiunea acum

Nodul sursă: 2704382

Cea mai recentă actualizare Chrome de la Google a apărut și de data aceasta compania nu și-a tocat cuvintele despre unul dintre cele două corecții de securitate pe care le include:

Google este conștient de faptul că un exploit pentru CVE-2023-3079 există în sălbăticie.

Nu există verbiaj de două grade de separare, așa cum am văzut adesea de la Google înainte, pentru a spune că compania „este conștientă de rapoarte” despre un exploit.

De data aceasta, este „suntem conștienți de toate singuri”, ceea ce se traduce și mai direct prin „știm că escrocii abuzează de asta în timp ce vorbim”, având în vedere că raportul de eroare a venit direct de la propriul grup de cercetare a amenințărilor Google.

Ca de obicei, acest lucru implică faptul că Google investiga un atac activ (fie împotriva lui însuși Google sau a unei organizații externe, nu știm) în care Chrome fusese provocat de o gaură de securitate necunoscută anterior.

Bug-ul este descris simplu ca: Tastați Confuzie în V8. (De înțeles, Google nu spune mai mult decât atât în ​​acest stadiu.)

După cum am explicat mai înainte, a confuzie de tip eroarea se întâmplă atunci când furnizați unui program o bucată de date pe care ar trebui să le analizeze, să valideze, să proceseze și să acționeze într-un singur fel...

… dar mai târziu reușiți să păcăliți programul să interpreteze datele într-un mod diferit, neautorizat, nevalidat și potențial periculos.

Pericolele de confuzie de tip explicate

Imaginați-vă că scrieți un program în C. (Nu contează dacă cunoașteți C sau nu, puteți să urmați oricum.)

În C, de obicei declari variabilele individual, astfel nu doar rezervând memoria unde pot fi stocate, ci și semnalând programului cum ar trebui să fie utilizate acele variabile.

De exemplu:

 long long int JulianDayNumber; caracter semnat* CustomerName;

Prima declarație de variabilă rezervă 64 de biți pentru stocarea unei valori întregi vechi simple reprezentând numărul zilei astromonomice. (În cazul în care vă întrebați, această după-amiază este JDN 23157 – Zilele Iuliene încep la prânz, nu la miezul nopții, deoarece astronomii lucrează adesea noaptea, miezul nopții fiind mijlocul zilei lor de lucru.)

Al doilea rezervă 64 de biți pentru stocarea unei adrese de memorie unde poate fi găsit șirul de text al numelui unui client.

După cum vă puteți imagina, ar fi bine să nu amestecați aceste două valori, deoarece un număr care are sens și este sigur de utilizat ca număr de zi, cum ar fi 23157, ar fi aproape sigur nesigur de utilizat ca adresă de memorie.

După cum puteți vedea din această descărcare de memorie a unui program Windows care rulează, cea mai mică adresă de memorie care este alocată pentru utilizare începe la 0x00370000, care este 3,604,480 în zecimală, mult mai mare decât orice număr sensibil al zilei.

Adresele de memorie reale utilizate de Windows variază aleatoriu de-a lungul timpului, pentru a face aspectul memoriei mai greu de ghicit pentru escrocii, așa că dacă ar fi să rulați același program, ați obține valori, dar acestea vor fi totuși similare:

Și (deși se află în partea de jos a imaginii de mai sus) adresele de memorie ale secțiunii de date ale utilizatorului de rulare atunci când acest program rula din 0x01130000 la 0x01134FFF, reprezentând intervalul de date improbabil de la 22 iulie 44631 la 16 august 44687.

Într-adevăr, dacă încercați să amestecați aceste două variabile, compilatorul ar trebui să încerce să vă avertizeze, de exemplu, astfel:

 JulianDayNumber = CustomerName; CustomerName = JulianDayNumber; avertisment: atribuirea face un număr întreg din indicator fără o transformare avertisment: atribuirea face indicatorul dintr-un întreg fără o transformare

Acum, dacă ați programat vreodată în C, veți ști că, pentru comoditate, puteți declara variabile cu mai multe interpretări diferite folosind union cuvânt cheie, ca acesta:

 unire { long long int JulianDayNumer; caracter semnat* CustomerName; } date;

Acum puteți referi exact aceeași variabilă în memorie în două moduri diferite.

Dacă scrii data.JulianDayNumber, interpretezi magic datele stocate ca un număr întreg, dar scriind data.CustomerName spune compilatorului că faceți referire la o adresă de memorie, chiar dacă accesați aceleași date stocate.

Ceea ce faci, mai mult sau mai puțin, este să recunoști compilatorului că uneori vei trata datele pe care le ai ca o dată, iar alteori ca o adresă de memorie și că îți asumi responsabilitatea pentru a-ți aminti ce interpretare se aplică în ce moment în cod.

Ați putea decide să aveți o a doua variabilă, cunoscută sub numele de a tag (de obicei un număr întreg) pentru a merge împreună cu dvs union pentru a urmări tipul de date cu care lucrați acum, de exemplu:

 struct { int tag; unire { long long int JulianDayNumer; caracter semnat* CustomerName; } date; } valoare;

S-ar putea să hotărăști asta când value.tag este setat la 0, datele nu sunt încă inițializate pentru utilizare, 1 înseamnă că memorezi o dată, 2 înseamnă că este o adresă de memorie și orice altceva denotă o eroare.

Ei bine, ai face bine să nu lași pe nimeni altcineva să se încurce cu asta value.tag setare, sau programul dvs. ar putea ajunge să se comporte prost în mod dramatic.

Un exemplu mai îngrijorător ar putea fi ceva de genul acesta:

 struct { int tag; // 1 = hash, 2 = function pointers union { unsigned char hash[16]; // fie stochează o structură hash aleatorie { void* openfunc; // sau două void* closefunc validate cu grijă; // pointeri de cod pentru a executa mai târziu } validate; } } valoare;

Acum, supraîncărcăm același bloc de memorie, așa că uneori îl putem folosi pentru a stoca un hash de 16 octeți și, uneori, pentru a stoca doi pointeri de 8 octeți către funcții pe care programul nostru le va apela mai târziu.

În mod clar, când value.tag == 1, am fi bucuroși să lăsăm software-ul nostru să stocheze orice șir de 16 octeți în memoria alocată pentru unire, deoarece hashurile sunt pseudoaleatoare, deci orice colecție de octeți este la fel de probabilă.

Dar cand value.tag == 2, codul nostru ar trebui să fie foarte atent pentru a nu permite utilizatorului să furnizeze adrese de funcții nevalidate, de încredere și necunoscute pentru a le executa mai târziu.

Acum imaginați-vă că ați putea trimite o valoare acestui cod în timp ce eticheta era setată la 1, așa că nu a fost verificată și validată...

… dar mai târziu, chiar înainte ca programul să folosească efectiv valoarea stocată, ați putut să păcăliți codul să schimbe eticheta la 2.

Codul ar accepta apoi adresele tale nevalidate ca fiind „cunoscute și deja verificate sigure” (chiar dacă nu au fost) și ar trimite cu încredere execuția programului într-o locație necinstită din memorie pe care ai ales-o pe furiș în avans.

Și asta se întâmplă într-o eroare de tip confuzie, deși folosind un exemplu artificial și simplificat,

Memoria care ar putea fi consumată în siguranță dacă ar fi gestionată într-un singur mod este livrată în mod rău intenționat programului pentru a fi procesată într-un mod alternativ, nesigur.

Ce să fac?

Asigurați-vă că aveți cea mai recentă versiune de Chrome sau Chromium.

Vrei Chrome 114.0.5735.106 sau mai târziu pe Mac și Linux și 114.0.5735.110 sau mai târziu pe Windows.

Microsoft Edge, care se bazează pe Chromium, este, de asemenea, afectat de această eroare.

Microsoft a avut până acum [2023-06-06T16:25:00Z] am notat

Microsoft este conștient de exploatările recente existente în sălbăticie. Lucrăm activ la lansarea unui patch de securitate.

Edge este în prezent la versiunea 114.0.1823.37, deci orice este numerotat mai târziu de atât ar trebui să includă corecțiile Microsoft CVE-2023-3079.

Pentru a vă verifica versiunea și a forța o actualizare dacă există una pe care nu ați primit-o încă:

  • Google Chrome. Meniu cu trei puncte (⋮) > Ajutor > Despre Chrome.
  • Microsoft Edge. Setări și multe altele (...) > Ajutor și feedback > Despre Microsoft Edge.

Cu plăcere.


Timestamp-ul:

Mai mult de la Securitate goală