Root-kwetsbaarheid in de Linux-kernel en Denial of Service in systemd

Beveiligingsonderzoekers van Qualys hebben details onthuld van twee kwetsbaarheden die de Linux-kernel en de systemd-systeembeheerder treffen. Door een kwetsbaarheid in de kernel (CVE-2021-33909) kan een lokale gebruiker code uitvoeren met rootrechten door manipulatie van sterk geneste mappen.

Het gevaar van de kwetsbaarheid wordt vergroot door het feit dat de onderzoekers werkende exploits hebben kunnen voorbereiden die werken op Ubuntu 20.04/20.10/21.04, Debian 11 en Fedora 34 in de standaardconfiguratie. Opgemerkt wordt dat andere distributies niet zijn getest, maar theoretisch ook vatbaar zijn voor het probleem en kunnen worden aangevallen. Er wordt beloofd dat de volledige code van de exploits zal worden gepubliceerd nadat het probleem overal is opgelost, maar voorlopig is er slechts een prototype met beperkte functionaliteit beschikbaar, waardoor het systeem crasht. Het probleem doet zich voor sinds juli 2014 en treft kernelreleases vanaf 3.16. De oplossing voor de kwetsbaarheid werd gecoördineerd met de gemeenschap en op 19 juli in de kernel geaccepteerd. De belangrijkste distributies hebben al updates voor hun kernelpakketten gegenereerd (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Het beveiligingslek wordt veroorzaakt doordat het resultaat van een conversie van size_t naar int niet kan worden gecontroleerd voordat bewerkingen worden uitgevoerd in de seq_file-code, waarmee bestanden worden gemaakt op basis van een reeks records. Als u dit niet controleert, kan dit ertoe leiden dat er buiten het bereik naar de buffer wordt geschreven bij het maken, koppelen en verwijderen van een zeer geneste mapstructuur (padgrootte groter dan 1 GB). Als gevolg hiervan kan een aanvaller een string van 10 bytes "//verwijderd" verkrijgen, geschreven met een offset van "-2 GB - 10 bytes", die verwijst naar het gebied dat onmiddellijk voorafgaat aan de toegewezen buffer.

De voorbereide exploit vereist 5 GB geheugen en 1 miljoen vrije inodes om te kunnen werken. De exploit werkt door mkdir() aan te roepen om een ​​hiërarchie van ongeveer een miljoen submappen te creëren om een ​​bestandspadgrootte van meer dan 1 GB te bereiken. Deze map wordt via bind-mount in een aparte gebruikersnaamruimte aangekoppeld, waarna de functie rmdir() wordt uitgevoerd om deze te verwijderen. Tegelijkertijd wordt een thread gemaakt die een klein eBPF-programma laadt, dat wordt geblokkeerd in de fase na het controleren van de eBPF-pseudocode, maar vóór de JIT-compilatie ervan.

In de niet-bevoorrechte gebruikersnaamruimte wordt het bestand /proc/self/mountinfo geopend en wordt de lange padnaam van de aan de bind gekoppelde map gelezen, wat ertoe leidt dat de tekenreeks "//deleted" naar het gebied wordt geschreven vóór het begin van de buffer. De positie voor het schrijven van de regel wordt zo gekozen dat deze de instructie in het reeds geteste maar nog niet gecompileerde eBPF-programma overschrijft.

Vervolgens wordt op het eBPF-programmaniveau ongecontroleerd schrijven buiten de buffer omgezet in gecontroleerd vermogen om andere kernelstructuren te lezen en te schrijven door manipulatie van de btf- en map_push_elem-structuren. Als gevolg hiervan bepaalt de exploit de locatie van de modprobe_path[] buffer in het kernelgeheugen en overschrijft het pad “/sbin/modprobe” daarin, waardoor u de lancering van elk uitvoerbaar bestand met rootrechten kunt initiëren in het geval van een request_module()-aanroep, die bijvoorbeeld wordt uitgevoerd bij het maken van een netlink-socket.

Onderzoekers bieden verschillende oplossingen die alleen effectief zijn voor een specifieke exploit, maar die het probleem zelf niet elimineren. Het wordt aanbevolen om "/proc/sys/kernel/unprivileged_userns_clone" in te stellen op 0 om het mounten van mappen in een aparte gebruikers-ID-naamruimte uit te schakelen, en "/proc/sys/kernel/unprivileged_bpf_disabled" op 1 om het laden van eBPF-programma's in de kernel uit te schakelen.

Het is opmerkelijk dat de onderzoekers bij het analyseren van een alternatieve aanval waarbij gebruik werd gemaakt van het FUSE-mechanisme in plaats van bind-mound om een ​​grote directory te mounten, een andere kwetsbaarheid tegenkwamen (CVE-2021-33910) die de systemd-systeembeheerder aantastte. Het bleek dat bij een poging om een ​​map met een padgrootte van meer dan 8 MB via FUSE te mounten, het controle-initialisatieproces (PID1) geen stapelgeheugen meer heeft en crasht, waardoor het systeem in een “paniek”-status terechtkomt.

Het probleem is dat systemd de inhoud van /proc/self/mountinfo volgt en parseert, en elk koppelpunt verwerkt in de functie unit_name_path_escape(), die een strdupa()-bewerking uitvoert die de gegevens op de stapel plaatst in plaats van in dynamisch toegewezen geheugen . Omdat de maximale stapelgrootte beperkt is via RLIMIT_STACK, zorgt het verwerken van een te groot pad naar het koppelpunt ervoor dat het PID1-proces crasht en het systeem stopt. Voor een aanval kun je de eenvoudigste FUSE-module gebruiken in combinatie met het gebruik van een sterk geneste map als koppelpunt, waarvan de padgrootte groter is dan 8 MB.

Het probleem doet zich voor sinds systemd 220 (april 2015), is al opgelost in de hoofdrepository van systemd en opgelost in distributies (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Met name in systemd release 248 werkt de exploit niet vanwege een bug in de systemd-code die ervoor zorgt dat de verwerking van /proc/self/mountinfo mislukt. Het is ook interessant dat in 2018 een soortgelijke situatie zich voordeed en toen Qualys-onderzoekers bij het schrijven van een exploit voor de CVE-2018-14634-kwetsbaarheid in de Linux-kernel drie kritieke kwetsbaarheden in systemd tegenkwamen.

Bron: opennet.ru

Voeg een reactie