Compania Qualys a identificat două vulnerabilități în instrumentele apport (CVE-2025-5054) și systemd-coredump (CVE-2025-4598), utilizate pentru procesarea fișierelor core generate în urma finalizării premature a proceselor. Vulnerabilitățile permit accesul la fișierele core salvate după finalizarea prematură a aplicațiilor suid sau a unor procese de fond din sistem, în memoria cărora pot fi stocate acreditive cache sau chei de criptare. Utilitarul apport este apelat automat pentru a salva dump-urile core în Ubuntu, iar systemd-coredump în Red Hat Enterprise Linux 9+, Fedora și multe alte distribuții Linux.
A fost demonstrată o tehnică de atac, în cadrul căreia au fost create condiții pentru finalizarea prematură a aplicației suid unix_chkpwd și obținerea accesului la fișierul core cu dump-ul stării în timpul crizei. În dump-ul core salvat au fost prezente hash-urile parolelor utilizatorilor sistemului, care au rămas în memoria procesului finalizat prematur după încărcarea conținutului /etc/shadow. Posibilitatea exploatării vulnerabilităților a fost demonstrată în Ubuntu 24.04 și Fedora 40/41, dar se presupune că și alte distribuții sunt expuse la atacuri similare.
Ambele vulnerabilități sunt cauzate de starea de competiție, care permite înlocuirea procesului suid finalizat prematur cu un alt proces în momentul de după începerea procesării de către nucleu a finalizării premature, dar înainte de verificarea parametrilor procesului de către handler în spațiul utilizatorului prin /proc/pid/files. Apelul pentru apport și systemd-coredump se face astfel: nucleul, primind informațiile despre finalizarea premature a procesului, apelează handler-ul specificat în fișierul /proc/sys/kernel/core_pattern, după care îi transmite conținutul dump-ului core prin fluxul de intrare.
Generarea dump-ului core și apelarea handler-ului nu se întâmplă instantaneu, iar acest timp este suficient pentru a înlocui procesul suid finalizat cu un proces obişnuit de utilizator. În cazul în care înlocuirea are loc, handler-ul de dump-uri core lansat va considera că eșecul a avut loc nu în procesul suid, ci în aplicația obișnuită a utilizatorului și, prin urmare, va salva fișierul core cu posibilitate de acces pentru utilizatorul obișnuit, și nu doar pentru administrator.
Atacul asupra apport constă în următorii pași:
- Un nou proces este derivat și funcția execve() este apelată pentru a lansa un program suid, cum ar fi unix_chkpwd.
- Se saltă timpul necesar pentru ca programul suid să încarce datele confidențiale în memorie (în cazul unix_chkpwd, se așteaptă încărcarea hash-urilor parolelor tuturor utilizatorilor din sistem din fișierul /etc/shadow).
- Înainte de finalizarea comenzii, procesului i se trimite un semnal SIGSEGV sau SIGSYS pentru a se închide în mod forțat.
- Ca răspuns la închiderea forțată, nucleul generează un core dump și lansează procesul apport pentru a gestiona core dump-ul în utilizator.
- După ce aport este lansat, dar înainte de a începe să analizeze, procesului care a eșuat i se trimite un semnal SIGKILL, iar procesul în sine este înlocuit cu altul fără banderola suid. Pentru a evita verificările în apport, noul proces este creat în spații de nume separate (user, pid și mount namespace).
- apport se conectează la unix socket-ul /run/apport.socket în spațiul de nume al punctelor de montare creat pentru noul proces și trimite un descriptor de fișier pentru accesul la core dump.
Pentru a obține pentru noul proces identificatorul necesar, care corespunde identificatorului procesului suid, înainte de a trimite semnalul SIGSEGV, procesul suid este oprit cu semnalul SIGSTOP și în timpul opririi sunt lansate în mod ciclic noi procese, până când se obține un PID cu un număr precedent, apropiat de procesul suid. După ajustarea numerotării PID, semnalele SIGSEGV și SIGCONT sunt trimise procesului suid, după care se trimite SIGKILL și se lansează în mod ciclic noi procese pentru a atinge același PID ca și cel al procesului suid.
În ceea ce privește systemd-coredump, dintr-o parte atacul este mai simplu, deoarece nu este necesară înlocuirea procesului suid cu un proces într-un spațiu de utilizator separat și este suficient să se obțină o potrivire între AT_UID și AT_EUID. Pe de altă parte, systemd-coredump este scris în limbajul C și se lansează destul de repede, ceea ce oferă mai puțin timp pentru înlocuire, spre deosebire de apport, care este scris în Python și în timpul inițializării încarcă diverse fișiere pyc. Această problemă este rezolvată prin întârzierea artificială a systemd-coredump - atunci când se apelează fișierul suid, se transmit un număr foarte mare de argumente pentru linia de comandă, ceea ce creează întârzierea necesară care apare în timpul analizei /proc/pid/cmdline.
În procesul de analiză a vulnerabilităților, cercetătorii au descoperit că systemd-coredump nu specifică flagul „%d” în /proc/sys/kernel/core_pattern când este configurat pentru apeluri, ceea ce îi permite atacatorului să provoace închiderea neașteptată a proceselor de fundal care rulează cu privilegii root și care inițiază alte procese, schimbând identificatorul utilizatorului la un utilizator neprivilegiat sub care se desfășoară atacul. Această capacitate permite atacuri nu doar asupra aplicațiilor setuid, ci și asupra unor procese precum sesiunea sshd (OpenSSH), sd-pam (systemd) și cron, pentru a obține date confidențiale păstrate în memoria acestora, cum ar fi chei private, hash-uri de parole din /etc/shadow, marcaje de canar din stivă și date pentru ocolirea randomizării spațiului de adresare (ASLR).
Urmărirea publicării actualizărilor de pachete în distribuții poate fi efectuată pe paginile: Debian, Ubuntu, RHEL, openSUSE, Fedora, Gentoo, Arch. Ca soluție temporară pentru blocarea vulnerabilităților, se recomandă dezactivarea salvării core-dump-urilor pentru programele suid și a proceselor cu privilegii reduse, setând parametrul /proc/sys/fs/suid_dumpable la valoarea 0. Pentru a rezolva complet problema, sunt necesare modificări în nucleul Linux care implementează posibilitatea de a transmite informații despre un proces închis neașteptat prin mecanismul pidfd (pidfd este legat de procesele specifice și, spre deosebire de pid, nu este reatribuit).
Sursa: opennet.ro
