Root zranitelnost v jádře Linuxu a odmítnutí služby v systemd

Bezpečnostní výzkumníci ze společnosti Qualys odhalili podrobnosti o dvou zranitelnostech, které se týkají kernelu Linux a systémového správce systemd. Zranitelnost v kernelu (CVE-2021-33909) umožňuje lokálnímu uživateli získat práva root prostřednictvím manipulace s hluboce vnořenými adresáři.

Nebezpečí této zranitelnosti je umocněno tím, že výzkumníkům se podařilo připravit funkční exploity, které pracují na Ubuntu 20.04/20.10/21.04, Debianu 11 a Fedoře 34 v základní konfiguraci. Jinak se uvádí, že další distribuce nebyly testovány, ale teoreticky by také mohly být ohroženy a mohou být napadeny. Kompletní kód exploitů slibují zveřejnit po celkovém odstranění problému, zatímco je k dispozici pouze omezená funkční verze prototypu, která způsobuje pád systému. Problém se projevuje od července 2014 a týká se verzí jádra počínaje 3.16. Oprava zranitelnosti byla koordinována se komunitou a byla přijata do jádra 19. července. Hlavní distribuce již vydaly aktualizace balíčků s jádrem (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Zranitelnost je způsobena absencí kontroly výsledku převodu typu size_t na int před prováděním operací v kódu seq_file, který vytváří soubory z posloupnosti záznamů. Nedostatek kontroly může vést k zápisu mimo hranice vyrovnávací paměti při vytváření, montování a odstraňování struktury adresářů s velmi vysokou úrovní vnoření (velikost cesty přes 1 GB). V důsledku toho může útočník dosáhnout zápisu 10-bajtového řetězce „//deleted“ s offsetem „- 2 GB - 10 bytů“, který ukazuje na oblast těsně před přidělenou vyrovnávací pamětí.

Připravený exploit potřebuje k provozu 5 GB paměti a 1 milion volných inode. Funkce exploitu spočívá ve vytvoření hierarchie z přibližně milionu vnořených adresářů prostřednictvím volání mkdir() tak, aby dosáhla velikosti cesty souboru větší než 1 GB. Tento adresář je namontován pomocí bind-mount v samostatném uživatelském jmenovém prostoru (user namespace), po čemž následuje volání funkce rmdir() pro jeho odstranění. Současně je vytvářen vlákno, které načítá malý program eBPF, který se blokuje ve stádiu po kontrole pseudokódu eBPF, ale před jeho JIT-kompilací.

Ve jménu neprivilegovaného prostoru identifikátorů uživatelů se otevře soubor /proc/self/mountinfo a začne se číst dlouhá cesta adresáře připojeného pomocí bind-mount, což vede k zápisu řetězce „//deleted“ do oblasti před začátkem vyrovnávací paměti. Pozice pro zápis řetězce je vybrána tak, aby přepsala instrukci v již ověřeném, ale ještě nepřeloženém programu eBPF.

Dále na úrovni programu eBPF se nekontrolovaný zápis mimo vyrovnávací paměť transformuje na řízenou možnost čtení a zápisu do jiných struktur jádra prostřednictvím manipulace se strukturami btf a map_push_elem. V důsledku toho exploit určuje umístění vyrovnávací paměti modprobe_path[] v paměti jádra a přepisuje v ní cestu „/sbin/modprobe“, což umožňuje iniciovat spuštění jakéhokoliv spustitelného souboru s právy root při provedení volání request_module(), které se provádí například při vytváření socketu netlink.

Výzkumníci uvádějí několik obcházejících metod ochrany, které jsou účinné pouze pro konkrétní exploit, ale neodstraňují samotný problém. Doporučuje se nastavit parametr „/proc/sys/kernel/unprivileged_userns_clone“ na hodnotu 0 pro zakázání připojování adresářů v samostatném prostoru identifikátorů uživatelů, a také „/proc/sys/kernel/unprivileged_bpf_disabled“ na 1 pro zakázání načítání programů eBPF do jádra.

Zajímavé je, že při analýze alternativní varianty útoku, která se týká použití mechanismu FUSE místo bind-mount pro připojování velkého adresáře, narazili výzkumníci na další zranitelnost (CVE-2021-33910), která se dotýká systémového správce systemd. Ukázalo se, že při pokusu o připojení adresáře pomocí FUSE, jehož velikost cesty přesahuje 8 MB, dochází v řídícím procesu inicializace (PID1) k vyčerpání paměti zásobníku a pádu, který přivádí systém do stavu „panic“.

Problém je spojen s tím, že systemd sleduje a analyzuje obsah /proc/self/mountinfo a zpracovává každou montážní jednotku ve funkci unit_name_path_escape(), kde se provádí operace strdupa(), která umísťuje data na zásobník místo do dynamicky alokované paměti. Vzhledem k tomu, že maximální velikost zásobníku je omezena přes RLIMIT_STACK, zpracování příliš dlouhé cesty k montážnímu bodu způsobuje pád procesu PID1 a zastavení systému. K útoku lze využít jednoduchý modul FUSE v kombinaci s použitím jako montážního bodu adresáře s velkým počtem podadresářů, jehož délka cesty přesahuje 8 MB.

Problém se projevuje od systemd 220 (duben 2015), již byl odstraněn v hlavním repozitáři systemd a opraven v distribucích (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Zajímavé je, že v verzi systemd 248 exploit nefunguje kvůli chybě v kódu systemd, která způsobuje pád při zpracování /proc/self/mountinfo. Také je zajímavé, že v roce 2018 nastala podobná situace, kdy při pokusu o napsání exploitu na zranitelnost CVE-2018-14634 v jádře Linux vědci z Qualys narazili na tři kritické zranitelnosti v systemd.

Zdroj: opennet.ru

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster