PDA

Просмотр полной версии : Root-уязвимость в ядре Linux и отказ в обслуживании в systemd


Suicide
21.07.2021, 19:43
Исследователи безопасности из компании Qualys раскрыли (https://blog.qualys.com/vulnerabilities-threat-research/2021/07/20/sequoia-a-local-privilege-escalation-vulnerability-in-linuxs-filesystem-layer-cve-2021-33909) детали (https://blog.qualys.com/vulnerabilities-threat-research/2021/07/20/cve-2021-33910-denial-of-service-stack-exhaustion-in-systemd-pid-1) двух уязвимостей, затрагивающих ядро Linux и системный менеджер systemd. Уязвимость в ядре (https://www.openwall.com/lists/oss-security/2021/07/20/1) (CVE-2021-33909 (https://security-tracker.debian.org/tracker/CVE-2021-33909)) позволяет локальному пользователю добиться выполнения кода с правами root через манипуляции с каталогами большой вложенности.

Опасность уязвимости усугубляется тем, что исследователям удалось подготовить рабочие эксплоиты, работающие в Ubuntu 20.04/20.10/21.04, Debian 11 и Fedora 34 в конфигурации по умолчанию. Отмечается, что другие дистрибутивы не проверялись, но теоретически тоже подвержены проблеме и могут быть атакованы. Полный код эксплоитов обещают опубликовать после повсеместного устранения проблемы, а пока доступен (https://www.qualys.com/research/security-advisories/) лишь ограниченный в функциональности прототип, вызывающий крах системы. Проблема проявляется (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=058504ed) с июля 2014 года и затрагивает выпуски ядра начиная с 3.16. Исправление уязвимости было скоординировано с сообществом и принято (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8cae8cd89f05f6de223d63e6d15e31c8ba9cf53b) в состав ядра 19 июля. Основные дистрибутивы уже сформировали обновления пакетов с ядром (Debian (https://security-tracker.debian.org/tracker/CVE-2021-33909), Ubuntu (https://ubuntu.com/security/CVE-2021-33909), Fedora (https://bugzilla.redhat.com/show_bug.cgi?id=1984019), RHEL (https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2021-33909), SUSE (https://bugzilla.suse.com/show_bug.cgi?id=CVE-2021-33909), Arch (https://security.archlinux.org/CVE-2021-33909)).

Уязвимость вызвана отсутствием проверки результата преобразования типа size_t в int перед выполнением операций в коде seq_file (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/seq_file.c?id=8cae8cd89f05), осуществляющем создание файлов из последовательности записей. Отсутствие проверки может привести к записи в область вне границ буфера при создании, монтировании и удалении структуры каталогов с очень большим уровнем вложенности (размер пути более 1 ГБ). В итоге атакующий может добиться записи 10-байтовой строки "//deleted" со смещением "- 2 ГБ - 10 байт", указывающим на область, непосредственно предшествующую выделенному буферу.

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

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

Далее на уровне программы eBPF неконтролируемая запись вне буфера трансформируется в управляемую возможность чтения и записи в другие структуры ядра через манипуляцию со структурами btf и map_push_elem (https://www.thezdi.com/blog/2020/4/8/cve-2020-8835-linux-kernel-privilege-escalation-via-improper-ebpf-program-verification). Затем эксплоит определяет местоположение буфера 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 для монтирования большого каталога, исследователи натолкнулись (https://www.openwall.com/lists/oss-security/2021/07/20/2) на ещё одну уязвимость (CVE-2021-33910 (https://security-tracker.debian.org/tracker/CVE-2021-33910)), затрагивающую системный менеджер systemd. Оказалось, что при попытке монтирования через FUSE каталога c размером пути, превышающим 8 МБ, в управляющем процессе инициализации (PID1) наступает исчерпание памяти стека и крах, который приводит систему в состояние "panic".

Проблема связана с тем, что systemd отслеживает и разбирает содержимое /proc/self/mountinfo и обрабатывает каждую точку монтирования в функции unit_name_path_escape(), в которой выполняется операция strdupa(), размещающая данные в стеке, а не в динамически выделяемой памяти. Так как максимальный размер стека ограничен через RLIMIT_STACK, обработка слишком большого пути к точке монтирования приводит к краху процесса PID1 и остановке работы системы. Для атаки можно использовать простейший модуль (https://www.qualys.com/2021/07/20/cve-2021-33910/cve-2021-33910-crasher.c) FUSE в сочетании с использованием в качестве точки монтирования каталога с большим уровнем вложенности, размер пути в котором превышает 8 МБ.

Проблема проявляется начиная с systemd 220 (апрель 2015), уже устранена (https://github.com/systemd/systemd/pull/20256/commits/441e0115646d54f080e5c3bb0ba477c892861ab9) в основном репозитории systemd и исправлена в дистрибутивах (Debian (https://security-tracker.debian.org/tracker/CVE-2021-33910), Ubuntu (https://ubuntu.com/security/CVE-2021-33910), Fedora (https://bugzilla.redhat.com/show_bug.cgi?id=1984019), RHEL (https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2021-33910), SUSE (https://bugzilla.suse.com/show_bug.cgi?id=CVE-2021-33910), Arch (https://security.archlinux.org/CVE-2021-33910)). Примечательно, что в выпуске systemd 248 эксплоит не работает из-за ошибки (https://github.com/systemd/systemd/issues/19464) в коде systemd, приводящей к сбою при обработке /proc/self/mountinfo. Также интересно, что в 2018 году возникла похожая ситуация и при попытке написать эксплоит к уязвимости CVE-2018-14634 (https://www.opennet.ru/opennews/art.shtml?num=49340) в ядре Linux, исследователи Qualys натолкнулись на три критические уязимости (https://www.opennet.ru/opennews/art.shtml?num=49931) в systemd.

21.07.2021

https://www.opennet.ru/opennews/art.shtml?num=55528​