Exploatarea referințelor nule în nucleul Linux
Recent s-a anunțat că cercetătorii din echipa Google Project Zero au dezvoltat o metodă de exploatare a vulnerabilităților din kernelul Linux cauzate de dereferențierea pointerului NULL.
Până în prezent, problemele kernelului legate de dereferențierea pointerilor NULL nu au primit atenția cuvenită , deoarece se considera nerealist să se transforme astfel de probleme în atacuri care să ducă la escaladarea privilegiilor sau la executarea propriului cod (maparea proceselor neprivilegiate în regiunea inferioară a spațiului de adrese este interzisă).
Ca regulă generală, astfel de erori duc la generarea de avertismente oops de către kernel, după care sarcinile problematice sunt finalizate și starea este restabilită fără a fi nevoie să opriți sistemul.
Noua metodă de atac se bazează pe gestionarea stărilor „oops” , care pot duce la o creștere a valorii contorului de referință (refcount), ceea ce, la rândul său, poate provoca depășirea valorii contorului și eliberarea memoriei asociate cu refcount-ul.
În acest caz, exploatarea se reduce la manipulări tipice atacurilor use-after-free (apare o situație în care numărul de referință al obiectului devine zero, memoria este eliberată, dar de fapt există legături de lucru care indică către memoria eliberată).
În prezent, când kernelul Linux declanșează o dereferențiere nulă din cadrul unui context de proces, acesta generează un oops , care este distinct de o panică de kernel. O panică apare atunci când kernelul stabilește că nu există o modalitate sigură de a continua execuția și, prin urmare, trebuie să înceteze toată execuția. Cu toate acestea, kernelul nu oprește toată execuția în timpul unui oops; în schimb, kernelul încearcă să se recupereze cât mai bine posibil și continuă execuția.
Dereferentarea unui pointer NULL este folosită aici ca o modalitate de a genera starea „oops” într-o manieră controlată. Problema este că este nevoie de aproximativ 232 de apeluri de stare „oops” pentru a ajunge la o depășire de refcount pe 32 de biți.
Din punct de vedere practic, este nevoie de aproximativ opt zile de generare continuă de stări out-of-place (OOP) pentru a efectua un atac folosind exploit-ul propus. Dacă are succes, exploit-ul vă permite să executați codul la nivel de kernel.
Dereferința pointerului NULL folosită în exploit a fost remediată în octombrie, dar din moment ce probleme similare nu sunt neobișnuite și au fost tratate anterior ca erori, nu vulnerabilități, dezvoltatorii vor adăuga protecție generală la kernel-ul Linux pentru a preveni atacurile care manipulează generarea „oops”. ."
În cazul unei sarcini, asta înseamnă să renunți la stiva existentă de kernel și să mergi direct la make_task_dead care apelează do_exit. Nucleul va posta, de asemenea, pe dmesg un jurnal de „crash” și o urmărire a nucleului care arată în ce stare se afla nucleul când a apărut eroarea. Aceasta poate părea o alegere ciudată atunci când coruperea memoriei a avut loc în mod clar; totuși, intenția este de a face erorile de kernel mai ușor de detectat și de logat, conform filozofiei că un sistem care rulează este mult mai ușor de depanat decât unul nefuncțional.
În special , Kernel 6.2 include modificări pentru a limita numărul maxim de „oops” . După atingerea limitei, care este setată implicit la 10 de oops (puteți modifica această valoare folosind parametrul oops_limit, dacă doriți), kernelul va iniția o tranziție către o stare de „panică”, urmată de o repornire, care nu va permite numărul de iterații necesar pentru a reseta refcount la zero.
De asemenea, este planificat ca restricția să fie transferată în ramurile nucleului lansate anterior, dar încă acceptate, precum și în pachetele de nucleu ale distribuțiilor populare.
În cele din urmă, dacă sunteți interesați să aflați mai multe despre acest subiect , puteți găsi detalii la linkul următor.