## https://sploitus.com/exploit?id=17DBE2B1-DEF0-51A5-B745-0096B4F01603
# Pack2TheRoot Lab โ CVE-2026-41651
A Dockerised, CTF-style local-privilege-escalation lab built around the
**Pack2TheRoot** advisory (`CVE-2026-41651`), a 12-year-old flaw in the
[PackageKit](https://github.com/PackageKit/PackageKit) daemon disclosed
by Deutsche Telekom's Red Team on **22 April 2026**.
> **Read me first.** The actual Pack2TheRoot primitive is **embargoed**
> by the discoverer to let distribution patches propagate. The challenge
> in this lab exercises the **same vulnerability class** (permissive
> polkit on a PackageKit D-Bus action โ unsigned-RPM install โ root
> code execution via `%post` scriptlet) using a publicly-documented
> primitive. Players get the same defensive and offensive reflexes
> without touching the embargoed root cause.
---
## 1. What you get
| Container | Port | Role | Exploit outcome |
|---|---|---|---|
| `pack2theroot-vuln` | `tcp/2222` (ssh) | PackageKit โค 1.3.4 + permissive polkit rule | **Root** via crafted RPM |
| `pack2theroot-patched` | `tcp/2223` (ssh) | Same, but polkit hardened | Exploit fails |
Plus:
- A player-facing challenge brief ([`docs/CHALLENGE.md`](docs/CHALLENGE.md))
- Progressive hints ([`docs/HINTS.md`](docs/HINTS.md))
- Full walkthrough & flag ([`docs/SOLUTION.md`](docs/SOLUTION.md))
- Defender tooling: version check, IOC monitor, side-by-side compare,
interim polkit mitigation script.
## 2. Vulnerability summary
| Field | Value |
|---|---|
| CVE | `CVE-2026-41651` |
| Name | Pack2TheRoot |
| Class | Local Privilege Escalation |
| Component | `PackageKit` daemon |
| Vulnerable range | `>= 1.0.2` and ` pack2theroot-lab
cd pack2theroot-lab
docker compose build
docker compose up -d
```
Then play:
```bash
ssh labuser@localhost -p 2222 # password: labuser
# then work through docs/CHALLENGE.md
```
The flag is at `/root/flag.txt` (mode `0400 root:root`). Submission
format:
```
PACK2THEROOT{...}
```
Tear down with:
```bash
docker compose down -v
```
## 4. Repository layout
```
pack2theroot-lab/
โโโ README.md
โโโ docker-compose.yml
โโโ docs/
โ โโโ CHALLENGE.md # player brief
โ โโโ HINTS.md # 4 collapsible hints
โ โโโ SOLUTION.md # full walkthrough + flag
โ โโโ references.md # primary and secondary sources
โ โโโ threat-model.md # attacker/defender assumptions
โโโ vulnerable/
โ โโโ Dockerfile
โ โโโ entrypoint.sh
โ โโโ policy/
โ โโโ 10-pack2theroot-lab-misconfig.rules # the challenge
โโโ patched/
โ โโโ Dockerfile
โ โโโ entrypoint.sh
โ โโโ local/ # drop a 1.3.5 backport RPM here (optional)
โ โโโ policy/
โ โโโ 10-pack2theroot-lab-hardened.rules # the fix
โโโ scripts/
โโโ 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
โโโ exploit-check.sh # placeholder until PoC is public
```
## 5. Playing the challenge
See [`docs/CHALLENGE.md`](docs/CHALLENGE.md). TL;DR:
1. SSH in as `labuser` (password `labuser`).
2. Recon the polkit rules. One of them is way too permissive.
3. Build a malicious RPM (`rpm-build`, `rpmdevtools` are installed).
4. Install it with `pkcon install-local --allow-untrusted`.
5. The `%post` scriptlet runs as root. Read `/root/flag.txt`.
Stuck? [`docs/HINTS.md`](docs/HINTS.md) has four progressively more
explicit hints, each hidden behind a spoiler tag. Only open
[`docs/SOLUTION.md`](docs/SOLUTION.md) after you've either solved it or
genuinely need the write-up.
## 6. Running the defender tooling
Inside either container, as any user:
```bash
/opt/lab/check-version.sh # VULNERABLE or PATCHED verdict
/opt/lab/check-preconditions.sh # exposure self-check
/opt/lab/monitor-ioc.sh # tail the journal for the IOC
```
From the host, side-by-side:
```bash
./scripts/compare-env.sh
```
Apply the interim polkit mitigation to a hardened container:
```bash
docker exec pack2theroot-vuln /opt/lab/apply-polkit-mitigation.sh
# Then retry the exploit โ should now fail.
```
## 7. Patched image โ backport status
On disclosure day, PackageKit 1.3.5 may not yet be in the stock
Fedora/Ubuntu repositories. The `patched` image handles this honestly:
- It installs whatever PackageKit the distro currently ships.
- It surfaces a clear banner
(`/etc/pack2theroot-banner`) stating whether the installed version is
the real patch or just a distro placeholder.
- Regardless of version, it ships a **hardened polkit rule** that
blocks the authenticationless install path. This alone prevents the
lab's exploit from succeeding.
To build a version-complete patched image once your distro publishes
the backport, drop the RPM(s) into `patched/local/` and rebuild:
```bash
docker compose build --build-arg USE_LOCAL_RPM=1 patched
```
## 8. Safety and responsible use
- The challenge uses a **deliberately permissive polkit rule** as the
vulnerable primitive. This is a well-documented misconfiguration
pattern, independent of the embargoed Pack2TheRoot root cause.
- Do **not** ship either container image on a shared Docker host with
untrusted users.
- Do **not** publish a weaponised CVE-2026-41651 PoC before Telekom
releases their technical write-up.
- When the embargo lifts, replace `scripts/exploit-check.sh` in your
fork with the actual primitive. Keep it scoped to the vulnerable
container only.
- The SSH password (`labuser`) is intentionally weak. Never reuse it on
anything real.
## 9. References
Primary sources:
- Telekom Security advisory โ
- NVD โ `CVE-2026-41651`:
- Upstream fix โ PackageKit 1.3.5:
See [`docs/references.md`](docs/references.md) for secondary coverage
and distribution trackers.
## 10. License
MIT โ add a `LICENSE` file in your fork before publishing.