Dobësia rrënjësore në kernelin Linux dhe mohimi i shërbimit në systemd

Studiuesit e sigurisë nga Qualys kanë zbuluar detaje të dy dobësive që prekin kernelin Linux dhe menaxherin e sistemit systemd. Një dobësi në kernel (CVE-2021-33909) lejon një përdorues lokal të arrijë ekzekutimin e kodit me të drejta rrënjësore përmes manipulimit të drejtorive shumë të mbivendosur.

Rreziku i cenueshmërisë përkeqësohet nga fakti se studiuesit ishin në gjendje të përgatisnin shfrytëzime pune që funksionojnë në Ubuntu 20.04/20.10/21.04, Debian 11 dhe Fedora 34 në konfigurimin e paracaktuar. Vihet re se shpërndarjet e tjera nuk janë testuar, por teorikisht janë gjithashtu të ndjeshme ndaj problemit dhe mund të sulmohen. Kodi i plotë i shfrytëzimeve premtohet të publikohet pasi problemi të eliminohet kudo, por tani për tani është i disponueshëm vetëm një prototip i funksionalitetit të kufizuar, duke shkaktuar rrëzimin e sistemit. Problemi ka qenë i pranishëm që nga korriku 2014 dhe prek lëshimet e kernelit duke filluar nga 3.16. Rregullimi i cenueshmërisë u koordinua me komunitetin dhe u pranua në kernel më 19 korrik. Shpërndarjet kryesore kanë gjeneruar tashmë përditësime në paketat e tyre të kernelit (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Dobësia shkaktohet nga dështimi për të kontrolluar rezultatin e një konvertimi size_t në int përpara se të kryeni operacione në kodin seq_file, i cili krijon skedarë nga një sekuencë regjistrimesh. Dështimi për të kontrolluar mund të rezultojë në shkrime jashtë kufijve në buffer gjatë krijimit, montimit dhe fshirjes së një strukture direktorie shumë të mbivendosur (madhësia e shtegut më e madhe se 1 GB). Si rezultat, një sulmues mund të arrijë një varg 10-bytesh "//deleted" të shkruar me një zhvendosje prej "-2 GB - 10 bytes" që tregon zonën menjëherë para bufferit të caktuar.

Shfrytëzimi i përgatitur kërkon 5 GB memorie dhe 1 milion inode falas për të funksionuar. Shfrytëzimi funksionon duke thirrur mkdir() për të krijuar një hierarki prej rreth një milion nëndrejtorish për të arritur një madhësi shtegu skedari që tejkalon 1 GB. Kjo direktori montohet nëpërmjet bind-mount në një hapësirë ​​të veçantë emri të përdoruesit, pas së cilës funksioni rmdir() ekzekutohet për ta hequr atë. Paralelisht, krijohet një thread që ngarkon një program të vogël eBPF, i cili bllokohet në fazën pas kontrollit të pseudokodit eBPF, por përpara përpilimit të tij JIT.

Në hapësirën e emrave të paprivilegjuar të përdoruesit, skedari /proc/self/mountinfo hapet dhe lexohet emri i rrugës së gjatë të direktorisë së montuar në bind, duke rezultuar në shkrimin e vargut "//deleted" në zonë përpara fillimit të bufferit. Pozicioni për shkrimin e rreshtit zgjidhet në mënyrë që të mbishkruan udhëzimet në programin eBPF tashmë të testuar, por ende të pa kompiluar.

Më pas, në nivelin e programit eBPF, shkrimi i pakontrolluar jashtë buferit shndërrohet në aftësi të kontrolluar për të lexuar dhe shkruar në strukturat e tjera të kernelit përmes manipulimit të strukturave btf dhe map_push_elem. Si rezultat, shfrytëzimi përcakton vendndodhjen e tamponit modprobe_path[] në kujtesën e kernelit dhe mbishkruan shtegun “/sbin/modprobe” në të, i cili ju lejon të filloni nisjen e çdo skedari të ekzekutueshëm me të drejta rrënjësore në rast të një thirrja request_module(), e cila ekzekutohet, për shembull, kur krijohet foleja netlink.

Studiuesit ofrojnë disa zgjidhje që janë efektive vetëm për një shfrytëzim specifik, por nuk e eliminojnë vetë problemin. Rekomandohet të vendosni "/proc/sys/kernel/unprivileged_userns_clone" në 0 për të çaktivizuar direktoritë e montimit në një hapësirë ​​emri të veçantë të ID-së së përdoruesit dhe "/proc/sys/kernel/unprivileged_bpf_disabled" në 1 për të çaktivizuar ngarkimin e programeve eBPF në kernel.

Vlen të përmendet se gjatë analizimit të një sulmi alternativ që përfshin përdorimin e mekanizmit FUSE në vend të bind-mound për të montuar një drejtori të madhe, studiuesit hasën në një dobësi tjetër (CVE-2021-33910) që prek menaxherin e sistemit systemd. Doli se kur përpiqeni të montoni një drejtori me një madhësi shteg që kalon 8 MB përmes FUSE, procesi i inicializimit të kontrollit (PID1) mbaron memorien e stivës dhe rrëzohet, gjë që e vendos sistemin në një gjendje "paniku".

Problemi është se systemd gjurmon dhe analizon përmbajtjen e /proc/self/mountinfo dhe përpunon çdo pikë montimi në funksionin unit_name_path_escape(), i cili kryen një operacion strdupa() që vendos të dhënat në pirg dhe jo në memorien e alokuar dinamikisht. . Meqenëse madhësia maksimale e stivës është e kufizuar nëpërmjet RLIMIT_STACK, përpunimi i një shteg shumë të madh drejt pikës së montimit shkakton që procesi PID1 të rrëzohet dhe të ndalojë sistemin. Për një sulm, mund të përdorni modulin më të thjeshtë FUSE në kombinim me përdorimin e një drejtorie shumë të mbivendosur si pikë montimi, madhësia e shtegut të së cilës i kalon 8 MB.

Problemi është shfaqur që nga systemd 220 (prill 2015), tashmë është rregulluar në depon kryesore të systemd dhe është rregulluar në shpërndarje (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Veçanërisht, në versionin systemd 248, shfrytëzimi nuk funksionon për shkak të një gabimi në kodin systemd që shkakton dështimin e përpunimit të /proc/self/mountinfo. Është gjithashtu interesante që në vitin 2018, u krijua një situatë e ngjashme dhe kur u përpoqën të shkruanin një shfrytëzim për cenueshmërinë CVE-2018-14634 në kernelin Linux, studiuesit e Qualys hasën në tre dobësi kritike në systemd.

Burimi: opennet.ru

Shto një koment