Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-41651 — Local privilege escalation via TOCTOU race condition in PackageKit's. | Kitploit
Tools/GitHubGitHub/gbuyssens/cve-2026-41651
Privilege EscalationVulnerability AnalysisExploitationCTFPenetration Testing
GitHubgbuyssens/cve-2026-41651

CVE-2026-41651

Local privilege escalation via TOCTOU race condition in PackageKit's.

View Repository
31 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-41651

root@kitploit:~
CVSS 3.x : 7.8 HIGH
CWE      : CWE-367 (Time-of-Check Time-of-Use)
Fix      : PackageKit 1.3.5+
Affects  : PackageKit 1.0.2 – 1.3.4

Local privilege escalation via TOCTOU race condition in PackageKit's D-Bus transaction handler.
Any unprivileged local user can install arbitrary packages as root — no authentication beyond having a local session.

Lab / authorized testing only (HTB, CTF, engagement with written scope).


Usage

root@kitploit:~
python3 exploit.py

That's it. Drops /tmp/.suid_bash, then exec into a root shell.

Custom SUID path or timeout:

root@kitploit:~
SUID_BIN=/dev/shm/.sh TIMEOUT=90 python3 exploit.py

Requirements

root@kitploit:~
apt install python3-gi dpkg-dev

The exploit builds two .deb packages at runtime — no compiler needed.


Root cause

Three bugs in src/pk-transaction.c chain together:

Bug 1 — Unconditional flag overwrite

InstallFiles() overwrites cached_transaction_flags and cached_full_paths with no state check. A second D-Bus call on the same transaction blindly replaces them — even while the transaction is already running.

Bug 2 — Silent state-machine guard

pk_transaction_set_state() rejects illegal backward transitions (RUNNING→READY, etc.) without rolling back the overwritten flags from Bug 1. The corrupted flags persist.

Bug 3 — Late flag read

pk_transaction_run() reads cached_transaction_flags at dispatch time (GLib idle), not at authorization time. The backend sees the attacker's flags.

Bonus — SIMULATE bypasses polkit

Setting PK_TRANSACTION_FLAG_SIMULATE (0x4) skips the polkit authorization check entirely. Call 1 gets authorized with no user interaction.


Attack chain

root@kitploit:~
Attacker                         packagekitd
   │                                  │
   │  CreateTransaction()             │  state = NEW
   │─────────────────────────────────►│
   │                                  │
   │  InstallFiles(SIMULATE, dummy)   │  polkit skipped (SIMULATE)
   │─────────────────────────────────►│  state = READY, idle queued
   │                                  │
   │  InstallFiles(NONE, payload)     │  flags+paths overwritten
   │─────────────────────────────────►│  set_state(WAITING_FOR_AUTH) rejected
   │                                  │  state stays READY (BUG 2)
   │                                  │
   │                      [idle fires]│
   │                                  │  pk_transaction_run() reads NONE (BUG 3)
   │                                  │  → dpkg installs payload as root
   │                                  │  → postinst: chmod +s /tmp/.suid_bash
   │                                  │
   │  execv("/tmp/.suid_bash -p")     │
   │─────────────────────────────────►│  euid=0(root)

Both calls arrive before the GLib idle fires — no race to win, it's deterministic.


Affected systems

Ubuntu Desktop 18.04–26.04, Debian Trixie, Fedora 43, RockyLinux 10.1, and any distro shipping PackageKit 1.0.2–1.3.4 with the daemon active.


Remediation

  1. Upgrade to PackageKit 1.3.5+
  2. Mask the service if upgrade isn't possible: systemctl mask packagekit
  3. The fix adds a state guard: transaction->state != PK_TRANSACTION_STATE_NEW → reject

References

  • NVD — CVE-2026-41651
  • GitHub Advisory — GHSA-f55j-vvr9-69xv
  • Fix commit
Download Tool