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 — Proof-of-concept exploit for CVE-2026-41651, a PackageKit TOCTOU local privilege escalation, with technical analysis, detection logic, and remediation guidance. | Kitploit
Tools/GitHubGitHub/baph00met/cve-2026-41651
Privilege EscalationVulnerability AnalysisExploitationPenetration TestingRed TeamingLabs & Practice
GitHubbaph00met/cve-2026-41651

CVE-2026-41651

Proof-of-concept exploit for CVE-2026-41651, a PackageKit TOCTOU local privilege escalation, with technical analysis, detection logic, and remediation guidance.

View Repository
1534 months 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 — PackageKit TOCTOU Local Privilege Escalation

Classification: Purple Team Assessment Artifact
Authorized use only. This document and the accompanying test script are intended solely for internal security validation on systems where written authorization has been obtained.


Proof of Exploitation

Proof of exploitation


Table of Contents

  1. Vulnerability Overview
  2. Technical Analysis
  3. Test Script Description
    • Behavior
    • Hardened Environment Support
    • Compatibility
  4. Indicators of Compromise
    • File System
    • Process & Execution
    • D-Bus Activity
    • Audit Log Patterns
    • Package Manager Artifacts
    • Privilege Escalation Artifacts
  5. Detection Logic
  6. Affected Systems & Versions
  7. Remediation
  8. References

Vulnerability Overview

PackageKit is a D-Bus abstraction layer for system package management, present by default on GNOME-based desktops across Debian, Ubuntu, Fedora, RHEL, SUSE, and Arch Linux. Because it mediates privileged package operations on behalf of unprivileged users, a flaw in its authorization flow has system-wide root impact.


Technical Analysis

Root Cause

pk-transaction.c (pre-1.3.5) did not enforce a state guard on action method re-invocation. A D-Bus client could call InstallFiles (or other action methods) multiple times on the same transaction object after it had already transitioned out of PK_TRANSACTION_STATE_NEW.

Attack Chain

root@kitploit:~
Attacker (unprivileged)
  │
  ├─① CreateTransaction()          → PackageKit returns transaction object path (tid)
  │
  ├─② InstallFiles(tid, FLAG_SIMULATE=4, [dummy.pkg])
  │       PackageKit queues a polkit authorization check for dummy.pkg.
  │       No installation occurs yet — SIMULATE means dry-run only.
  │
  ├─③ InstallFiles(tid, FLAG_NONE=0, [payload.pkg])   ← TOCTOU window
  │       Re-invokes on the same tid before auth resolves.
  │       Vulnerable versions overwrite the queued parameters with payload.pkg.
  │
  └─④ polkit grants authorization (user approved or auto-authorized)
          packagekitd installs payload.pkg as root.
          payload postinst/post script: install -m 4755 /bin/bash /tmp/.suid_bash
          Attacker executes /tmp/.suid_bash -p  →  root shell.

Why the Race Wins

Steps ② and ③ are sent as non-blocking async D-Bus calls on the same connection and flushed in a single write. The two messages arrive at packagekitd before it can process ② and advance the state machine, leaving the TOCTOU window open. The fix in 1.3.5 adds an explicit state check that returns PK_TRANSACTION_ERROR_INVALID_STATE on any re-invocation after PK_TRANSACTION_STATE_NEW.


Test Script Description

File: cve-2026-41651-purpleteam.py
Language: Python 3
Dependencies: python3-gi (GObject introspection / GLib/Gio bindings)

Purpose

Demonstrates exploitability of CVE-2026-41651 on a prepared test system for the purposes of:

  • Validating whether the installed PackageKit version is vulnerable
  • Generating realistic IOC telemetry for SIEM/EDR tuning
  • Testing detection coverage before and after patching

Behavior

Hardened Environment Support

Default-hardened systems can block the exploit at two independent points. The script handles both automatically.

1. Restrictive umask (027 / 077)

A process-inherited umask of 027 or 077 causes mkdir() to produce 750 or 700 directories. Both dpkg-deb and rpmbuild must traverse the full build tree — if any directory is unreadable the build fails silently.

Fix applied: os.umask(0o022) is called at startup before any file or directory is created. Additionally, every directory and file in the build tree receives an explicit chmod immediately after creation (0o755 for directories and scripts, 0o644 for data files), so the correct permissions are guaranteed regardless of the inherited umask.

2. nosuid / noexec mount flags on /tmp

FlagEffect on exploit
nosuidKernel silently strips the SUID bit from any file stored on that filesystem — the copied bash never becomes root
noexecThe SUID binary cannot be executed at all

Fix applied: At startup, _find_suid_dir() reads /proc/mounts and tests candidate directories in preference order until it finds one whose filesystem has neither flag set. The resolved path is then baked into the payload's post-install script and used for polling and execution.

If all candidates are blocked the script exits with a clear error rather than silently failing.

Compatibility

Distribution FamilyPackage ToolTested
Debian / Ubuntudpkg-deb✓
RHEL / Fedora

Indicators of Compromise

IOCs are listed from generic/infrastructure-level down to script-specific artifacts. Detections built on the generic indicators will catch this CVE regardless of which PoC variant is used.

File System

Process & Execution

D-Bus Activity

Audit Log Patterns

Enable with: auditctl -a always,exit -F arch=b64 -S all -F path=/usr/bin/packagekitd
Or use the rules below in /etc/audit/rules.d/:

root@kitploit:~
# Detect SUID file creation in all candidate drop directories
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/tmp -k suid_drop
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/var/tmp -k suid_drop
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F a2&04000 -F dir=/dev/shm -k suid_drop

# Detect dpkg-deb / rpmbuild by non-root
-w /usr/bin/dpkg-deb -p x -k pkg_build_nonroot
-w /usr/bin/rpmbuild -p x -k pkg_build_nonroot

# Detect SUID bash execution from any candidate drop directory
-a always,exit -F arch=b64 -S execve -F dir=/tmp -F uid!=0 -F euid=0 -k priv_esc_drop
-a always,exit -F arch=b64 -S execve -F dir=/var/tmp -F uid!=0 -F euid=0 -k priv_esc_drop
-a always,exit -F arch=b64 -S execve -F dir=/dev/shm -F uid!=0 -F euid=0 -k priv_esc_drop

Package Manager Artifacts

Privilege Escalation Artifacts


Detection Logic

SIEM Pseudo-Rule (Generic — covers all CVE-2026-41651 variants)

root@kitploit:~
(
  event.category == "process"
  AND process.name IN ("dpkg-deb", "rpmbuild")
  AND process.user.id != "0"
  AND NOT process.parent.name IN ("apt", "apt-get", "dpkg", "rpm", "dnf", "yum", "zypper", "mock", "koji")
)
OR
(
  event.category == "file"
  AND file.path LIKE "/tmp/%" OR file.path LIKE "/var/tmp/%" OR file.path LIKE "/dev/shm/%"
  AND file.owner == "root"
  AND (file.mode LIKE "04%")
)
OR
(
  event.category == "process"
  AND process.name == "bash"
  AND process.real_user.id != "0"
  AND process.effective_user.id == "0"
  AND NOT process.parent.name IN ("sudo", "su", "sshd", "login", "pam")
)

EDR Behavioral Chain

root@kitploit:~
packagekitd
  └─ sh / bash  (cwd or arg matches /tmp, /var/tmp, /dev/shm, or $HOME)
       └─ install / cp / chmod  (target has SUID + owner root)

Flag the full chain. Any individual step alone may be benign; the parent-child relationship through packagekitd to a SUID-setting command is high-fidelity regardless of which drop directory was selected. Widen path-based rules to cover all four candidates.


Affected Systems & Versions

Check installed version: pkcon backend-details or packagekit --version
Vulnerable if reported version is ≤ 1.3.4.


Remediation

Primary: Upgrade PackageKit to 1.3.5 or apply the vendor-specific backport.

root@kitploit:~
# Debian / Ubuntu
apt update && apt install --only-upgrade packagekit

# Fedora / RHEL
dnf upgrade packagekit

# SUSE
zypper update packagekit

Mitigations (if patching is not immediately possible):


References


Generated: 2026-04-24 | Updated: 2026-04-25 | Purple Team Assessment | Internal Use Only

Download Tool
FieldValue
CVE IDCVE-2026-41651
CWECWE-367 — Time-of-check Time-of-use (TOCTOU) Race Condition
ComponentPackageKit (packagekitd, D-Bus service)
AffectedPackageKit ≤ 1.3.4
Fixed inPackageKit 1.3.5
ImpactLocal Privilege Escalation → root
Attack VectorLocal / D-Bus (unprivileged user session)
Disclosed2026-04-22 (Deutsche Telekom Red Team)
AdvisoryGHSA-f55j-vvr9-69xv
Fix commit76cfb675fb31acc3ad5595d4380bfff56d2a8697
PhaseAction
SetupProbes /proc/mounts to select a SUID/exec-capable drop directory, sets umask(022), applies explicit chmod on all build artifacts, then builds a dummy and a payload package in /tmp
ExploitOpens a system D-Bus connection, creates a PackageKit transaction, fires the two-call race
PayloadPackage post-install script copies /bin/bash to <drop_dir>/.suid_bash with mode 04755, owner root. Drop directory is resolved at runtime (see Hardened Environment Support)
EscalationPolls for the SUID binary (90 s timeout), then execls into it with -p for a root shell
CleanupRemoves the temporary .deb/.rpm files on exit (success or failure)
PriorityCandidateTypical hardening
1/var/tmpRarely carries nosuid/noexec; survives reboots
2/dev/shmtmpfs, usually permissive; cleared on reboot
3/tmpOften hardened on CIS/STIG systems
4$HOMELast resort; always writable by the user
rpmbuild
✓
SUSE / openSUSErpmbuild✓
IOCPath / PatternNotes
SUID binary in world-writable directory<drop_dir>/.suid_bash — drop directory is /var/tmp, /dev/shm, /tmp, or $HOME depending on mount flagsScript selects the first directory without nosuid/noexec; widen detections to cover all four candidates
Transient package file in /tmp/tmp/*.deb, /tmp/*.rpmBuilt by unprivileged user; legitimate package operations use /var/cache or download paths
dpkg build tree/tmp/pkbuild_*, /tmp/build_*Staging directories for dpkg-deb -b
rpmbuild tree in /tmp/tmp/rpmbuild_*Staging directories for rpmbuild invoked outside ~/rpmbuild
postinst / %post script in /tmp/tmp/*/DEBIAN/postinst, /tmp/*/SPECS/*.specScripts that copy or chmod system binaries are high-confidence
IOCDetail
dpkg-deb spawned by non-root, non-apt processParent is a user Python/shell process, not apt, dpkg, or unattended-upgrades
rpmbuild spawned by unprivileged userWithout a packaging-related parent (mock, koji, CI runner) this is anomalous
packagekitd spawning /bin/sh or /bin/bash from /tmp pathpackagekitd runs postinst scripts; source path in /tmp is the anomaly
bash process where UID ≠ EUIDSUID execution; EUID=0, UID=<attacker>
bash -p invocationThe -p flag enables privileged mode when SUID is set — rarely used legitimately
Short-lived .suid_bash process ancestryGrandparent is packagekitd, parent is attacker's shell
IOCDetail
org.freedesktop.PackageKit.Transaction.InstallFiles called twice on same object pathBoth calls arrive within milliseconds; legitimate clients call once per transaction
FLAG_SIMULATE (4) followed immediately by FLAG_NONE (0) on same tidThis sequence has no legitimate use case
CreateTransaction → rapid double InstallFiles patternDetectable via D-Bus monitor (dbus-monitor --system) or audit dbus rules
InstallFiles with a file path under /tmpLegitimate GUI package installers (GNOME Software, Discover) use paths in $HOME or /var/cache
IOCDetail
Package named pk-dummy-* or pk-payload-* in dpkg/rpm historyScript-specific but variants will use different names
Package installed from local file (/tmp/*.deb or /tmp/*.rpm)dpkg -l or rpm -qa --last — look for packages with no repository origin
Package installed with no changelog / empty descriptionCrafted packages use minimal metadata; dpkg -s <pkg> or rpm -qi <pkg>
Package removed immediately after install or never appears in package DBFailed exploit attempts may leave partial state
packagekit transaction log entries for local-file installs/var/log/PackageKit/transactions.db or journald packagekitd entries
IOCDetail
.suid_bash in any candidate drop directoryDrop path is chosen at runtime from /var/tmp, /dev/shm, /tmp, $HOME based on mount flags — check all four: find /var/tmp /dev/shm /tmp $HOME -uid 0 -perm -4000 2>/dev/null
Any file owned by root with SUID bit in a user-writable directoryShould always return empty on clean systems
bash process tree with euid=0 and no PAM / sudo / su ancestorIndicates SUID execution path rather than legitimate privilege transition
polkit grant for org.freedesktop.packagekit.package-install to non-admin userUnexpected if user is not in sudo / wheel group
DistributionDefault PackageKitVulnerablePatched version available
Ubuntu 24.04 LTS1.3.xYesVia apt upgrade
Ubuntu 22.04 LTS1.2.xYesBackport in progress
Debian 12 (Bookworm)1.2.xYesSecurity tracker pending
Fedora 411.3.xYesdnf upgrade packagekit
RHEL 9 / CentOS Stream 91.2.xYesRHSA pending
SUSE Linux Enterprise 151.1.xLikelySUSE advisory pending
Arch Linux1.3.xYesAUR / pacman updated
MitigationCommand / ConfigCaveat
Disable PackageKit servicesystemctl disable --now packagekitdBreaks GNOME Software / Discover GUI updates
Restrict D-Bus accessAdd deny rule in /etc/dbus-1/system.d/org.freedesktop.PackageKit.conf for unprivileged usersMay break legitimate user-facing package tools
Polkit hardeningSet org.freedesktop.packagekit.package-install to auth_admin (require admin password always)Reduces convenience but narrows the attack surface
Audit monitoringDeploy audit rules from the Audit Log Patterns sectionDetective only, not preventive
ResourceLink
OSS-Security disclosurehttps://www.openwall.com/lists/oss-security/2026/04/22/6
GitHub Security AdvisoryGHSA-f55j-vvr9-69xv
Fix commithttps://github.com/PackageKit/PackageKit/commit/76cfb675fb31acc3ad5595d4380bfff56d2a8697
PackageKit 1.3.5 releasehttps://github.com/PackageKit/PackageKit/releases/tag/v1.3.5
Public PoC referencehttps://github.com/CipherCloak/CVE-2026-41651
CWE-367https://cwe.mitre.org/data/definitions/367.html
polkit documentationhttps://www.freedesktop.org/software/polkit/docs/latest/