CVE-2026-41651 — PackageKit TOCTOU ローカル権限昇格
分類: パープルチーム評価アーティファクト
許可された用途のみ。 本書および付属のテストスクリプトは、書面による許可が得られたシステム上での内部セキュリティ検証のみを目的としています。
悪用の証明

目次
- 脆弱性の概要
- 技術的分析
- テストスクリプトの説明
- 侵害の指標
- 検出ロジック
- 影響を受けるシステムとバージョン
- 修復
- 参考情報
脆弱性の概要
PackageKit は、システムパッケージ管理のための D-Bus 抽象化レイヤーであり、Debian、Ubuntu、Fedora、RHEL、SUSE、Arch Linux の GNOME ベースのデスクトップにデフォルトで存在します。非特権ユーザーに代わって特権パッケージ操作を仲介するため、その認可フローに存在する欠陥は、システム全体に root レベルの影響を及ぼします。
技術的分析
根本原因
pk-transaction.c (1.3.5 より前) は、アクションメソッドの再呼び出しに対する状態ガードを強制していませんでした。D-Bus クライアントは、トランザクションオブジェクトがすでに PK_TRANSACTION_STATE_NEW から遷移した後でも、同じトランザクションオブジェクトに対して InstallFiles (または他のアクションメソッド) を複数回呼び出すことができました。
攻撃チェーン
攻撃者 (非特権)
│
├─① CreateTransaction() → PackageKit がトランザクションオブジェクトパス (tid) を返す
│
├─② InstallFiles(tid, FLAG_SIMULATE=4, [dummy.pkg])
│ PackageKit は dummy.pkg の polkit 認可チェックをキューに入れる。
│ まだインストールは発生しない — SIMULATE はドライラン専用を意味する。
│
├─③ InstallFiles(tid, FLAG_NONE=0, [payload.pkg]) ← TOCTOU ウィンドウ
│ 認可が解決される前に同じ tid で再呼び出し。
│ 脆弱なバージョンはキューに入れられたパラメータを payload.pkg で上書きする。
│
└─④ polkit が認可を付与 (ユーザーが承認、または自動認可)
packagekitd が payload.pkg を root としてインストール。
payload の postinst/post スクリプト: install -m 4755 /bin/bash /tmp/.suid_bash
攻撃者は /tmp/.suid_bash -p を実行 → root シェル。
競合が成立する理由
手順②と③は、同じ接続上でノンブロッキングの非同期 D-Bus 呼び出しとして送信され、単一の書き込みでフラッシュされます。この2つのメッセージは、packagekitd が②を処理して状態機械を進める前に到着するため、TOCTOU ウィンドウが開いたままになります。1.3.5 の修正では、PK_TRANSACTION_STATE_NEW 以降の再呼び出しに対して PK_TRANSACTION_ERROR_INVALID_STATE を返す明示的な状態チェックが追加されています。
テストスクリプトの説明
ファイル: cve-2026-41651-purpleteam.py
言語: Python 3
依存関係: python3-gi (GObject introspection / GLib/Gio バインディング)
目的
準備されたテストシステム上で CVE-2026-41651 の悪用可能性を実証します。目的は以下の通りです:
- インストールされている PackageKit バージョンが脆弱かどうかの検証
- SIEM/EDR チューニングのための現実的な IOC テレメトリの生成
- パッチ適用前後の検出カバレッジのテスト
動作
強化環境への対応
デフォルトで強化されたシステムでは、2つの独立したポイントで悪用をブロックできます。スクリプトは両方を自動的に処理します。
1. 制限的な umask (027 / 077)
プロセスが継承した umask が 027 または 077 の場合、mkdir() は 750 または 700 のディレクトリを生成します。dpkg-deb と rpmbuild の両方がビルドツリー全体を走査する必要があります — いずれかのディレクトリが読み取り不可の場合、ビルドは静かに失敗します。
適用される修正: os.umask(0o022) が、ファイルやディレクトリが作成される前に起動時に呼び出されます。さらに、ビルドツリー内のすべてのディレクトリとファイルは、作成直後に明示的な chmod を受け取ります (ディレクトリとスクリプトは 0o755、データファイルは 0o644)。これにより、継承された umask に関係なく正しいパーミッションが保証されます。
2. /tmp の nosuid / noexec マウントフラグ
| フラグ | 悪用への影響 |
|---|
nosuid | カーネルはそのファイルシステムに保存されたファイルから SUID ビットを静かに削除する — コピーされた bash は root にならない |
noexec | SUID バイナリをまったく実行できない |
適用される修正: 起動時に、_find_suid_dir() が /proc/mounts を読み取り、どちらのフラグも設定されていないファイルシステムが見つかるまで、優先順位に従って候補ディレクトリをテストします。解決されたパスはペイロードの post-install スクリプトに組み込まれ、ポーリングと実行に使用されます。
すべての候補がブロックされている場合、スクリプトは静かに失敗するのではなく、明確なエラーで終了します。
互換性
| ディストリビューションファミリー | パッケージツール | テスト済み |
|---|
| Debian / Ubuntu | dpkg-deb | ✓ |
| RHEL / Fedora |
侵害の指標
IOC は、汎用/インフラストラクチャレベルからスクリプト固有のアーティファクトまでリストされています。汎用の指標に基づく検出は、使用される PoC のバリアントに関係なく、この CVE を捕捉します。
ファイルシステム
プロセスと実行
D-Bus アクティビティ
監査ログパターン
有効化: auditctl -a always,exit -F arch=b64 -S all -F path=/usr/bin/packagekitd
または、以下のルールを /etc/audit/rules.d/ で使用:
# すべての候補ドロップディレクトリでの SUID ファイル作成を検出
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/tmp -k suid_drop
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/var/tmp -k suid_drop
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/dev/shm -k suid_drop
# root 以外による dpkg-deb / rpmbuild を検出
-w /usr/bin/dpkg-deb -p x -k pkg_build_nonroot
-w /usr/bin/rpmbuild -p x -k pkg_build_nonroot
# 任意の候補ドロップディレクトリからの SUID bash 実行を検出
-a always,exit -F arch=b64 -S execve -F dir=/tmp -F uid!=0 -F euid=0 -k priv_esc_drop
-a always,exit -F arch=b64 -S execve -F dir=/var/tmp -F uid!=0 -F euid=0 -k priv_esc_drop
-a always,exit -F arch=b64 -S execve -F dir=/dev/shm -F uid!=0 -F euid=0 -k priv_esc_drop
パッケージマネージャの痕跡
権限昇格の痕跡
検出ロジック
SIEM 疑似ルール (汎用 — すべての CVE-2026-41651 バリアントをカバー)
(
event.category == "process"
AND process.name IN ("dpkg-deb", "rpmbuild")
AND process.user.id != "0"
AND NOT process.parent.name IN ("apt", "apt-get", "dpkg", "rpm", "dnf", "yum", "zypper", "mock", "koji")
)
OR
(
event.category == "file"
AND file.path LIKE "/tmp/%" OR file.path LIKE "/var/tmp/%" OR file.path LIKE "/dev/shm/%"
AND file.owner == "root"
AND (file.mode LIKE "04%")
)
OR
(
event.category == "process"
AND process.name == "bash"
AND process.real_user.id != "0"
AND process.effective_user.id == "0"
AND NOT process.parent.name IN ("sudo", "su", "sshd", "login", "pam")
)
EDR ビヘイビアチェーン
packagekitd
└─ sh / bash (cwd または引数が /tmp、/var/tmp、/dev/shm、または $HOME に一致)
└─ install / cp / chmod (ターゲットが SUID + 所有者 root)
完全なチェーンにフラグを立てます。個々のステップだけでは良性の場合がありますが、packagekitd から SUID 設定コマンドへの親子関係は、選択されたドロップディレクトリに関係なく高信頼度です。パスベースのルールを4つの候補すべてをカバーするように拡張します。
影響を受けるシステムとバージョン
インストール済みバージョンの確認: pkcon backend-details または packagekit --version
報告されたバージョンが ≤ 1.3.4 の場合、脆弱です。
修復
主な対策: PackageKit を 1.3.5 にアップグレードするか、ベンダー固有のバックポートを適用します。
# Debian / Ubuntu
apt update && apt install --only-upgrade packagekit
# Fedora / RHEL
dnf upgrade packagekit
# SUSE
zypper update packagekit
緩和策 (パッチ適用が直ちに不可能な場合):
参考情報
生成日: 2026-04-24 | 更新日: 2026-04-25 | パープルチーム評価 | 内部使用のみ