dinosn/pack2theroot-lab
GitHub: dinosn/pack2theroot-lab
一个基于 Docker 的 CTF 风格实验环境,用于复现、学习 PackageKit CVE-2026-41651 本地权限提升漏洞(TOCTOU 竞态条件)及其防御方法。
Stars: 2 | Forks: 0
# Pack2TheRoot 实验环境 — CVE-2026-41651
一个围绕 **Pack2TheRoot** 公告 (`CVE-2026-41651`) 构建的 Docker 化、CTF 风格的本地权限提升实验环境。这是一个在 [PackageKit](https://github.com/PackageKit/PackageKit) 守护进程中发现长达 12 年之久的漏洞,由德国电信(Deutsche Telekom)红队于 **2026 年 4 月 22 日** 披露。
该实验环境包含 **三个容器**:一个带有宽松 polkit 规则的 CTF 挑战环境,一个用于对比的加固目标,以及一个**完整的 TOCTOU 漏洞复现环境**(从源码构建受漏洞影响的 PackageKit 并运行真实的 CVE-2026-41651 根因漏洞利用程序)。
## 1. 你将获得什么
| 容器 | 端口 | 角色 | 漏洞利用结果 |
|---|---|---|---|
| `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/CHALLENGE.md))
- 循序渐进的提示 ([`docs/HINTS.md`](docs/HINTS.md))
- 完整的通关步骤与 Flag ([`docs/SOLUTION.md`](docs/SOLUTION.md))
- 漏洞利用流程的可视化图表 ([`docs/diagrams/`](docs/diagrams/))
- 防御方工具:版本检查、IOC 监控、横向对比、临时 polkit 缓解脚本。
## 2. 漏洞概述
| 字段 | 值 |
|---|---|
| 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 的主机上拥有本地无特权 shell |
| 发现者 | 德国电信安全有限公司 (Deutsche Telekom Security GmbH) — 红队 |
### 根本原因 — `pk-transaction.c` 中串联的三个 Bug
| Bug | 位置 | 效果 |
|---|---|---|
| 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 |
该漏洞利用在同一个事务上发送两个异步 D-Bus `InstallFiles()` 调用:第一个带有 `SIMULATE` 标志(绕过 polkit,排队一个 GLib idle 回调),然后立即带有 `NONE` 标志 + 恶意软件包发送第二个调用(在 idle 回调触发之前覆盖缓存的标志/路径)。GLib 的优先级排序保证两个 D-Bus 消息都在 idle 回调之前调度 — 这使其成为确定性的,而非依赖于时间的竞争。
已知的 IOC (来自安全公告):
```
journalctl --no-pager -u packagekit | grep -iE 'emitted_finished|pk_transaction_finished_emit|pk-transaction\.c:514'
```
## 3. 快速开始
```
git clone https://github.com/dinosn/pack2theroot-lab.git
cd pack2theroot-lab
docker compose build
docker compose up -d
```
### CTF 挑战 (宽松 polkit 路径)
```
ssh labuser@localhost -p 2222 # password: labuser
# 然后按照 docs/CHALLENGE.md 进行操作
```
Flag 位于 `/root/flag.txt` (权限 `0400 root:root`)。格式:
`PACK2THEROOT{...}`
### TOCTOU 漏洞利用复现 (真实的 CVE 根本原因)
```
# 构建并运行 — auto-mode 会立即执行 exploit:
docker compose run --rm exploit
# 或者 manual mode:
docker compose run --rm --entrypoint /entrypoint.sh exploit
# 然后在 container 内部:
su - victim -c /exploit/cve-2026-41651
```
该漏洞利用程序使用 C 语言构建了两个 `.deb` 软件包(无需外部工具),发送双调用 D-Bus 竞争,并在 `/tmp/.suid_bash` 处创建了一个 SUID bash。完整的技术分析请参见 [docs/SOLUTION.md](docs/SOLUTION.md)。
销毁环境:
```
docker compose down -v
```
## 4. 仓库布局
```
pack2theroot-lab/
├── README.md
├── docker-compose.yml
├── docs/
│ ├── CHALLENGE.md # player brief
│ ├── HINTS.md # progressive hints (both paths)
│ ├── SOLUTION.md # full walkthrough + flag
│ ├── references.md # primary and secondary sources
│ ├── threat-model.md # attacker/defender assumptions
│ └── diagrams/ # SVG visual diagrams of the exploit flow
│ ├── 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 # builds vulnerable PackageKit 1.3.4 from source
│ ├── entrypoint.sh # starts dbus + polkitd + packagekitd
│ ├── Makefile
│ └── src/
│ └── cve-2026-41651.c # the TOCTOU exploit (public PoC)
├── vulnerable/
│ ├── Dockerfile
│ ├── entrypoint.sh
│ └── policy/
│ └── 10-pack2theroot-lab-misconfig.rules # CTF challenge
├── patched/
│ ├── Dockerfile
│ ├── entrypoint.sh
│ ├── local/ # drop a 1.3.5 backport RPM here (optional)
│ └── policy/
│ └── 10-pack2theroot-lab-hardened.rules # the fix
└── scripts/
├── exploit-check.sh # checks version, polkit, D-Bus, IOCs
├── check-version.sh # VULNERABLE vs PATCHED verdict
├── check-preconditions.sh # pkcon / polkit / D-Bus sanity
├── monitor-ioc.sh # tail journal for the advisory IOC
├── compare-env.sh # diff both containers
└── apply-polkit-mitigation.sh # interim hardening for unpatched hosts
```
## 5. 可视化图表
[`docs/diagrams/`](docs/diagrams/) 目录包含展示漏洞利用流程的 SVG 图表。可在任何浏览器中打开它们:
| 图表 | 描述 |
|---|---|
| `01-docker-build.svg` | 两阶段 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 shell |
## 6. 游玩 CTF 挑战
参见 [`docs/CHALLENGE.md`](docs/CHALLENGE.md)。简要步骤如下:
1. 以 `labuser` 身份通过 SSH 登录(密码 `labuser`)。
2. 侦察 polkit 规则。其中有一条过于宽松。
3. 构造一个恶意 RPM(`rpm-build`、`rpmdevtools` 已安装)。
4. 使用 `pkcon install-local --allow-untrusted` 安装它。
5. 其 `%post` 脚本小程序会以 root 身份运行。读取 `/root/flag.txt`。
卡住了?[`docs/HINTS.md`](docs/HINTS.md) 提供了循序渐进的明确提示。只有在你已解决问题或确实需要参考解题过程时,才打开 [`docs/SOLUTION.md`](docs/SOLUTION.md)。
## 7. 运行防御工具
在任一容器内,以任何用户身份执行:
```
/opt/lab/check-version.sh # VULNERABLE or PATCHED verdict
/opt/lab/check-preconditions.sh # exposure self-check
/opt/lab/exploit-check.sh # version + polkit + D-Bus + IOC check
/opt/lab/monitor-ioc.sh # tail the journal for the IOC
```
从宿主机横向对比执行:
```
./scripts/compare-env.sh
```
将临时 polkit 缓解措施应用于受漏洞影响的容器:
```
docker exec pack2theroot-vuln /opt/lab/apply-polkit-mitigation.sh
# 然后重试 exploit — 现在应该会失败。
```
## 8. 已修补镜像 — 回溯移植状态
`patched` 镜像能如实反映 PackageKit 的版本状态:
- 它会安装发行版当前提供的任何 PackageKit 版本。
- 它会通过一个清晰的横幅 (`/etc/pack2theroot-banner`) 标明安装的版本是真正的补丁还是发行版的占位符。
- 无论版本如何,它都会附带一个**加固的 polkit 规则**,以阻止无认证安装路径。
要在你的发行版发布回溯移植补丁后构建一个版本完整的已修补镜像,请将 RPM 包放入 `patched/local/` 并重新构建:
```
docker compose build --build-arg USE_LOCAL_RPM=1 patched
```
## 9. 安全与负责任的使用
- 在拥有不受信任用户的共享 Docker 宿主机上,**不要**发布上述任何容器镜像。
- 漏洞利用容器需要 `--privileged` 以运行完整的 dbus/polkitd/packagekitd 栈。请仅在隔离环境中运行它。
- SSH 密码 (`labuser`) 被故意设置为弱密码。切勿重复使用该密码。
- 仅限用于授权的防御性研究、教育和渗透测试。
## 10. 参考
主要来源:
- 德国电信安全公告 —
- NVD — `CVE-2026-41651`:
- 上游修复 — PackageKit 1.3.5:
- 修复提交 — `76cfb675`:
- 公开 PoC — Vozec:
次要报道和发行版追踪请参见 [`docs/references.md`](docs/references.md)。
## 11. 许可证
MIT — 详见 [LICENSE](LICENSE)。
标签:CSV导出, CVE-2026-41651, CWE-367, D-Bus, Docker, GitHub Advanced Security, OPA, PackageKit, Polkit, RPM, TOCTOU, Web截图, Web报告查看器, 安全加固, 安全防御评估, 容器安全, 数据展示, 本地提权, 漏洞复现, 竞态条件, 红队, 网络安全, 请求拦截, 隐私保护, 靶场