Detection: Linux Dirty Frag Kernel Privilege Escalation

Description

The following analytic detects exploitation of Dirty Frag (CVE-2026-43284 and CVE-2026-43500), a Linux kernel local privilege escalation vulnerability. The exploit corrupts the kernel page cache via the IPsec ESP or RxRPC subsystems using a high-frequency splice() syscall loop, followed by a privilege transition to root in the same audit session. This analytic anchors on the exploit-specific behavioral signature, a sustained splice() spray (50 or more calls within a 60-second window) from an unprivileged process executing from a user-writable path (/home, /tmp, /dev/shm, /var/tmp, /run/user, /root), followed within 5 minutes by execution of a set-uid binary in the same auditd session.

 1`linux_auditd`
 2type=SYSCALL
 3key=splice_user
 4exe IN (
 5    "/home/*",
 6    "/tmp/*",
 7    "/var/tmp/*",
 8    "/dev/shm/*",
 9    "/run/user/*",
10    "/root/*"
11)
12
13
14| bin _time span=60s
15
16| eval user = coalesce(user, auid, AUID)
17
18
19| stats count AS splice_count
20        values(exe) AS spray_binary
21        values(pid) AS spray_pid
22        values(user) AS user
23        earliest(_time) AS spray_start
24        latest(_time) AS spray_end
25  BY auid host ses _time
26
27
28| where splice_count >= 50
29
30
31| join type=inner auid host ses [
32    search `linux_auditd`
33    type=SYSCALL
34    key=process_creation
35    exe IN (
36        "/usr/bin/chfn",
37        "/usr/bin/chsh",
38        "/usr/bin/fusermount3",
39        "/usr/bin/gpasswd",
40        "/usr/bin/mount",
41        "/usr/bin/newgrp",
42        "/usr/bin/passwd",
43        "/usr/bin/su",
44        "/usr/bin/sudo",
45        "/usr/bin/umount",
46        "/usr/lib/dbus-1.0/dbus-daemon-launch-helper",
47        "/usr/lib/landscape/apt-update",
48        "/usr/lib/openssh/ssh-keysign",
49        "/usr/lib/polkit-1/polkit-agent-helper-1"
50    )
51
52    
53| stats earliest(_time) AS privesc_time
54            values(exe) AS privesc_binary
55            values(comm) AS privesc_comm
56            values(ppid) AS privesc_ppid
57      BY auid host ses
58]
59
60
61| eval window_secs = privesc_time - spray_end
62
63| where window_secs >= 0 AND window_secs <= 300
64
65
66| `security_content_ctime(spray_start)`
67
68| `security_content_ctime(spray_end)`
69
70| `security_content_ctime(privesc_time)`
71
72
73| rename host AS dest
74
75
76| table dest user auid ses spray_binary spray_pid
77        splice_count spray_start spray_end privesc_binary
78        privesc_comm privesc_ppid privesc_time window_secs
79
80
81| `linux_dirty_frag_kernel_privilege_escalation_filter`

Data Source

Name Platform Sourcetype Source
Linux Auditd Syscall Linux icon Linux 'auditd' 'auditd'

Macros Used

Name Value
security_content_ctime convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$)
linux_dirty_frag_kernel_privilege_escalation_filter search *
linux_dirty_frag_kernel_privilege_escalation_filter is an empty macro by default. It allows the user to filter out any results (false positives) without editing the SPL.

Annotations

- MITRE ATT&CK
+ Kill Chain Phases
+ NIST
+ CIS
- Threat Actors
ID Technique Tactic
T1068 Exploitation for Privilege Escalation Privilege Escalation
T1548.001 Setuid and Setgid Privilege Escalation
Exploitation
DE.CM
CIS 10

CVE

Default Configuration

This detection is configured by default in Splunk Enterprise Security to run with the following settings:

Setting Value
Disabled true
Cron Schedule 0 * * * *
Earliest Time -70m@m
Latest Time -10m@m
Schedule Window auto
Creates Finding (Notable) Yes
Rule Title %name%
Rule Description %description%
Notable Event Fields user, dest
Creates Intermediate Finding (Risk Event) Yes
TTP detections generate a Finding (Notable) and may generate Intermediate Findings (Risk Events) for associated entities.

Implementation

This analytic requires Linux auditd telemetry forwarded to Splunk via the Splunk_TA_nix add-on with the linux_audit sourcetype (referenced through the linux_auditd macro).

The detection depends on two audit rule keys, both of which are standard in the Neo23x0 recommended ruleset (https://github.com/Neo23x0/auditd) and the existing ESCU Copy Fail analytic (Linux Auditd Copy Fail Privilege Escalation), so no detection-specific custom keys are introduced.

PREREQUISITE 1; splice_user key.

-a always,exit -F arch=b64 -S splice -S vmsplice -F success=1 -F auid>=1000 -F auid!=unset -k splice_user -a always,exit -F arch=b32 -S splice -S vmsplice -F success=1 -F auid>=1000 -F auid!=unset -k splice_user

Operators should baseline splice volume in their environment before enabling. Hosts running heavy zero-copy I/O workloads (specific: web servers, mail transfer agents, container runtimes) may need additional filtering.

PREREQUISITE 2; process_creation key.

-a always,exit -F arch=b64 -S execve -S execveat -F auid>=1000 -F auid!=unset -k process_creation -a always,exit -F arch=b32 -S execve -S execveat -F auid>=1000 -F auid!=unset -k process_creation

Known False Positives

The splice volume threshold (50 calls per 60 seconds from a single process in a user-writable path) is calibrated against the V4bel public PoC, which produces 100-460 splice calls in 90 seconds depending on system state. Legitimate user-mode workloads that may produce splice() calls (web servers, mail transfer agents, language runtimes) typically execute from system paths (/usr/sbin, /usr/bin, /usr/lib) and are excluded by the user-writable path filter. Custom-compiled applications, developer test binaries, or container runtimes executing from /home or /tmp could theoretically reach the volume threshold during legitimate I/O-heavy workloads (large file copies, log rotation, archive operations). Operators should baseline splice volume in their environment before enabling as a notable event. If false positives occur, add an allowlist of trusted binary paths via the linux_dirty_frag_kernel_privilege_escalation_filter macro, or raise the splice_count threshold based on observed legitimate-workload baseline.

Associated Analytic Story

Finding

Title Entity Field Entity Type Risk Score
Local privilege escalation attempt detected on $dest$ executed by $user$ using $spray_binary$ dest system 50

Intermediate Findings

Message Entity Field Entity Type Risk Score
Local privilege escalation attempt detected on $dest$ executed by $user$ using $spray_binary$ user user 50

Threat Objects

Field Type
spray_binary process_name

References

Detection Testing

Test Type Status Dataset Source Sourcetype
Validation Passing N/A N/A N/A
Unit Passing Dataset auditd auditd
Integration ✅ Passing Dataset auditd auditd

Replay any dataset to Splunk Enterprise by using our replay.py tool or the UI. Alternatively you can replay a dataset into a Splunk Attack Range


Source: GitHub |

Version: 1