
CTFスタイルのDockerラボ CVE-2026-41651(Pack2TheRoot)用:PackageKitのpermissive-polkitによるローカル権限昇格
Docker化されたCTF形式のローカル権限昇格ラボです。PackageKit デーモンに存在する12年前の脆弱性である Pack2TheRoot アドバイザリ(CVE-2026-41651)を題材としており、ドイツテレコムのレッドチームによって 2026年4月22日 に公開されました。
このラボには 3つのコンテナ が含まれています:寛容なpolkit設定のCTFチャレンジ、堅牢化された比較対象、そして脆弱なPackageKitをソースからビルドして実際のCVE-2026-41651の根本原因エクスプロイトを実行する 完全なTOCTOUエクスプロイト再現 です。
| コンテナ | ポート | 役割 | エクスプロイト結果 |
|---|---|---|---|
pack2theroot-vuln | tcp/2222 (ssh) | PackageKit ≤ 1.3.4 + 寛容なpolkitルール | 細工されたRPMによる root 権限取得 |
pack2theroot-patched | tcp/2223 (ssh) | 同一構成だがpolkitを堅牢化 | エクスプロイト失敗 |
pack2theroot-exploit | — | ソースからビルドした脆弱なPackageKit 1.3.4 | TOCTOU D-Busレースによる root 権限取得 |
さらに:
docs/CHALLENGE.md)docs/HINTS.md)docs/SOLUTION.md)docs/diagrams/)pk-transaction.c における3つの連鎖バグこのエクスプロイトは、同じトランザクションに対して2つの非同期D-Bus InstallFiles() 呼び出しを送信します:最初に SIMULATE(polkitをバイパスし、GLibアイドルコールバックをキューに追加)、その後すぐに NONE + 悪意のあるパッケージ(アイドルが発火する前にキャッシュされたフラグ/パスを上書き)。GLibの優先順位付けにより、両方のD-Busメッセージがアイドルコールバックの前にディスパッチされることが保証されます — つまりこれはタイミングレースではなく決定的に動作します。
既知のIOC(アドバイザリより):
journalctl --no-pager -u packagekit | grep -iE 'emitted_finished|pk_transaction_finished_emit|pk-transaction\.c:514'
git clone https://github.com/dinosn/pack2theroot-lab.git
cd pack2theroot-lab
docker compose build
docker compose up -d
ssh labuser@localhost -p 2222 # パスワード: labuser
# その後 docs/CHALLENGE.md に従って進める
フラグは /root/flag.txt(モード 0400 root:root)にあります。形式:
PACK2THEROOT{...}
# ビルドして実行 — 自動モードでエクスプロイトを即座に実行:
docker compose run --rm exploit
# または手動モード:
docker compose run --rm --entrypoint /entrypoint.sh exploit
# コンテナ内で:
su - victim -c /exploit/cve-2026-41651
このエクスプロイトはC言語で2つの .deb パッケージをビルドし(外部ツール不要)、2回のD-Busレースを送信して、/tmp/.suid_bash にSUID bashを作成します。完全な技術的ウォークスルーは docs/SOLUTION.md を参照してください。
終了:
docker compose down -v
pack2theroot-lab/
├── README.md
├── docker-compose.yml
├── docs/
│ ├── CHALLENGE.md # プレイヤー向け概要
│ ├── HINTS.md # 段階的なヒント(両経路)
│ ├── SOLUTION.md # 完全なウォークスルー + フラグ
│ ├── references.md # 一次および二次情報源
│ ├── threat-model.md # 攻撃者/防御者の前提条件
│ └── diagrams/ # エクスプロイトフローのSVG図解
│ ├── 01-docker-build.svg
│ ├── 02-container-startup.svg
│ ├── 03-exploit-execution.svg
│ ├── 04-dbus-race-sequence.svg
│ ├── 05-attack-overview.svg
│ └── 06-auto-mode-full-run.svg
├── exploit/
│ ├── Dockerfile # 脆弱なPackageKit 1.3.4をソースからビルド
│ ├── entrypoint.sh # dbus + polkitd + packagekitd を起動
│ ├── Makefile
│ └── src/
│ └── cve-2026-41651.c # TOCTOUエクスプロイト(公開PoC)
├── vulnerable/
│ ├── Dockerfile
│ ├── entrypoint.sh
│ └── policy/
│ └── 10-pack2theroot-lab-misconfig.rules # CTFチャレンジ
├── patched/
│ ├── Dockerfile
│ ├── entrypoint.sh
│ ├── local/ # 1.3.5バックポートRPMをここに配置(任意)
│ └── policy/
│ └── 10-pack2theroot-lab-hardened.rules # 修正版
└── scripts/
├── exploit-check.sh # バージョン、polkit、D-Bus、IOCを確認
├── check-version.sh # VULNERABLE vs PATCHED 判定
├── check-preconditions.sh # pkcon / polkit / D-Bus の健全性確認
├── monitor-ioc.sh # アドバイザリのIOCをjournalで監視
├── compare-env.sh # 両コンテナを差分比較
└── apply-polkit-mitigation.sh # 未パッチホスト向け暫定堅牢化
docs/diagrams/ ディレクトリにはエクスプロイトフローを示すSVG図が含まれています。任意のブラウザで開いてください:
docs/CHALLENGE.md を参照してください。要約:
labuser としてSSH接続(パスワード labuser)。rpm-build、rpmdevtools がインストール済み)。pkcon install-local --allow-untrusted でインストールする。%post スクリプトレットがrootとして実行されます。/root/flag.txt を読み取ってください。行き詰まった? docs/HINTS.md には段階的に具体的なヒントがあります。docs/SOLUTION.md は、解けた後か、本当に解説が必要な場合にのみ開いてください。
どちらかのコンテナ内で、任意のユーザーとして:
/opt/lab/check-version.sh # VULNERABLE または PATCHED 判定
/opt/lab/check-preconditions.sh # 露出の自己チェック
/opt/lab/exploit-check.sh # バージョン + polkit + D-Bus + IOC確認
/opt/lab/monitor-ioc.sh # IOCをjournalで監視
ホストからサイドバイサイドで:
./scripts/compare-env.sh
脆弱なコンテナに暫定polkit緩和を適用:
docker exec pack2theroot-vuln /opt/lab/apply-polkit-mitigation.sh
# その後エクスプロイトを再試行 — 失敗するはずです。
patched イメージはPackageKitのバージョン状況を正直に扱います:
/etc/pack2theroot-banner)を表示します。ディストリビューションがバックポートを公開したら、バージョン完全なパッチ済みイメージをビルドするには、RPMを patched/local/ に配置して再ビルドします:
docker compose build --build-arg USE_LOCAL_RPM=1 patched
--privileged が必要です。隔離された環境でのみ実行してください。labuser)は意図的に弱いものです。再利用しないでください。一次情報源:
CVE-2026-41651:
https://nvd.nist.gov/vuln/detail/CVE-2026-4165176cfb675:
https://github.com/PackageKit/PackageKit/commit/76cfb675fb31acc3ad5595d4380bfff56d2a8697二次的な報道やディストリビューションの追跡状況については docs/references.md を参照してください。
MIT — LICENSE を参照してください。
| フィールド | 値 |
|---|
| CVE | CVE-2026-41651 |
| 名称 | Pack2TheRoot |
| 分類 | ローカル権限昇格(TOCTOU / CWE-367) |
| コンポーネント | PackageKit デーモン(pk-transaction.c) |
| 影響を受ける範囲 | >= 1.0.2 かつ <= 1.3.4(12年間のリリース) |
| 修正バージョン | PackageKit 1.3.5(コミット 76cfb675、2026-04-22リリース) |
| CVSS 3.1 | 8.8 (HIGH) — AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |
| 前提条件 | PackageKitを実行しているホスト上のローカル非特権シェル |
| 発見者 | Deutsche Telekom Security GmbH — レッドチーム |
| バグ | 場所 | 影響 |
|---|
| BUG 1 | InstallFiles()(約4036行目) | cached_transaction_flags と cached_full_paths を無条件に上書き — 状態ガードなし |
| BUG 2 | pk_transaction_set_state()(約876〜881行目) | 後方状態遷移をエラーにせず黙って破棄 — フラグはすでに汚染済み |
| BUG 3 | pk_transaction_run()(約2273〜2277行目) | 認可時ではなくディスパッチ時に cached_transaction_flags を読み取る |
| バイパス | SIMULATEフラグ(約2893〜2900行目) | PK_TRANSACTION_FLAG_SIMULATE(0x4)がpolkitを完全にバイパス |
| 図 | 説明 |
|---|
01-docker-build.svg | 2段階Dockerビルド — 脆弱なPackageKitのコンパイル |
02-container-startup.svg | コンテナ起動 — dbus、polkitd、packagekitdの起動 |
03-exploit-execution.svg | 注釈付きフェーズによるステップバイステップのエクスプロイト出力 |
04-dbus-race-sequence.svg | D-Busシーケンス図 — BUG 1/2/3がGLib優先順位と連鎖する仕組み |
05-attack-overview.svg | 高レベル攻撃フロー:タイムライン付きの攻撃者 vs システム |
06-auto-mode-full-run.svg | 完全な --auto モードターミナル — コンテナ起動からrootシェルまで |