Beveiligingsonderzoekers van Qualys hebben details onthuld over twee kwetsbaarheden die het Linux-kernel en het systeembeheerder systemd aantasten. De kwetsbaarheid in de kernel (CVE-2021-33909) stelt een lokale gebruiker in staat om code met root-rechten uit te voeren door manipulatie van mappen met een grote diepte.
De gevaren van de kwetsbaarheid worden verergerd doordat onderzoekers werkende exploits hebben voorbereid die werken op Ubuntu 20.04/20.10/21.04, Debian 11 en Fedora 34 in de standaardconfiguratie. Het is opgemerkt dat andere distributies niet zijn getest, maar theoretisch ook kwetsbaar kunnen zijn en aangevallen kunnen worden. De volledige code van de exploits belooft openbaar gemaakt te worden na een alomvattende oplossing van het probleem, terwijl momenteel slechts een beperkte functionele prototype beschikbaar is die een systeemcrash veroorzaakt. Het probleem bestaat al sinds juli 2014 en beïnvloedt kernelversies vanaf 3.16. De patch voor de kwetsbaarheid is gecoördineerd met de gemeenschap en is op 19 juli in de kernel opgenomen. De belangrijkste distributies hebben al updates voor de kernelpakketten geformuleerd (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).
De kwetsbaarheid wordt veroorzaakt door het ontbreken van controle op de conversieresultaten van type size_t naar int voordat bewerkingen in de seq_file-code worden uitgevoerd, die bestanden uit een reeks records aanmaakt. Het ontbreken van controle kan leiden tot schrijven buiten de buffer bij het aanmaken, monteren en verwijderen van een mappenstructuur met een zeer hoge mate van nesting (padgrootte van meer dan 1 GB). Als gevolg hiervan kan een aanvaller een 10-byte string "//deleted" schrijven met een offset van "-2 GB - 10 bytes", wat duidt op het gebied direct voorafgaand aan de toegewezen buffer.
De voorbereide exploit vereist 5 GB geheugen en 1 miljoen vrije inode. De werking van de exploit bestaat uit het maken van een hiƫrarchie van ongeveer een miljoen geneste mappen via een mkdir()-aanroep om een padgrootte groter dan 1 GB te bereiken. Deze map wordt gemonteerd via een bind-mount in een aparte gebruikersnaamruimte (user namespace), waarna de rmdir()-functie wordt aangeroepen om deze te verwijderen. Tegelijkertijd wordt er een thread aangemaakt die een kleine eBPF-programma laadt, welke wordt geblokkeerd tijdens de fase na controle van de pseudocode van eBPF, maar voor de JIT-compilatie.
In de niet-privileged namespace voor gebruikers-ID's wordt het bestand /proc/self/mountinfo geopend en begint men met het lezen van het lange pad van de map die is gekoppeld met behulp van een bind-mount, wat resulteert in het schrijven van de string "//deleted" in het gebied voor het begin van de buffer. De positie voor het schrijven van de string wordt zo gekozen dat deze een instructie in een al gecontroleerd, maar nog niet gecompileerd eBPF-programma overschrijft.
Vervolgens wordt op het niveau van het eBPF-programma een ongecontroleerde schrijfactie buiten de buffer omgevormd tot een beheersbare mogelijkheid tot lezen en schrijven in andere kernelstructuren door middel van manipulatie van de btf- en map_push_elem-structuren. Uiteindelijk bepaalt de exploit de locatie van de buffer modprobe_path[] in het geheugen van de kernel en overschrijft het daarin het pad "/sbin/modprobe", wat het mogelijk maakt om elk uitvoerbaar bestand met rootrechten te starten in het geval van de aanroep request_module(), die bijvoorbeeld wordt uitgevoerd bij het aanmaken van een netlink-socket.
Onderzoekers beschrijven verschillende omzeilmethoden voor beveiliging die alleen effectief zijn tegen specifieke exploits maar het probleem zelf niet verhelpen. Het wordt aanbevolen om de parameter "/proc/sys/kernel/unprivileged_userns_clone" op 0 te zetten om het koppelen van mappen in een aparte gebruikers-ID namespace te verbieden, evenals "/proc/sys/kernel/unprivileged_bpf_disabled" op 1 om het laden van eBPF-programma's in de kernel te verbieden.
Het is opmerkelijk dat terwijl ze een alternatieve aanvalsmethode onderzochten die gebruik maakt van het FUSE-mechanisme in plaats van bind-mount voor het koppelen van een grote map, onderzoekers nog een kwetsbaarheid (CVE-2021-33910) ontdekten die het systeembeheerder systemd raakt. Het bleek dat bij het proberen te koppelen van een map via FUSE met een padgrootte van meer dan 8 MB, er een uitputting van de stackgeheugen in het init-proces (PID1) optreedt, wat leidt tot een crash die het systeem in een "panic"-toestand brengt.
Het probleem heeft te maken met het feit dat systemd de inhoud van /proc/self/mountinfo volgt en ontleedt, en elke montagepunt behandelt in de functie unit_name_path_escape(), waarin de strdupa()-bewerking wordt uitgevoerd, waardoor de gegevens op de stack worden geplaatst in plaats van in dynamisch toegewezen geheugen. Aangezien de maximale stackgrootte is beperkt via RLIMIT_STACK, leidt de verwerking van een te lange pad naar het montagepunt tot een crash van proces PID1 en het stoppen van het systeem. Voor de aanval kan een eenvoudige FUSE-module worden gebruikt in combinatie met een directory met een grote diepte als montagepunt, waarvan de padgrootte meer dan 8 MB bedraagt.
Het probleem doet zich voor vanaf systemd 220 (april 2015), en is al opgelost in de hoofdrepository van systemd en gecorrigeerd in distributies (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Opmerkelijk is dat de exploit in release systemd 248 niet werkt vanwege een fout in de systemd-code, die leidt tot een crash bij de verwerking van /proc/self/mountinfo. Ook interessant is dat in 2018 een vergelijkbare situatie ontstond en bij een poging om een exploit te schrijven voor de kwetsbaarheid CVE-2018-14634 in de Linux-kernel, onderzoekers van Qualys op drie kritieke kwetsbaarheden in systemd stuitten.
Bron: opennet.ru
