Критическая уязвимость в PolKit, позволяющая получить root-доступ в большинстве дистрибутивов Linux

Компания Qualys выявила уявзвимость (CVE-2021-4034) в системном компоненте Polkit (бывший PolicyKit), используемом в дистрибутивах Linux для организации выполнения непривилегированными пользователями действий, требующих повышенных прав доступа. Уязвимость позволяет непривилегированному локальному пользователю повысить свои привилегии до пользователя root и получить полный контроль за системой. Проблема получила кодовое имя PwnKit и примечательная подготовкой рабочего эксплоита, работающего в конфигурации по умолчанию большинства дистрибутивов Linux.

Проблема присутствует во входящей в состав PolKit утилите pkexec, поставляемой с флагом SUID root и предназначенной для запуска команд с привилегиями другого пользователя в соответствии с заданными правилами
PolKit. Из-за некорректной обработки передаваемых в pkexec аргументов командной строки непривилегированный пользователь мог обойти аутентификацию и добиться запуска команд с правами root, независимо от установленных правил доступа.

Pkexec не проверял корректность счётчика аргументов командной строки (argc), передаваемых при запуске процесса в массиве argv. Подразумевалось, что первая запись массива всегда содержит имя процесса (pkexec), а вторая либо значение NULL, либо имя запускаемой через pkexec команды.

|———+———+—–+————|———+———+—–+————|
| argv[0] | argv[1] | … | argv[argc] | envp[0] | envp[1] | … | envp[envc] |
|—-|—-+—-|—-+—–+—–|——|—-|—-+—-|—-+—–+—–|——|
V V V V V V
“program” “-option” NULL “value” “PATH=name” NULL

Так как счётчик аргументов не проверялся на соответствие фактическому содержимому массива и полагалось, что он всегда больше 1, в случае передачи процессу пустого массива, pkexec воспринимал значение NULL как первый аргумент (имя процесса), а следующую за пределами буфера память как далее идущее содержимое массива. Проблема в том, что следом за массивом argv в памяти размещается массив envp, содержащий переменные окружения. Таким образом, при пустом массиве argv, pkexec извлекает данные о запускаемой с повышенными привилегиями команде из первого элемента массива с переменными окружения (argv[1] становился идентичен envp[0]), содержимое которого может контролировать атакующий.

Получив значение argv[1], pkexec пытается с учётом файловых путей в переменной окружения PATH определить полный путь к исполняемому файлу и записать указатель на строку с полный путём в argv[1], что приведёт к перезаписи и значения первой переменной окружения, так как argv[1] идентичен envp[0]. Через манипуляцию с именами файлов атакующий может осуществить подстановку своей переменной окружения в
pkexec, в том числе подставить переменную окружения “LD_PRELOAD” и организовать загрузку в процесс своей разделяемой библиотеки на стадии, когда pkexec ещё выполняется с правами root и до проверки полномочий запуска.

Отмечается, что несмотря на то, что проблема вызвана повреждением памяти, она может надёжно и повторяемо эксплуатироваться независимо от используемой аппаратной архитектуры. Подготовленный эксплоит успешно протестирован в Ubuntu, Debian, Fedora и CentOS, но может быть использован и в других дистрибутивах. Оригинальный эксплоит пока не доступен публично, что утверждается, что он является тривиальным и может быть легко воссоздан другими исследователями, поэтому на многопользовательских системах важно как можно скорее установить обновление с исправлением. Polkit также доступен для BSD-систем и Solaris, но изучение возможности эксплуатации в них не производилось. Известно только то, что атака не сможет быть осуществлена в OpenBSD, так как ядро OpenBSD не допускает указание при вызове execve() нулевого значения argc.

Проблема присутствует с мая 2009 года, со времени добавления команды pkexec. Исправление уявзимости в PolKit пока доступно в виде патча (корректирующий выпуск не сформирован), но так как разработчики дистрибутива были заранее уведомлены о проблеме, большинство дистрибутивов опубликовало обновление одновременно с раскрытием информации об уязвимости. Проблема устранена в RHEL 6/7/8, Debian, Ubuntu, openSUSE, SUSE, Fedora, ALT Linux и ROSA. Проблема пока не исправлена в Gentoo и Arch Linux. В качестве временной меры для блокирования уязвимости можно убрать флаг SUID root с программы /usr/bin/pkexec (“chmod 0755 /usr/bin/pkexec”).



Release. Ссылка here.