Root уязвимост в ядрото на Linux и отказ на обслужване в systemd

Изследователи по сигурността от компанията Qualys разкриха подробности за две уязвимости, които засягат ядрото на Linux и системния мениджър systemd. Уязвимостта в ядрото (CVE-2021-33909) позволява на локален потребител да постигне изпълнение на код с правата на root чрез манипулации с директории с голяма вложеност.

Опасността от уязвимостта се засилва от факта, че на изследователите е успяло да подготвят работещи експлойти, които действат в Ubuntu 20.04/20.10/21.04, Debian 11 и Fedora 34 в конфигурацията по подразбиране. Отбелязва се, че други дистрибуции не са проверявани, но теоретично също могат да бъдат засегнати и да станат обект на атака. Пълен код на експлоитите се обещава да бъде публикуван след всеобхватно отстраняване на проблема, а в момента е наличен само ограничен по функционалност прототип, който причинява срив на системата. Проблемът се проявява от юли 2014 година и засяга версии на ядрото, започващи от 3.16. Поправката на уязвимостта беше координирана с общността и приета в ядрото на 19 юли. Основните дистрибуции вече са издали актуализации на пакетите с ядрото (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

Уязвимостта е причинена от липсата на проверка на резултата от преобразуването на типа size_t в int преди изпълнението на операции в кода seq_file, който осъществява създаването на файлове от последователност от записи. Липсата на проверка може да доведе до запис в област извън границите на буфера при създаване, монтиране и изтриване на структура на директории с много голямо ниво на вложеност (размер на пътя над 1 GB). В резултат на това атакуващият може да достигне записването на 10-байтова стринг „//deleted“ с отместване „- 2 GB - 10 байта“, указващо на зоната, непосредствено предшестваща заделения буфер.

Подготовеният експлоит изисква за работа 5 GB памет и 1 милион свободни inode. Работата на експлоита се свежда до създаване чрез повикване на mkdir() йерархия от около милион вложени директории за достигане на размер на файловия път, превишаващ 1 GB. Тази директория се монтира чрез bind-mount в отделно пространство на имената на идентификаторите на потребителите (user namespace), след което се стартира функцията rmdir() за нейното изтриване. Паралелно се създава поток, който зарежда малка eBPF-програма, която е блокирана на етапа след проверка на псевдокода eBPF, но преди JIT-компилацията.

В непривилегированото пространство на идентификаторите на потребителите се отваря файл \/proc\/self\/mountinfo и започва да се чете дългия път на каталога, монтиран чрез bind-mount, което води до запис на реда "\/\/deleted" в областта преди началото на буфера. Позицията за запис на реда се избира по такъв начин, че да презапише инструкция в вече проверен, но все още не компилиран eBPF програма.

След това, на нивото на eBPF програмата неконтролираното записване извън буфера се трансформира в управление на възможността за четене и запис в други структури на ядрото чрез манипулация с btf структури и map_push_elem. В крайна сметка, експлоитът определя местоположението на буфера modprobe_path[] в ядрената памет и презаписва в него пътя "\/sbin\/modprobe", което позволява да се инициира стартиране на всеки изпълним файл с права root в случай на извършване на повикването request_module(), което се изпълнява, например, при създаване на сокет netlink.

Изследователите представят няколко обходни метода за защита, които са ефективни само за конкретния експлоит, но не решават самия проблем. Препоръчва се да се зададе параметър "\/proc\/sys\/kernel\/unprivileged_userns_clone" на стойност 0 за забрана на монтиране на каталози в отделно пространство на идентификаторите на потребителите, а също така "\/proc\/sys\/kernel\/unprivileged_bpf_disabled" на 1 за забрана на зареждането на eBPF програми в ядрото.

Забележително е, че разглеждайки алтернативен вариант на атаката, свързана с използването на механизма FUSE вместо bind-mount за монтиране на голям каталог, изследователите се натъкнаха на още една уязвимост (CVE-2021-33910), засягаща системния мениджър systemd. Оказа се, че при опит за монтиране през FUSE на каталог с размер на пътя, надвишаващ 8 MB, в управляващия процес на инициализация (PID1) настъпва исчерпване на паметта на стека и срив, което въвежда системата в състояние на "panic."

Проблемата е свързана с това, че systemd проследява и обработва съдържанието на /proc/self/mountinfo, и обработва всяка точка на монтиране в функцията unit_name_path_escape(), в която се изпълнява операцията strdupa(), разполагайки данните в стека, а не в динамично заделена памет. Тъй като максималният размер на стека е ограничен чрез RLIMIT_STACK, обработката на твърде дълъг път към точка на монтиране води до срив на процеса PID1 и спиране на системата. За атака може да се използва прост модул FUSE в комбинация с използването на каталог с висока степен на вложеност като точка на монтиране, чийто размер на пътя надвишава 8MB.

Проблемата се проявява от systemd 220 (април 2015), вече е отстранена в основното хранилище на systemd и е поправена в дистрибуциите (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Забележително е, че в версията systemd 248 експлоитът не работи поради грешка в кода на systemd, която води до срив при обработка на /proc/self/mountinfo. Интересно е, че през 2018 година възникна подобна ситуация и при опити за написване на експлоит за уязвимостта CVE-2018-14634 в ядрото на Linux, изследователите на Qualys се натъкнаха на три критични уязвимости в systemd.

Източник: opennet.ru

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster