Сергей Попов
Администратор
- 30.12.2015
- 5 712
- 6 744
- Специализация
- OSINT
- Веб-безопасность
- Статус верификации
- ✓ Verified
На внутреннем пентесте корпоративного парка Fedora Workstation получил shell от обычного пользователя через фишинговый payload. Стандартная рутина:
sudo -l - пусто, SUID-бинари - штатные, cron - чисто. Тоска. Но при проверке пакетного менеджера обнаружилось, что pkcon install на целевом хосте выполняется без запроса пароля - пакет устанавливается от root. Зафиксировал аномалию в отчёте как potential finding и пошёл дальше. А в апреле 2026 Deutsche Telekom Red Team опубликовали CVE-2026-41651 (Pack2TheRoot), подтвердив: за этим поведением стоит TOCTOU-уязвимость в PackageKit с CVSS 8.8 (HIGH), затрагивающая дефолтные установки Ubuntu, Debian, Fedora и RHEL-based дистрибутивов. Двенадцать лет уязвимого кода - с версии 1.0.2 - в привилегированном D-Bus-сервисе, который по умолчанию крутится на миллионах Linux-машин. Двенадцать лет, Карл.Место Pack2TheRoot в цепочке атаки
Pack2TheRoot - вектор локального повышения привилегий (LPE linux), который встраивается в kill chain после получения initial access. В терминологии MITRE ATT&CK основная техника - Exploitation for Privilege Escalation (T1068, privilege-escalation). Побочно задействуется Unix Shell (T1059.004, execution) для взаимодействия с D-Bus и подготовки вредоносного пакета. Подробнее - в нашем обзоре linux для пентестера.Что нужно до: непривилегированный shell на хосте с установленным PackageKit >= 1.0.2 и <= 1.3.4. Способ получения shell не принципиален - SSH с украденными кредами, RCE в веб-приложении, фишинговый документ.
Что даёт: произвольная установка пакетов от root, включая выполнение RPM/DEB scriptlets. На практике это полный root access - scriptlet в пакете выполняет любую команду от root.
Что следует после: с root - lateral movement через SSH-ключи или кеши кредов, persistence через systemd unit, exfiltration данных.
PackageKit как компонент, установленный по умолчанию и редко обновляемый отдельно от ядра системы - классический пример OWASP A06 (Vulnerable and Outdated Components). Админы патчат ядро, обновляют openssh, но PackageKit не попадает в чеклист hardening'а, хотя работает от root и принимает D-Bus-вызовы от любого локального пользователя. Типичная слепая зона.
| Параметр | Значение |
|---|---|
| Тип пентеста | Внутренний (требуется локальный доступ, AV:L) |
| Уровень привилегий | Low (PR:L - любой непривилегированный пользователь) |
| Целевые ОС | Ubuntu Desktop/Server 18.04–26.04, Debian Trixie 13.4, Fedora 43, RockyLinux 10.1 |
| Условие | PackageKit 1.0.2–1.3.4, демон доступен через D-Bus |
| Сложность | Низкая (AC:L), эксплуатация за секунды |
| Scope | Changed (S:C - выход за пределы уязвимого компонента) |
Анатомия CVE-2026-41651: TOCTOU в транзакциях PackageKit
Архитектура PackageKit и D-Bus транзакции
PackageKit - кросс-дистрибутивный D-Bus системный сервис, работающий от root. Он абстрагирует управление пакетами через единый API поверх бэкендов apt (Debian/Ubuntu) и dnf (Fedora/RHEL). GUI-центры приложений (GNOME Software) используют его для установки софта, а на серверах PackageKit часто появляется как зависимость Cockpit. Авторизация делегируется polkit.Процесс установки пакета выглядит так:
- Клиент создаёт объект транзакции через D-Bus
- Вызывает метод
InstallFiles(flags, [path]) - PackageKit проверяет авторизацию через polkit
- При успешной авторизации планировщик выполняет операцию от root
flags - битовое поле, управляющее поведением транзакции. Значения SIMULATE и ONLY_DOWNLOAD заставляют PackageKit пропустить проверку polkit полностью - эти операции считаются безопасными: симуляция не модифицирует систему, скачивание без установки тоже. Звучит логично, правда? А теперь смотрим, где это ломается.Три бага в pk-transaction.c
Уязвимость классифицирована как CWE-367 (Time-of-check Time-of-use Race Condition). Три дефекта вsrc/pk-transaction.c складываются в эксплуатируемую цепочку:Баг 1: безусловная перезапись флагов (строка 4036).
InstallFiles() записывает переданные клиентом флаги в transaction->cached_transaction_flags без проверки текущего состояния транзакции. Повторный вызов перезаписывает флаги даже когда транзакция уже авторизована и работает в состоянии RUNNING.Баг 2: тихое отклонение обратных переходов (строки 873–882).
pk_transaction_set_state() молча отбрасывает обратные переходы состояний (например, RUNNING → WAITING_FOR_AUTH), но перезапись флагов из первого бага к этому моменту уже произошла. Транзакция продолжает работу с испорченными флагами - ошибки нет, лог чистый. Красота.Баг 3: позднее чтение флагов (строки 2273–2277). Планировщик читает
cached_transaction_flags в момент dispatch, а не в момент авторизации. Если флаги перезаписаны между авторизацией и выполнением - бэкенд видит флаги атакующего, а не те, под которые выдавалось разрешение.Решающий фактор - приоритеты GLib main loop. D-Bus-сообщения диспетчеризуются с более высоким приоритетом, чем idle-коллбэки планировщика. Атакующий отправляет первый
InstallFiles(SIMULATE, [package]) - polkit не нужен, флаг SIMULATE кешируется. Немедленно за ним - второй InstallFiles(0, [package]), перезаписывающий флаги на 0 (без safety-флагов). Из-за приоритетов event loop второй D-Bus-вызов обрабатывается до idle-коллбэка - и планировщик выполняет реальную установку без авторизации.AC:L в CVSS-векторе нетипичен для race condition - обычно гонки условий получают AC:H. Здесь низкая сложность обусловлена именно детерминистическим порядком обработки событий в GLib. Это не классическая гонка «кто успеет» - это гарантированная последовательность, которую диктует сам event loop.
Эксплуатация Pack2TheRoot: privilege escalation linux от пользователя до root
Требования к окружению
| Параметр | Значение |
|---|---|
| ОС | Ubuntu Desktop 18.04+, Debian Trixie 13.4, Fedora 43, RockyLinux 10.1 (дефолтная установка) |
| PackageKit | >= 1.0.2 и <= 1.3.4 |
| Привилегии | Любой непривилегированный пользователь с shell |
| Сеть | Доступ к репозиторию пакетов или наличие локального .rpm/.deb |
| RAM/CPU | Минимальные (эксплойт тривиален по ресурсам) |
Fingerprinting уязвимой системы
Преж
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Обнаружение эксплуатации и индикаторы компрометации
При всей скорости эксплуатации Pack2TheRoot оставляет характерный след. После гонки демон PackageKit попадает в assertion failure:
Код:
PackageKit:ERROR:../src/pk-transaction.c:514:pk_transaction_finished_emit:
assertion failed: (!transaction->priv->emitted_finished)
journalctl --no-pager -u packagekit | grep -i emitted_finished. Присутствие этой строки - сильный индикатор эксплуатации CVE-2026-41651. В нормальном режиме работы PackageKit не падает с этим assertion. Если видите его в логах - это не «демон глюканул», это кто-то уже побывал на хосте.Дополнительные индикаторы для SOC:
- Неожиданная установка пакетов без записи в polkit auth log
- Новые SUID-бинари или изменения в
/etc/sudoersпосле крэша PackageKit - Аномальные пакеты в истории установки:
dnf historyилиgrep " install " /var/log/apt/history.log - Серия stop/start PackageKit в systemd journal без видимой причины
emitted_finished в journald с привязкой к unit packagekit.service. По данным Elastic Security Labs, детекция privilege escalation через Linux process capabilities требует мониторинга D-Bus-взаимодействий - для Pack2TheRoot критичен именно крэш демона как маркер успешной эксплуатации.Митигация CVE-2026-41651
Патч. Уязвимость исправлена в PackageKit 1.3.5. Обновления доступны с 22 апреля 2026 для Debian, Ubuntu (через Launchpad) и Fedora 42–44 (PackageKit-1.3.4-3). Приоритет - штатное обновление дистрибутива.Workaround для систем без доступного патча - polkit-правило, запрещающее установку пакетов непривилегированным пользователям. Файл размещается в
/etc/polkit-1/rules.d/49-workaround-cve-2026-41651.rules:
JavaScript:
// CVE-2026-41651 workaround: deny PackageKit install без root
polkit.addRule(function(action, subject) {
if (action.id.indexOf("org.freedesktop.packagekit.package-") === 0 ||
action.id === "org.freedesktop.packagekit.system-update") {
if (subject.uid === 0) return polkit.Result.YES;
return polkit.Result.NO;
}
});
sudo apt/dnf install из терминала не затрагивается, поскольку не использует PackageKit. На рабочих станциях разработчиков может вызвать возмущение, но root через scriptlet вызовет больше.Чеклист для сисадмина:
- Проверить версию PackageKit на всех Linux-хостах
- Обновить PackageKit до 1.3.5+ через штатный менеджер пакетов
- На хостах без патча - развернуть polkit workaround
- Проверить логи на IoC:
journalctl -u packagekit | grep emitted_finished - Аудит установленных пакетов - искать аномалии в
dnf history/apt log - На серверах с Cockpit - проверить PackageKit как зависимость
Уязвимости пакетных менеджеров Linux в 2026: не только PackageKit
Pack2TheRoot - не изолированный случай. Пакетные менеджеры и связанные подсистемы в 2026 году стали заметным вектором локального повышения привилегий linux.CVE-2026-3888: snapd и systemd-tmpfiles
Qualys Threat Research Unit обнаружили LPE в дефолтных установках Ubuntu Desktop 24.04+. CVE-2026-3888 (CVSS 7.8, HIGH, CWE-268) эксплуатирует взаимодействие двух компонентов: snap-confine (setuid-root бинарь, строящий sandbox для snap-приложений) и systemd-tmpfiles (автоматическая очистка временных файлов по расписанию).Атака: systemd-tmpfiles по таймеру удаляет директорию
/tmp/.snap (30 дней в Ubuntu 24.04, 10 дней в более поздних версиях). Атакующий пересоздаёт директорию с вредоносным содержимым. При следующей инициализации sandbox snap-confine bind-mount'ит эти файлы от root.Принципиальное отличие от Pack2TheRoot - временное окно: ожидание cleanup-цикла 10–30 дней делает эксплуатацию непрактичной в рамках типового пентеста. Это отражено в AC:H (Attack Complexity: High) и крайне низком EPSS 0.0001. В терминологии MITRE ATT&CK использование запланированного cleanup-цикла systemd-tmpfiles концептуально близко к Scheduled Task/Job (T1053), конкретно Cron (T1053.003) - таймер как элемент цепочки атаки на Linux-платформе.
Snap-confine как setuid-root бинарь также относится к технике Setuid and Setgid (T1548.001, privilege-escalation) - это Linux-специфичный вектор, не применимый к Windows.
Выбор LPE-вектора: decision tree
При планировании privilege escalation linux на пентесте - последовательность проверок для выбора оптимального вектора:| Условие | Вектор | Сложность | Детектируемость |
|---|---|---|---|
| Ядро >= 4.17, algif_aead доступен | Copy Fail (CVE-2026-31431) | Низкая, PoC 732 байта | Низкая (page cache) |
| PackageKit 1.0.2–1.3.4 | Pack2TheRoot (CVE-2026-41651) | Низкая, секунды | Высокая (крэш демона) |
| snap-confine + systemd-tmpfiles | CVE-2026-3888 | Высокая, 10–30 дней | Средняя |
sudo -l выдаёт привилегированные бинари | GTFOBins (apt, dpkg, dnf) | Зависит от конфигурации | Средняя |
| SUID-бинари с capabilities | Capabilities abuse | Зависит от бинаря | Низкая-средняя |
- Проверь ядро -
uname -r. Если >= 4.17 и algif_aead доступен (lsmod | grep algif_aead) - Copy Fail приоритетнее: детерминистический, низкая детектируемость, CISA KEV. EPSS 0.0257 (percentile 0.8571) - значительно выше медианы, что подтверждает активную эксплуатацию - Проверь PackageKit -
rpm -qa | grep -i packagekit/dpkg -l | grep -i packagekit. Версия в диапазоне - Pack2TheRoot, быстро и надёжно, но оставляет IoC - snap установлен? - CVE-2026-3888 возможен, но ожидание 10–30 дней в рамках пентеста обычно неприемлемо. Разве что у вас бессрочный контракт (и бывает же такое)
- Классические вектора -
sudo -l,find / -perm -4000 2>/dev/nullдля SUID (T1548.001),getcap -r / 2>/dev/nullдля capabilities. GTFOBins (gtfobins.github.io) содержит готовые абьюзы дляapt,dpkgиdnfесли они в sudo или SUID-конфигурации
linpeas на чистом хосте - в знании того, что пакетный менеджер вообще бывает вектором.Pack2TheRoot изменил мой подход к LPE-фазе на пентестах. Раньше PackageKit попадал в категорию «системный сервис, не интересно» - наравне с NetworkManager или udisks2. Теперь любой D-Bus-сервис, работающий от root и принимающий вызовы от непривилегированных пользователей, автоматически попадает в scope проверки. Deutsche Telekom Red Team нашли CVE-2026-41651 с помощью AI-ассистированного исследования (Claude Opus) - и это показательный момент: LLM хорошо работают именно по таким задачам, как перебор state machine transitions и поиск гонок условий в event loop, где человек работает медленно.
Прогноз: в ближайший год увидим больше CVE в D-Bus-сервисах. polkit, udisks2, NetworkManager - архитектурно аналогичные цели с тем же паттерном: root-привилегированный демон, D-Bus-интерфейс, polkit-авторизация с флагами для «безопасных» операций. Если на пентесте вы ограничиваетесь
sudo -l и find / -perm -4000 - вы пропускаете целый класс LPE-векторов, который пакетные менеджеры сделали очевидным в 2026 году. Двенадцать лет TOCTOU в сервисе, через который GUI ставит пакеты - и никто не смотрел, пока Red Team не натравил LLM на исходники. Попробуйте на следующем проекте начать LPE-фазу с systemctl list-units --type=service | grep -i package - возможно, удивитесь.