1. Описание зафиксированной угрозы

[Название угрозы]: LPE-уязвимость в утилите pkexec, входящей в состав PolkIt

[Тип угрозы]: локальное повышение привилегий (LPE)

[CVE]: CVE-2021-4034

[CVSS vector]: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

[Platform]: Все дистрибутивы Linux

[Product]: pkexec

[Version]: Все версии

[Severity]: 7.8/10

[Дата обнаружения]: 18.11.2021 (Дата публикации: 25.01.2022)

25 января 2022 года группа исследователей кибербезопасности из Qualys опубликовала уязвимость, получившую название PwnKit. Эксплуатация данной уязвимости приводит к повреждению памяти в программе pkexec, вследствие чего злоумышленник может локально повысить привилегии до уровня системы. Данная уязвимость присутствует в pkexec с момента ее создания, с мая 2009 г. Pkexec как часть polkit присутствует во всех основных дистрибутивах Linux (Ubuntu, Debian, Fedora, CentOS).

Polkit (PolicyKit) — это компонент, контролирующий привилегии на уровне системы в Unix-подобных ОС и позволяющий организовать взаимодействие непривилегированных процессов с привилегированными. Иногда его называют «sudo для systemd». Примеры использования polkit — когда пользователь выключает или перезагружает компьютер, управляет беспроводными подключениями, получает доступ к аудио, сканера и пр. Pkexec — это SUID root-программа, предоставляющая интерфейс к Polkit и позволяющая исполнять команды от имени другого пользователя или администратора.

Уязвимость PwnKit (CVE-2021-4034) является опасной по следующим причинам:

  • Pkexec установлена по умолчанию во всех основных дистрибутивах Linux. Исследователями были успешно поэксплуатированы дистрибутивы Ubuntu, Debian, Fedora, CentOS. Уязвимость присутствует в pkexec с мая 2009 года
  • Любой непривилегированный пользователь может использовать данную уязвимость для получения root-прав.
  • Хотя технически эта уязвимость представляет собой уязвимость типа повреждения памяти, с ее эксплуатацией не происходит никаких проблем независимо от архитектуры, эксплойт работает быстро и надежно.Эксплуатировать уязвимость возможно, даже если сам демон Polkit не запущен.

Публичный эксплойт был разработан на C и опубликован даже до, а не после рекомендации. Он заявлен как proof-of-concept. Эксплойт доступен на haxx.in. Уязвимость рассматривалась как закрытый эксплойт нулевого дня в течение как минимум одного дня.

Для успешной эксплуатации уязвимости пользователь должен быть аутентифицирован в системе.

2. Технические детали угрозы

Программа pkexec неправильно проверяет количество переданных ей аргументов. Эта проблема в конечном итоге приводит к попыткам выполнить переменные среды как команды, что, в свою очередь, приводит к тому, что pkexec выполняет произвольный код от имени УЗ root, предоставляя злоумышленнику локальную эскалацию привилегий.

Ниже представлены технические подробности уязвимости.

Начало функции pkexec main() обрабатывает аргументы командной строки (строки 534-568) и ищет программу для выполнения, если ее путь не является абсолютным, в каталогах переменной среды PATH (строки 610-640):

------------------------------------------------------------------------

435 main (int argc, char *argv[])

436 {

...

534   for (n = 1; n < (guint) argc; n++)

535     {

...

568     }

...

610   path = g_strdup (argv[n]);

...

629   if (path[0] != '/')

630     {

...

632       s = g_find_program_in_path (path);

...

639       argv[n] = path = s;

640     }

------------------------------------------------------------------------

Если количество аргументов командной строки argc равно 0, что означает, что список аргументов argv, который мы передаем в execve(), пуст, т. е. {NULL}, тогда argv[0] равен NULL. Это терминатор списка аргументов. Следовательно:

  • В строке 534 целое число n постоянно установлено равным 1.
  • В строке 610 путь указателя считывается за пределами argv[1].
  • В строке 639 указатель s записывается за пределы argv[1].
Когда мы производим системный вызов execve() для новой программы, ядро копирует наш аргумент, строки окружения и указатели (argv и envp) в конец стека новой программы, например:

|---------+---------+-----+------------|---------+---------+-----+------------|

| 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

Поскольку указатели argv и envp непрерывны в памяти, если argc равен 0, то argv[1] за границами на самом деле является envp[0], указателем на нашу первую переменную среды, «значение». Следовательно:

  • В строке 610 путь исполняемой программы считывается за пределами argv[1] (т. е. envp[0]) и указывает на «значение»
  • В строке 632 это «значение» пути передается в g_find_program_in_path() (поскольку «значение» не начинается с косой черты в строке 629).
  • Затем g_find_program_in_path() ищет исполняемый файл с именем «value» в каталогах нашей переменной окружения PATH.
  • Если такой исполняемый файл найден, его полный путь возвращается функции main() pkexec (строка 632).
  • Наконец, в строке 639 этот полный путь записывается за пределы argv[1] (т. е. envp[0]), таким образом перезаписывая нашу первую переменную среды.

3. Рекомендации по обнаружению уязвимых компонентов

Уязвимы все Linux-дистрибутивы, содержащие Polkit.

Для выявления уязвимых систем рекомендуется проверять их на наличие pkexec с помощью одной из следующих команд:

whereis pkexec

which pkexec

ls -la /usr/bin/pkexec

find / -type f -name pkexec

4. Рекомендации по обнаружению попыток эксплуатации уязвимости PwnKit

Техника эксплуатации уязвимости PwnKit может оставлять следы в системных журналах (auth.log), ниже представлены примеры таких событий:

“The value for the SHELL variable was not found the /etc/shells file”,

“The value for environment variable […] contains suspicious content”.

Однако в оригинальном исследовании подчеркивается, что попытки эксплуатации могут проходить бесследно для системных журналов Linux.

5. Рекомендации по устранению уязвимости PwnKit

Поскольку большинство основных вендоров дистрибутивов уже выпустили исправления, лучшим вариантом сейчас будет их установка.
https://access.redhat.com/security/vulnerabilities/RHSB-2022-001
https://www.suse.com/de-de/security/cve/CVE-2021-4034.html
https://security-tracker.debian.org/tracker/CVE-2021-4034
https://ubuntu.com/security/CVE-2021-4034
Актуальный список ресурсов по уязвимости указан в разделе 6.
Если вы не можете установить или еще нет доступных исправлений, вы можете предотвратить использование уязвимости, удалив бит SUID из инструмента pkexec — просто убедитесь, что это не нарушит работоспособность системы:
# chmod 0755 /usr/bin/pkexec
Для восстановления:
# chmod 4755 /usr/bin/pkexec)

Разработчиками polkit была исправлена ошибка в проверке количества аргументов, приводящая к эксплуатации уязвимости. Так при количестве аргументов меньше одного (argc <1) утилита pkexec завершит свое исполнение с кодом 126 или 127.

6. Ссылки

https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034
https://access.redhat.com/security/vulnerabilities/RHSB-2022-001
https://github.com/berdav/CVE-2021-4034
https://www.bleepingcomputer.com/news/security/linux-system-service-bug-gives-root-on-all-major-distros-exploit-released/
https://www.helpnetsecurity.com/2022/01/26/cve-2021-4034/
https://gitlab.freedesktop.org/polkit/polkit/-/commit/a2bf5c9c83b6ae46cbd5c779d3055bff81ded683
https://www.suse.com/de-de/security/cve/CVE-2021-4034.html
https://security-tracker.debian.org/tracker/CVE-2021-4034
https://ubuntu.com/security/CVE-2021-4034