Статья Privilege escalation Linux через PackageKit: разбор CVE-2026-41651 (Pack2TheRoot)

Сергей Попов

Администратор
30.12.2015
5 712
6 744
Специализация
  1. OSINT
  2. Веб-безопасность
Статус верификации
  1. ✓ Verified
Латунный ключ-скелет вставлен в массивный чёрный замок, корпус которого расколот по линии излома. На лезвии ключа выгравирована надпись CVE-2026-41651.


На внутреннем пентесте корпоративного парка 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), эксплуатация за секунды
ScopeChanged (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.

Процесс установки пакета выглядит так:
  1. Клиент создаёт объект транзакции через D-Bus
  2. Вызывает метод InstallFiles(flags, [path])
  3. PackageKit проверяет авторизацию через polkit
  4. При успешной авторизации планировщик выполняет операцию от 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 без видимой причины
Sigma-правило можно построить на паттерне 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;
    }
});
Побочный эффект: GUI-центры приложений (GNOME Software) перестанут устанавливать пакеты от обычного пользователя. Для корпоративных сред это приемлемый trade-off - установка через sudo apt/dnf install из терминала не затрагивается, поскольку не использует PackageKit. На рабочих станциях разработчиков может вызвать возмущение, но root через scriptlet вызовет больше.

Чеклист для сисадмина:
  1. Проверить версию PackageKit на всех Linux-хостах
  2. Обновить PackageKit до 1.3.5+ через штатный менеджер пакетов
  3. На хостах без патча - развернуть polkit workaround
  4. Проверить логи на IoC: journalctl -u packagekit | grep emitted_finished
  5. Аудит установленных пакетов - искать аномалии в dnf history / apt log
  6. На серверах с 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.4Pack2TheRoot (CVE-2026-41651)Низкая, секундыВысокая (крэш демона)
snap-confine + systemd-tmpfilesCVE-2026-3888Высокая, 10–30 днейСредняя
sudo -l выдаёт привилегированные бинариGTFOBins (apt, dpkg, dnf)Зависит от конфигурацииСредняя
SUID-бинари с capabilitiesCapabilities abuseЗависит от бинаряНизкая-средняя
  1. Проверь ядро - uname -r. Если >= 4.17 и algif_aead доступен (lsmod | grep algif_aead) - Copy Fail приоритетнее: детерминистический, низкая детектируемость, CISA KEV. EPSS 0.0257 (percentile 0.8571) - значительно выше медианы, что подтверждает активную эксплуатацию
  2. Проверь PackageKit - rpm -qa | grep -i packagekit / dpkg -l | grep -i packagekit. Версия в диапазоне - Pack2TheRoot, быстро и надёжно, но оставляет IoC
  3. snap установлен? - CVE-2026-3888 возможен, но ожидание 10–30 дней в рамках пентеста обычно неприемлемо. Разве что у вас бессрочный контракт (и бывает же такое)
  4. Классические вектора - 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-конфигурации
Проверка занимает минуту. Разница между root через Pack2TheRoot за секунды и бесплодным часом 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 - возможно, удивитесь.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab