1. Executive summary
Elastic Security Labs has published a detection-engineering framework for Linux local privilege escalation (LPE), validated against 11 public proof-of-concept exploits and 2 SUID misconfigurations from the 2026 disclosure wave. The central finding is that seven of the 13 Linux LPE disclosures Elastic tracked in 2026 share a single bug class — a copy-on-write or zero-copy path writing into data it was supposed to copy first — aimed at different kernel interfaces (AF_ALG/crypto, ESP, RxRPC, socket-buffer fragment helpers, traffic control, filesystem). No verified CVE reference data was resolved for this item, so no CVSS scores, severities, or CISA-KEV exploitation states can be asserted here; the CVEs named in the source (CVE-2026-31431, CVE-2026-43284, CVE-2026-43500, CVE-2026-43503, CVE-2026-46333) are single-sourced to the Elastic blog and its cited research. There is no indication of in-the-wild exploitation, ransomware, or data extortion in the source material — this is a defensive detection framework, not an incident report. The bottom-line risk for EMEA financial services is that Linux server estates — including container hosts and any platform where an attacker can obtain an unprivileged foothold (web shell, compromised service account, phished developer) — face a rising volume of LPE paths that per-CVE detection cannot keep pace with; outcome-oriented detection of the "unprivileged exec from writable path → uid_change to 0" flow is the durable control.
2. Regulatory framing
No specific DORA/NIS2 article is directly engaged by this item. This is a vendor detection-framework publication describing publicly disclosed vulnerabilities and lab-validated PoCs, with no incident, no client-side compromise, and no third-party provider failure in evidence. Generic mappings to incident-reporting or patching articles would be compliance-checkbox padding.
3. Technical analysis & attack chain
The general LPE flow (confirmed across all 13 test cases). Nearly every Linux LPE, regardless of the underlying bug, produces the same host-level skeleton:
- An unprivileged user (uid != 0) executes something — usually a freshly dropped or compiled binary, a script, or a shell one-liner — from a writable location:
/tmp,/dev/shm,/var/tmp,/home, or/run/user/. - Moments later, a process in that lineage runs as root: a
uid_changeto0, an effective uid/gid of0, or an interactive root shell. - In many PoCs, the exploit confirms success by running
whoami,id, orlogname.
The 2026 bug-class convergence. Seven of 13 tracked disclosures share one class: a copy-on-write or zero-copy path that writes into data it was supposed to copy first. The mechanism: Linux moves file-backed page-cache pages through kernel subsystems without copying them (via splice(), sendfile()); when a subsystem writes in place without honouring copy-on-write, an unprivileged user corrupts the in-memory image of a privileged file. The file on disk stays clean; the cached version of /usr/bin/su, /bin/su, or another privileged target is not what the administrator expects. Elastic explicitly draws the lineage from DirtyCOW and Dirty Pipe into the 2026 wave.
Per-technique detail (from Elastic's lab runs of public PoCs)
- Copy Fail (CVE-2026-31431, single-sourced). Chains an
AF_ALGsocket withsplice()to land a controlled write into a page-cache page, then abuses the corruption against a privileged file. Public write-ups describe the vulnerable path as theauthencesnAEAD implementation mishandling input manipulated throughsplice(). Observed path:AF_ALGsocket()andsplice()burst → cached/usr/bin/sucorrupted →suexecutes with root effective UID. This is the one variant with both a primitive-level signal (auditd: non-root process producing a burst ofsocket(AF_ALG)calls interleaved withsplice()) and an outcome signal. - DirtyFrag. Chains the xfrm-ESP Page-Cache Write issue (CVE-2026-43284, single-sourced) with the RxRPC Page-Cache Write issue (CVE-2026-43500, single-sourced). Shared socket-buffer fragments reach in-place writers without the kernel forcing a safe copy. Observed: no distinct primitive alert; shared page-cache fragments reach in-place processing →
/bin/suexecutes with root effective UID. - Fragnesia. Targets
skb_segment()innet/core/skbuff.c. During GSO segmentation,skb_segment()propagatesSKBFL_SHARED_FRAGfrom the head skb but not from afrag_listmember carrying page-cache-backed fragments; once the marker is lost, the resulting skbs pass the ESPskip_cowguard and are decrypted in place over page-cache pages. Trigger is networking-heavy: namespaces, veth pairs,send(),splice(), GRO coalescing, GSO segmentation, ESP-in-TCP receiver. Observed: local compilation (./skb_segment_exploit) and network activity →skb_segment()loses the shared-fragment marker → ESP-in-TCP modifies cached/usr/bin/su, corrupted image executes. - DirtyDecrypt (aka DirtyCBC per the PoC authors). An
rxgkpage-cache write from a missing copy-on-write guard inrxgk_decrypt_skb(): the function builds an skb scatterlist and calls Kerberos decryption without forcing a safe copy, while thekrb5encAEAD template decrypts in place before the HMAC check. The PoC sets up user and network namespaces, drives RxRPC over loopback, splices file-backed pages into the packet path, repeatedly fires the decrypt primitive, targets a readable SUID-root binary (e.g./usr/bin/su), backs it up under/tmp, corrupts the in-memory image with a smallsetuid(0)+/bin/shpayload, and executes it. Observed binary:./dirtydecrypt. - pedit COW. The abused interface is the
tcpacket-editing actionact_pedit.tcf_pedit_act()computes the COW range once before the key loop and can leave part of the write region un-COW'd (NVD description quoted by Elastic: "net/sched: fix pedit partial COW leading to page cache corruption"). The PoC callsunshare()internally and configuresact_peditthrough Netlink; the write extends beyond the copied region, the cachedsuentry point is replaced, and execution yields a root shell. - DirtyClone (CVE-2026-43503, single-sourced). NVD describes missing propagation of
SKBFL_SHARED_FRAGthrough helpers such as__pskb_copy_fclone()andskb_shift(), letting an unprivileged user write into the page cache of a root-owned read-only file through later in-place writers. Python-driven, runs from a user-controlled working directory, crosses into root. Elastic explicitly cautions: confirm whether the observeduid_changerepresented host root or namespace-mapped root before describing it as completed host escalation. - CIFSwitch. A trusted-helper bug reached through the kernel: missing validation in the
cifs.spnegokey type. The attacker callsrequest_key()with a forged key description, causing the kernel to invoke the root-ownedcifs.upcallhelper with attacker-controlled fields. Withupcall_target=app, the helper enters the attacker's mount namespace and performs agetpwuid()lookup before dropping privileges — loading an attacker-controlled NSS library and executing code as root. Observed:unsharecreates a hostile mount namespace → forgedcifs.spnegorequest launches root-ownedcifs.upcall→ helper loads attacker-controlled NSS code and writes a sudoers rule. - OVSwrap. Uses a private user and network namespace to reach a vulnerable kernel interface directly:
unshare -Urngrants namespace-localCAP_NET_ADMIN, allowing creation of a private Open vSwitch datapath without host-levelCAP_NET_ADMIN. The bug is in OVS action handling: thenla_lenfield describing an individual Netlink attribute is 16 bits wide; before the fix, a generated nested action could grow beyond 65,535 bytes without rejection, the stored length wraps, and later OVS parsing resumes from attacker-controlled data inside the generated action stream. The PoC builds kernel read and targeted decrement primitives, locates a host-side process and its credentials, and modifies itsfsuid/fsgiduntil the process can write as root — then writes a passwordless sudo rule and executessudo -n bash. - ptrace_may_dream (CVE-2026-46333, single-sourced). The bug sits in the kernel's
__ptrace_may_access()path: during process exit there is a window when a task has dropped its memory image but still holds open file descriptors. Paired withpidfd_getfd(), an unprivileged process can duplicate descriptors from a dying privileged process when credential checks line up. Qualys (as cited by Elastic) described impact as credential disclosure and root-code-execution potential, with case studies againstchage,ssh-keysign,pkexec, andaccounts-daemon. Critically, a successful exploit may never create a root shell — root-only material simply leaves the boundary. Two sub-PoCs: - ssh-keysign-pwn (
./sshkeysign_pwn): repeatedly spawns/usr/lib/openssh/ssh-keysign(which opens SSH host private keys before dropping privileges), opens a pidfd for the child, racespidfd_getfd()across likely descriptors, and checks whether any duplicated descriptor points to anssh_host_*_keyfile. No root shell. - chage_pwn (
./chage_pwn root): forkschage -l <user>(which opens/etc/shadowthen drops privileges), racespidfd_getfd()over candidate descriptors, finds the duplicated descriptor pointing at/etc/shadow, and reads it. The meaningful transition is group-based: the unprivileged process entersshadowgroup context. - A third observed path in the test matrix:
busctl --system calltriggers AccountsService activity →pidfd_getfd()race duplicates a root-authenticated D-Bus socket → account shell, password, and administrator status changed beforesu/sudoyields root. - SUID misconfigurations (no CVE). (a) Root-owned SUID
findexecutes/bin/sh -pthrough-exec; the shell retains root effective UID. (b) System Bash copied to a non-standard path with SUID set;bash -ppreserves the elevated effective UID → root-capable shell.
Namespace precursor. A large family of LPEs begins with unshare(CLONE_NEWUSER) to gain capabilities inside a new user namespace, then uses that borrowed power to reach kernel code paths (filesystems, mounts, networking) never designed for untrusted local input. This step is shared across CIFSwitch, pedit COW, DirtyClone, and container escapes, making it a high-value early detection point independent of whichever bug follows.
LLM-assisted research trend (single-sourced to the Elastic blog's characterisation). Elastic reports that Qualys attributes RefluXFS to a research effort with Anthropic, pointing "Claude Mythos Preview" at the kernel's memory-management and filesystem code to hunt for a DirtyCOW-style race, with humans on validation and disclosure; the OVSwrap author credits a comparable LLM-assisted workflow. Adverse Trace note: this attribution of research methodology is single-sourced and concerns vulnerability research, not threat-actor activity — no malicious actor is named anywhere in the source material, and no MITRE-profiled actor attribution exists for any of these bugs.
Confidence caveat. All technical detail above derives from a single vendor publication (Elastic Security Labs) and the public PoCs it references. CVE identifiers, NVD descriptions, and Qualys impact statements are quoted through Elastic, not independently verified by Adverse Trace for this advisory. Verify before enforcement.
4. Mitigation & containment
This is a detection-framework item, not an active incident; there is no vendor fix named in the source for the individual kernel bugs. Actions are therefore hardening and detection-deployment oriented.
P1 — within 24 hours
- Audit SUID/SGID surface on all Linux hosts. Enumerate setuid-root binaries (
find / -perm -4000 -type f 2>/dev/null) and remove the SUID bit from any interactive-capable binary on the GTFOBins class list (find,gdb,vim,dd,nmap, and similar). The source's two misconfiguration cases — SUIDfind -execand a copied SUIDbash -p— are instant-root one-liners with no CVE required. - Deploy outcome-oriented LPE detection. If running Elastic: in Kibana, navigate to Security → Rules → Detection rules (SIEM), install the Elastic prebuilt rules, and enable the Linux privilege escalation ruleset (filter tags
OS: LinuxandTactic: Privilege Escalation). Deploy Elastic Defend on Linux hosts for behavioural coverage. Detection rules live in Elastic'sdetection-rulesrepository; endpoint rules inprotections-artifacts. - Enable syscall-level visibility. Enable the Auditd Manager integration. The page-cache class specifically relies on
socket,splice, andbindauditing, plusexecve. The Copy Fail and DirtyFrag research lists the exact auditd rules to add.
P2 — within 72 hours
- Prioritise the named detection rules by the coverage they provided in Elastic's validation runs:
Suspicious SUID/SGID Utility Execution(fired on Copy Fail and DirtyFrag finishes),General Privilege Escalation Sequence Detected(lowest false-positive, highest true-positive for public PoCs — lead investigations with it),Potential Privilege Escalation via Python Exploit/Suspicious UID Change to Root via Python(caught DirtyClone and OVSwrap where no per-CVE tell existed),Namespace Manipulation Using Unshare(early precursor for CIFSwitch, pedit COW, OVSwrap, container escapes),Potential Copy Fail (CVE-2026-31431) Exploitation via AF_ALG Socket(primitive-level), andPotential Shadow Read via Unprivileged User(chage_pwn descriptor theft). - Tune the writable-path exec rules. Elastic notes the exec-then-elevate correlation rules fire on false positives (benign precompiled binaries in
/tmpor/homeelevating) and require environment-specific tuning; on static server estates they should be near plug-and-play. The Pythonuid_changerule uses a new-terms rule type (command line not seen on thehost.idin the last five days) to control noise — replicate this pattern in non-Elastic tooling. - Restrict namespace creation where feasible.
unshare(CLONE_NEWUSER)is the shared precursor across multiple 2026 techniques and container escapes. Where workloads do not require user namespaces, disable via sysctl (kernel.unprivileged_userns_clone=0on distros exposing it, or equivalent AppArmor/seccomp policy). Note: this will break container tooling and sandboxing that legitimately callunshare— apply to server estates selectively.
P3 — within 7 days
- Patch mechanism, not per-CVE tracking. The source's core argument: when one bug class can be aimed at a dozen kernel interfaces in a quarter, per-CVE detection arrives late. Track and patch the kernel page-cache/COW class as a family (Copy Fail, DirtyFrag, Fragnesia, DirtyDecrypt, DirtyClone, pedit COW, RefluXFS) rather than triaging each advisory in isolation; ensure kernel update cadence on all Linux hosts including container hosts, since several of these primitives are reachable from inside containers via namespace capabilities.
- Protect the descriptor-theft class. For CVE-2026-46333-style attacks, the source indicates the loss is root-only material leaving the boundary (SSH host private keys,
/etc/shadow, authenticated D-Bus sockets) with no root shell. Verify: SSH host key file permissions and locations (ssh_host_*_key),/etc/shadowread auditing for non-root/non-shadow-group processes, and alerting onbusctl --system callfrom interactive user contexts. - Validate in a lab. Reproduce each technique in a disposable VM using the relevant public PoC — treat all exploit code as lab-only, never run against systems you do not own.
5. Indicators of compromise
No indicators of compromise available in the source material. This advisory covers publicly disclosed vulnerabilities and lab-validated PoCs; no malicious campaign, actor infrastructure, or in-the-wild artefacts are described.
Behavioural indicators (from Elastic's lab telemetry; these describe exploit behaviour, not confirmed adversary activity):
| Behaviour | Where to observe | Confidence |
|---|---|---|
Non-root process burst of socket(AF_ALG) calls interleaved with splice() |
auditd syscall logs | High (Copy Fail primitive) |
unshare creating user/network namespace from non-root user, followed by uid_change to 0 in same lineage |
EDR process telemetry, auditd | High (CIFSwitch, pedit COW, OVSwrap, DirtyDecrypt precursor) |
Exec from writable path (/tmp, /dev/shm, /var/tmp, /home/*, /run/user/*) followed by uid_change to 0 under same parent |
EDR process lineage | High (general LPE flow) |
SUID helper (su, sudo, pkexec, passwd) executed with argument count ≤1, euid 0, real user non-root, from interpreter/shell-one-liner/writable-path parent |
EDR process telemetry | High |
Python interpreter uid_change to 0 from world-/user-writable working directory, non-root parent, command line unseen on host in 5 days |
EDR new-terms telemetry | High (DirtyClone, OVSwrap) |
Repeated spawning of ssh-keysign or chage -l from a recently compiled binary in user directory (pidfd_getfd race) |
EDR process telemetry | High (CVE-2026-46333 class) |
Unprivileged process entering shadow group context from user-controlled executable path |
EDR group-transition telemetry | High (chage_pwn) |
busctl --system call from unprivileged interactive context |
EDR process telemetry | High (ptrace_may_dream) |
| Recently compiled executable making local network connections, then SUID execution with root euid | EDR + network telemetry | Medium (Fragnesia-style staging) |
| Sudoers file modification following namespace/mount activity | File integrity monitoring | High (CIFSwitch, OVSwrap finish) |
6. Detection
The source provides genuine threat artefacts: PoC binary names, exact SUID helper paths, command-line shapes, and target file paths. Rules below use only strings present in the source.
rule Linux_LPE_2026_PoC_Binaries_Elastic_Lab
{
meta:
author = "Adverse Trace"
date = "2026-09-11"
reference = "https://www.elastic.co/security-labs/threat-command/linux-privilege-escalation-detection-framework"
description = "Matches binary/script names of public 2026 Linux LPE PoCs observed in Elastic Security Labs validation runs. Lab artefacts; useful for retro-hunt on production estates to find unauthorised exploit staging."
strings:
$poc1 = "skb_segment_exploit" ascii
$poc2 = "dirtydecrypt" ascii
$poc3 = "sshkeysign_pwn" ascii
$poc4 = "chage_pwn" ascii
condition:
uint32(0) == 0x464c457f and 2 of them
or filesize < 200KB and 2 of them
}
Note: the four PoC names are the only exploit binary names given in the source. The uint32(0) == 0x464c457f check matches ELF magic; the filesize fallback covers script-form PoCs (e.g. Python-driven DirtyClone/OVSwrap were not named, so they are not included — do not extend the list speculatively).
title: Linux LPE - SUID helper executed with minimal arguments from writable path parent
id: 4c1a7f52-9d3e-4b18-a6f2-1e5d8c9b7a30
status: experimental
description: >
Detects the privilege shape Elastic identified as the most common LPE finish:
a setuid-root helper (su, sudo, pkexec, passwd) running with effective uid 0
while the real user is non-root, invoked with minimal arguments from an
interpreter, shell one-liner, or writable-path parent. Maps to ATT&CK
T1548.001 (Abuse Elevation Control Mechanism: Setuid and Setgid).
references:
- https://www.elastic.co/security-labs/threat-command/linux-privilege-escalation-detection-framework
author: Adverse Trace
date: 2026-09-11
tags:
- attack.privilege_escalation
- attack.t1548.001
logsource:
product: linux
service: auditd
detection:
selection_helper:
exe|endswith:
- '/bin/su'
- '/usr/bin/su'
- '/bin/sudo'
- '/usr/bin/sudo'
- '/usr/bin/pkexec'
- '/usr/bin/passwd'
selection_euid_root:
euid: 0
filter_real_user:
uid: 0
selection_min_args:
a0|endswith:
- '/bin/su'
- '/usr/bin/su'
- '/bin/sudo'
- '/usr/bin/sudo'
- '/usr/bin/pkexec'
- '/usr/bin/passwd'
condition: selection_helper and selection_euid_root and not filter_real_user
falsepositives:
- Legitimate sudo usage by users (typically carries additional arguments;
argument-count filtering reduces this)
level: high
title: Linux LPE - unshare user namespace creation by non-root user
id: 8f2b4d61-c7a9-4e30-b5d1-2f6e0a8c4d92
status: experimental
description: >
Detects unshare creating a user namespace from a non-root user - the shared
precursor across CIFSwitch, pedit COW, DirtyClone, OVSwrap and container
escapes per Elastic Security Labs. Correlate with subsequent uid_change to 0
in the same lineage to reduce false positives from sandboxing and container
tooling, which call unshare constantly but rarely transition to root.
references:
- https://www.elastic.co/security-labs/threat-command/linux-privilege-escalation-detection-framework
author: Adverse Trace
date: 2026-09-11
tags:
- attack.privilege_escalation
- attack.t1611
logsource:
product: linux
service: auditd
detection:
selection:
exe|endswith: '/usr/bin/unshare'
key|contains:
- 'CLONE_NEWUSER'
- '-U'
- '--user'
filter_root:
uid: 0
condition: selection and not filter_root
falsepositives:
- Container runtimes, sandboxing tooling, development environments
level: medium
title: Linux LPE - pidfd_getfd descriptor race against SUID helpers (CVE-2026-46333 class)
id: b3d5e9a2-1f4c-6d80-9b2e-7a1c5f8d3e60
status: experimental
description: >
Detects repeated execution of ssh-keysign or chage from a recently compiled
or user-writable-path parent - the observable shape of the ptrace_may_dream
pidfd_getfd() exit-race PoCs (sshkeysign_pwn, chage_pwn). A successful
exploit may never produce a root shell; the loss is duplicated descriptors
to SSH host private keys or /etc/shadow.
references:
- https://www.elastic.co/security-labs/threat-command/linux-privilege-escalation-detection-framework
author: Adverse Trace
date: 2026-09-11
tags:
- attack.privilege_escalation
- attack.t1068
logsource:
product: linux
service: auditd
detection:
selection_target:
exe|endswith:
- '/usr/lib/openssh/ssh-keysign'
- '/usr/libexec/openssh/ssh-keysign'
- '/usr/bin/chage'
selection_parent_writable:
parent_exe|startswith:
- '/tmp/'
- '/dev/shm/'
- '/var/tmp/'
- '/home/'
- '/run/user/'
filter_real_user:
uid: 0
condition: selection_target and selection_parent_writable and not filter_real_user
falsepositives:
- Legitimate administrative chage usage from user directories (rare)
level: high
7. Sources
- Elastic Security Labs, "Linux Detection Engineering — Local Privilege Escalation," https://www.elastic.co/security-labs/threat-command/linux-privilege-escalation-detection-framework, published 2026-09-11
8. Adverse Trace position
This is a high-value defensive publication, not an incident: no verified CVE reference data was resolved for this item, so Adverse Trace asserts no CVSS severity and no CISA-KEV exploitation state for any of the named CVEs, and no in-the-wild exploitation, ransomware, or actor attribution is claimed — none appears in the source. The material risk to EMEA financial services is structural: seven of 13 tracked 2026 Linux LPEs reuse one copy-on-write bug class across a dozen kernel interfaces, several are reachable from inside containers via user namespaces, and the descriptor-theft class (CVE-2026-46333) exfiltrates root-only material — SSH host keys, /etc/shadow — without ever producing a detectable root shell. Client impact concentrates on Linux server estates, container hosts, and any environment where an attacker can hold an unprivileged foothold; the SUID misconfiguration cases require no exploit at all. All technical detail is single-sourced to the Elastic publication and its referenced public PoCs — verify independently before enforcement actions. Adverse Trace will monitor for independent confirmation of the named CVEs, any emergence of CISA-KEV listings or in-the-wild exploitation reporting, and will update this advisory if verified reference data resolves.
Published via PulseTrace — Adverse Trace threat intelligence.