Turvauurijad ettevõttest Qualys avalikustasid kahe haavatavuse üksikasjad, mis mõjutavad Linuxi tuuma ja süsteemihaldurit systemd. Tuuma haavatavus (CVE-2021-33909) võimaldab kohalikul kasutajal saada root-õigustes koodi käivitamise võimaluse, manipuleerides sügavalt pesastatud kataloogidega.
Haavatavuse ohtlikkust suurendab asjaolu, et uurijatel õnnestus valmistada ette toimivad exploit'id, mis töötavad Ubuntu 20.04/20.10/21.04, Debian 11 ja Fedora 34 vaikekonfiguratsioonis. Märgitakse, et teisi distributsioone ei ole kontrollitud, kuid teoreetiliselt võivad ka need olla probleemist mõjutatud ja rünnatavad. Exploit'ide täielik kood lubatakse avaldada pärast probleemi laialdast kõrvaldamist, kuid praegu on saadaval vaid piiratud funktsionaalsusega prototüüp, mis põhjustab süsteemi krahhi. Probleem avaldub alates 2014. aasta juulist ja mõjutab tuuma versioone alates 3.16-st. Haavatavuse parandamine koordineeriti kogukonnaga ning lisati tuuma koosseisu 19. juulil. Peamised distributsioonid on juba koostanud uuendatud kernelipaketid (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).
Haavatavuse põhjus on see, et enne toimingute tegemist seq_file koodis, mis vastutab kirjete jadast failide loomise eest, ei kontrollita teisenduse tulemust tüübist size_t tüübiks int. Kontrolli puudumine võib väga suure pesastustasemega kataloogistruktuuri loomisel, ühendamisel ja kustutamisel viia kirjutamiseni väljapoole puhvri piire (tee pikkus üle 1 GB). Selle tulemusena võib ründaja saavutada 10-baidise stringi "//deleted" kirjutamise nihkega "- 2 GB — 10 baiti", mis osutab alale vahetult enne eraldatud puhvrit.
Ettevalmistatud exploit vajab töötamiseks 5 GB mälu ja 1 miljonit vaba inode'i. Exploit'i töö seisneb umbes miljonist pesastatud kataloogist koosneva hierarhia loomises mkdir() väljakutse abil, et saavutada failitee pikkus üle 1 GB. See kataloog ühendatakse bind-mount abil eraldi kasutajatunnuste nimeruumi (user namespace), mille järel käivitatakse selle eemaldamiseks funktsioon rmdir(). Paralleelselt luuakse lõim, mis laadib väikese eBPF-programmi ja blokeerub etapis pärast eBPF-i pseudokoodi kontrolli, kuid enne selle JIT-kompileerimist.
Ilma privileegideta kasutajanimede nimeruumis avatakse fail /proc/self/mountinfo ja hakatakse lugema bind-mount abil ühendatud kataloogi pikka teed, mille tulemusel kirjutatakse string «//deleted» puhvri algusest ettepoole jäävasse mälupiirkonda. Stringi kirjutuskoht valitakse nii, et see kirjutab üle juba kontrollitud, kuid veel kompileerimata eBPF-programmi instruktsiooni.
Seejärel muudetakse eBPF-programmi tasemel kontrollimatu puhvrist väljuv kirjutus btf-struktuuride ja map_push_elem kaudu teiste tuuma struktuuride juhitavaks lugemis- ja kirjutamisvõimaluseks. Lõpuks määrab exploit kindlaks modprobe_path[] puhvri asukoha tuuma mälus ja kirjutab selles üle tee «/sbin/modprobe», mis võimaldab käivitada mis tahes käivitatava faili root-õigustes, kui tehakse request_module() väljakutse, mida kasutatakse näiteks netlink-sokli loomisel.
Teadlased toovad välja mitu kaitsemeetmete möödahiilimise viisi, mis on tõhusad ainult selle konkreetse exploiti vastu ega kõrvalda probleemi ennast. Soovitatav on määrata parameeter «/proc/sys/kernel/unprivileged_userns_clone» väärtusele 0, et keelata kataloogide ühendamine eraldi kasutajanimede nimeruumis, ning «/proc/sys/kernel/unprivileged_bpf_disabled» väärtusele 1, et keelata eBPF-programmide laadimine tuuma.
Tähelepanuväärne on, et uurides ründe alternatiivset varianti, mis on seotud suure kataloogi ühendamisel bind-mount asemel FUSE-mehhanismi kasutamisega, avastasid teadlased veel ühe haavatavuse (CVE-2021-33910), mis mõjutab systemd süsteemihaldurit. Selgus, et kui FUSE kaudu püütakse ühendada kataloogi, mille tee pikkus ületab 8 MB, tekib initsialiseerimise juhtprotsessis (PID1) stekimälu ammendumine ja krahh, mis viib süsteemi olekusse «panic».
Probleem on seotud sellega, et systemd jälgib ja parsib faili /proc/self/mountinfo sisu ning töötleb iga haakepunkti funktsioonis unit_name_path_escape(), kus kasutatakse strdupa()-operatsiooni, mis paigutab andmed dünaamiliselt eraldatud mälu asemel pinu. Kuna pinu maksimaalne suurus on piiratud RLIMIT_STACK kaudu, põhjustab liiga pika haakepunkti tee töötlemine PID1 protsessi krahhi ja süsteemi töö seiskumise. Ründe jaoks saab kasutada lihtsat FUSE-moodulit koos väga sügava kataloogipuuga haakepunktiga, mille tee pikkus ületab 8 MB.
Probleem avaldub alates systemd versioonist 220 (aprill 2015), on systemd põhirepositooriumis juba kõrvaldatud ning parandatud distributsioonides (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Tähelepanuväärne on, et systemd 248 väljalaskes exploit ei toimi systemd koodis oleva vea tõttu, mis põhjustab tõrke faili /proc/self/mountinfo töötlemisel. Huvitav on ka see, et 2018. aastal tekkis sarnane olukord: kui püüti kirjutada exploiti Linuxi kerneli haavatavusele CVE-2018-14634, avastasid Qualysi uurijad systemd-s kolm kriitilist haavatavust.
Allikas: opennet.ru
