← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-5140 · CWE-93 · Disclosed 2026-04-29

Improper neutralization of CRLF sequences

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is less a front-door break-in than a janitor closet key left beside the lock

The CRLF bug lives in pardus-update's privileged helper SystemSettingsWrite.py, which in vulnerable builds writes attacker-controlled values into /etc/pardus/pardus-update.conf without rejecting carriage returns. Primary-source code shows the affected range is 0.6.3 before 0.6.4, and the fix added integer validation before writing the lastupdate and lastupgrade fields. In practice, the injected \r can smuggle a new config key such as custom_sourcesd_path, which matters because other privileged update helpers later consume that config.

The vendor's HIGH 8.8 / AV:N framing does not match what the code path looks like in the real world. This is not a network daemon and not something Shodan is going to hand to an external attacker; it is a local GUI updater plus pkexec helper chain. Severity stays relevant because the same package also shipped permissive Polkit rules and an unsafe APT-source copy path, so on an affected Pardus host a local foothold can turn into root quickly, but that is still post-initial-access and materially narrower than the vendor baseline.

"Root on the box is real, but this is a niche local privilege-escalation chain, not an internet fire drill."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Get code execution on a Pardus endpoint

The attacker first needs a local shell or the ability to run a process as an unprivileged user on a system that actually has pardus-update installed. This is the real gating factor: the bug is in a desktop update utility, not an exposed service. Typical entry points are shared-user systems, VDI-style Linux desktops, or a host already reached through phishing, credential theft, or another local code-exec vector.
Conditions required:
  • Attacker can execute commands locally as a non-root user
  • Target runs Pardus with the pardus-update package installed
  • Affected package version is 0.6.3 before 0.6.4
Where this breaks in practice:
  • Requires post-initial-access or a shared local-user environment
  • Pardus is niche in most US enterprise fleets
  • Servers without the GUI updater package are out of scope
Detection/coverage: Asset inventory and package scanners can find pardus-update versions reliably; internet-facing scanners will not help because there is no listening network service tied to this flaw.
STEP 02

Abuse pkexec policy to run the helper

The bundled policy file maps pkexec actions to SystemSettingsWrite.py and, in the vulnerable package, sets allow_any, allow_inactive, and allow_active to yes for that helper. That means the attacker can execute the privileged write helper without an admin password prompt if the shipped policy is present. Weaponized tool at this step is native pkexec against /usr/share/pardus/pardus-update/src/SystemSettingsWrite.py.
Conditions required:
  • Vulnerable Polkit policy file is deployed
  • Local user can invoke pkexec on the host
Where this breaks in practice:
  • If the policy was hardened locally, this step dies
  • Some stripped-down systems may not have the policy/helper deployed together
Detection/coverage: Polkit logs, shell history, EDR process telemetry, and auditd can all catch pkexec launching SystemSettingsWrite.py or AutoAptUpgrade.py.
STEP 03

Inject config keys with a carriage return

The vulnerable SystemSettingsWrite.py passes user input straight into Python ConfigParser as a timestamp value. Before 0.6.4, it does not validate the argument, so a payload like 123\rcustom_sourcesd_path=/tmp/pwn.list can be written into the root-owned config and interpreted as an extra option. The fix commit added validate_timestamp() and forces the field to parse as a non-negative integer before write.
Conditions required:
  • Helper is still the pre-fix build
  • Attacker can supply crafted argument data to the helper
Where this breaks in practice:
  • The bug by itself only poisons config; another consumer must act on the injected key
  • If defenders monitor config-file writes under /etc/pardus/, this becomes visible
Detection/coverage: FIM on /etc/pardus/pardus-update.conf is strong here; watch for unexpected writes and suspicious keys like custom_sourcesd_path.
STEP 04

Trigger privileged APT source ingestion and land root

The final stage uses AutoAptUpgrade.py, which in the vulnerable chain reads custom_sourcesd_path from the poisoned config and copies the attacker-controlled .list file into /etc/apt/sources.list.d/ as root. From there, a malicious repository can serve a package with a hostile maintainer script and convert the local foothold into full root on the host. Weaponized tool at this step is native pkexec plus apt, not a public exploit kit.
Conditions required:
  • AutoAptUpgrade.py is present and callable with elevated privileges
  • Attacker controls the referenced .list file and repository content
  • APT can reach the attacker-controlled source or a local file source
Where this breaks in practice:
  • Needs multiple package components to line up, so this is a chain not a one-bug miracle
  • Egress controls, repo allowlists, or signed-repo enforcement can break the last mile
  • Per-host blast radius remains one endpoint at a time
Detection/coverage: Monitor writes under /etc/apt/sources.list.d/, unexpected apt update/full-upgrade runs from pkexec, and post-install package scripts changing SUID bits.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo evidence of active exploitation found in primary sources reviewed; not listed in CISA KEV.
Proof-of-concept availabilityNo public standalone exploit repo was confirmed in the sources reviewed. The chain is still reproducible from upstream code paths because the vulnerable Polkit policy, config-write primitive, and APT-source copy logic are all visible in the project sources.
EPSS0.00046 (~0.046%) from the user-provided intel; that is very low likelihood. Exact percentile was not verified from a primary EPSS lookup, but this score is consistent with a low-single-digit percentile range.
KEV statusNo KEV listing as of 2026-05-29.
CVSS vector reality checkVendor/CNA vector is CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H, but upstream code points to a local pkexec helper chain, not an internet-reachable auth surface.
Affected versionspardus-update from 0.6.3 before 0.6.4 per NVD.
Fixed versionsFixed in 0.6.4; later release material also shows pardus-update 0.6.5 shipping in Pardus 25.1.
Exposure populationThis is a local desktop updater path, not a network listener. Shodan/Censys/FOFA-style exposure counts are largely irrelevant because there is no direct remote socket to enumerate.
Disclosure timelineCVE published 2026-04-29; NVD record modified 2026-05-04 with corrected product/version wording.
Researcher / reporting orgPrimary-source attribution points to the CNA as the Computer Emergency Response Team of the Republic of Turkey. Individual researcher attribution was not verified from primary sources reviewed.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (5.8/10)

The decisive downgrade factor is attacker position: this chain starts from local code execution on a Pardus host, not unauthenticated remote reachability. Once that prerequisite is met the path to root is ugly and fast, but the reachable population is narrow enough that this belongs in post-compromise hardening, not in the same bucket as externally exploitable auth bypasses.

HIGH Affected version range and fix mechanics in upstream code
HIGH Attack-path assessment that the issue is local/helper-based rather than network-exposed
MEDIUM Absence of public exploitation and lack of verified public PoC repo

Why this verdict

  • Vendor vector overstates reachability: the code path is a local pkexec helper chain, not an externally reachable web or auth service, so AV:N is not how defenders should triage it operationally.
  • Requires prior foothold: the attacker needs local execution on a Pardus endpoint, which implies either a shared-user machine or an earlier compromise stage; that sharply reduces enterprise-wide exposure.
  • Still root when the chain lines up: permissive Polkit rules plus CRLF config injection plus APT-source ingestion can end in full root on-host, so this is not backlog trivia.

Why not higher?

I am not scoring this HIGH because the reachable population is constrained twice: first by platform/package prevalence, then by the need for local execution before the bug matters. There is also no KEV signal, no confirmed active exploitation in the sources reviewed, and no evidence this is a broadly weaponized remote path.

Why not lower?

I am not pushing this to LOW because the exploit chain is straightforward on an affected box and ends in full administrative control of that host. On shared Linux desktops, labs, or any environment where an attacker can land a user shell, this is a clean privilege-escalation hop defenders should care about.

05 · Compensating Control

What to do — in priority order.

  1. Harden the Polkit policy — Change the pardus-update Polkit actions away from permissive yes defaults so unprivileged users cannot launch the helper chain without admin approval. Because this verdict is MEDIUM, there is no mitigation SLA; use this as a risk reducer while you work inside the 365-day remediation window.
  2. Watch the Pardus update config — Put file-integrity monitoring on /etc/pardus/pardus-update.conf and alert on unexpected keys such as custom_sourcesd_path or writes by unusual parent processes. There is no mitigation SLA here either, but this is cheap visibility to deploy during the remediation window.
  3. Constrain APT source changes — Alert on or block unauthorized writes into /etc/apt/sources.list and /etc/apt/sources.list.d/, especially when the parent process is pkexec, python3, or AutoAptUpgrade.py. This breaks the most important privilege-escalation follow-on path.
  4. Prioritize shared-user Linux estates — If you run teaching labs, kiosks, contractor workstations, jump boxes, or other multi-user Pardus endpoints, treat those as the real exposure subset because local-user-to-root matters most there. For MEDIUM, there is no mitigation SLA, but those systems deserve first attention inside the remediation window.
What doesn't work
  • Perimeter WAF or edge IDS: this is not a web request path and not an internet-facing service.
  • Password rotation alone: the permissive Polkit rule removes the normal admin-auth gate once the attacker already has a local user context.
  • External attack-surface scanning: Shodan/Censys visibility does not measure risk for a local GUI updater helper.
06 · Verification

Crowdsourced verification payload.

Run this on the target Pardus host as a normal user; no root is required for the version check, though root helps if your file permissions are unusually strict. Save it as check-pardus-cve-2026-5140.sh and run bash check-pardus-cve-2026-5140.sh.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-pardus-cve-2026-5140.sh
# Detects whether pardus-update is vulnerable to CVE-2026-5140 based on package version
# and a secondary content check for the timestamp validation fix.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

PKG="pardus-update"
FILE="/usr/share/pardus/pardus-update/src/SystemSettingsWrite.py"
VER=""

if ! command -v dpkg-query >/dev/null 2>&1; then
  echo "UNKNOWN: dpkg-query not found"
  exit 2
fi

if ! dpkg-query -W -f='${Version}' "$PKG" >/dev/null 2>&1; then
  echo "UNKNOWN: package '$PKG' is not installed or not queryable"
  exit 2
fi

VER="$(dpkg-query -W -f='${Version}' "$PKG" 2>/dev/null)"
if [ -z "$VER" ]; then
  echo "UNKNOWN: unable to determine package version"
  exit 2
fi

# Secondary signal: patched builds contain validate_timestamp().
HAS_FIX=0
if [ -r "$FILE" ] && grep -q 'def validate_timestamp' "$FILE" 2>/dev/null; then
  HAS_FIX=1
fi

# Affected range from primary-source advisory/NVD: 0.6.3 <= version < 0.6.4
if dpkg --compare-versions "$VER" ge 0.6.3 && dpkg --compare-versions "$VER" lt 0.6.4; then
  if [ "$HAS_FIX" -eq 1 ]; then
    echo "PATCHED: $PKG version $VER is in the nominal vulnerable range but the file contains the timestamp validation fix"
    exit 0
  else
    echo "VULNERABLE: $PKG version $VER is in the affected range and no fix marker was found"
    exit 1
  fi
fi

if dpkg --compare-versions "$VER" ge 0.6.4; then
  echo "PATCHED: $PKG version $VER is >= 0.6.4"
  exit 0
fi

if dpkg --compare-versions "$VER" lt 0.6.3; then
  echo "PATCHED: $PKG version $VER is below the affected range"
  exit 0
fi

echo "UNKNOWN: unable to classify $PKG version $VER"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not treat this like an external emergency unless you actually run Pardus at scale: first inventory where pardus-update is installed, then confirm whether any hosts are on 0.6.3. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window, but on shared-user Pardus desktops you should still tighten the Polkit policy and monitor APT-source/config writes early because the local-to-root chain is cheap once an attacker lands. Use the noisgate remediation SLA to move every affected host to 0.6.4 or later within <= 365 days, and document non-Pardus or non-affected systems as out of scope.

Sources

  1. NVD CVE-2026-5140
  2. Pardus Update upstream repository
  3. Pardus Update changelog (raw)
  4. Fix commit adding timestamp validation
  5. Vulnerable SystemSettingsWrite.py (0.6.3 raw)
  6. AutoAptUpgrade.py (0.6.3 raw)
  7. Pardus Polkit policy file
  8. Pardus 25.1 release notes
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.