
Un rapport sur Dirty Frag, qui est une chaîne de vulnérabilités d'escalade de privilèges locaux (LPE) sous Linux permettant à un utilisateur non privilégié d'obtenir un accès root.
Laboratoire de reproduction et de détection d'exploit pour une chaîne d'élévation de privilèges locale du noyau Linux.
Statut : VÉRIFIÉ. J'ai effectué la reproduction, la vérification sans fichier et la détection au niveau des appels système dans le laboratoire (noyau 6.18.9+kali-amd64). Ce document est un journal de laboratoire. Chaque affirmation ci-dessous a été observée lors de l'exécution de la reproduction. Les captures d'écran et les artefacts sont de véritables captures de la machine virtuelle.
Dirty Frag combine deux bugs logiques déterministes dans le noyau Linux. Ces bugs permettent à un utilisateur local non privilégié d'écraser le cache de pages de fichiers en lecture seule (par exemple, /usr/bin/su) et d'obtenir un shell root :
| Variante | CVE | Point de chute | Chemin de déclenchement | Nécessite un userns non privilégié |
|---|---|---|---|---|
| Écriture xfrm‑ESP dans le cache de pages | CVE‑2026‑43284 | crypto_authenc_esn_decrypt() dans esp_input() | socket(AF_INET) avec encapsulation UDP, puis xfrm_input() | Oui (CAP_NET_ADMIN) |
| Écriture RxRPC dans le cache de pages | CVE‑2026‑43500 | rxkad_verify_packet_1() (pcbc(fcrypt)) | socket(AF_RXRPC) | Non |
Les deux variantes utilisent le même schéma racine que Dirty Pipe et Copy Fail. L'appel système splice(2) place une référence à une page du cache de pages d'un fichier dans l'emplacement frag d'un sk_buff côté émetteur. L'attaquant ne peut que lire ce fichier. Le code du noyau côté réception effectue ensuite un STOCKAGE crypto en place par-dessus ce frag. Cela modifie le cache de pages en mémoire RAM. Aucune écriture sur disque n'a lieu, donc la surveillance de l'intégrité des fichiers (AIDE, Tripwire) ne peut pas le voir. L'attaque est déterministe. Elle n'a pas de fenêtre de course et aucun panique du noyau en cas d'échec.
cac2661c53f3 (2017‑01) à f4c50a4034e6 (corrigé 2026‑05‑05)2dc334f1a63a (2023‑06) à aa54b1d27fe0 (corrigé 2026‑05‑10)CVE-2026-43284 = 8,8 (Élevée), CVE-2026-43500 = 7,8 (Élevée)Dirty Frag est une élévation de privilèges sans fichier. Elle corrompt le cache de pages en mémoire, pas le fichier sur disque. La surveillance traditionnelle de l'intégrité des fichiers ne peut pas la voir. La détection doit se faire au niveau des appels système. La chaîne utilise ces primitives d'appels système : socket(AF_ALG)/socket(AF_RXRPC), splice et unshare(CLONE_NEWUSER|CLONE_NEWNET). Le chemin ESP crée également des sockets UDP AF_INET et netlink. Cette couche est au cœur de l'ingénierie de détection de ce dépôt.
Les deux variantes utilisent le même point de chute : un crypto en place qui STOCKE des octets sur une page du cache de pages que l'attaquant place avec splice(2).
UDP_ENCAP_ESPINUDP.vmsplice, puis 16 octets de /usr/bin/su au décalage de fichier cible avec splice.splice pousse le tube dans le socket d'envoi. splice_to_socket() définit MSG_SPLICE_PAGES. Cela place la page du cache de pages de /usr/bin/su directement dans skb->frags[0].xfrm4_udp_encap_rcv, puis xfrm_input, puis esp_input(). La branche vulnérable skip_cow (!skb_cloned() && !skb_has_frag_list()) contourne skb_cow_data(). Elle effectue un déchiffrement AEAD en place avec la page du cache de pages comme source et destination.crypto_authenc_esn_decrypt() émet un STOCKAGE des 32 bits de poids fort de l'ESN. Cette valeur est replay_esn->seq_hi. L'attaquant choisit cette valeur lors de l'enregistrement de l'AS avec l'attribut netlink XFRMA_REPLAY_ESN_VAL.L'attaquant contrôle à la fois l'emplacement (décalage splice) et la valeur (4 octets). La vérification d'authentification s'exécute après le stockage, donc la couche crypto ne signale jamais l'écriture. Cette variante nécessite CAP_NET_ADMIN et utilise unshare(CLONE_NEWUSER|CLONE_NEWNET).
rxkad_verify_packet_1() effectue un déchiffrement pcbc(fcrypt) sur un seul bloc directement sur le frag skb épinglé par splice. Elle ne copie pas les données d'abord. L'attaquant choisit une clé de session (add_key("rxrpc", …)) pour que decrypt(ciphertext) soit égal à desired_plaintext. Cela produit un STOCKAGE de 8 octets. Cette variante cible /etc/passwd. Elle ne nécessite pas d'espace de noms utilisateur. Elle requiert le module rxrpc.ko (chargé par défaut sur Ubuntu).
Le PoC public cible /usr/bin/su. Il écrit 48 stockages ESP de 4 octets chacun (192 octets au décalage de fichier 0). Il remplace les premiers octets du cache de pages par un ELF de shell root statique. Le point d'entrée de l'ELF exécute setgid(0); setuid(0); setgroups(0,NULL); execve("/bin/sh", …). Un seul execve("/usr/bin/su") donne alors un shell root.
Le correctif ESP (mainline f4c50a4034e6) marque les frags de pages qui arrivent via splice() avec le drapeau SKBFL_SHARED_FRAG. La branche skip_cow dans esp_input() vérifie désormais aussi ce drapeau. Les skbs à frags partagés passent par skb_cow_data() avant le déchiffrement AEAD en place.
Le correctif RxRPC (mainline aa54b1d27fe0) ajoute une vérification skb->data_len à côté de la vérification skb_cloned() existante. Le noyau copie un skb non linéaire avec des données paginées avant le déchiffrement pcbc(fcrypt) en place.
| Composant | Détails |
|---|---|
| Hyperviseur | VirtualBox |
| VM cible | Kali Linux 2026.1 (instantané restauré à un état vulnérable) |
| Noyau | 6.18.9+kali‑amd64 (plus ancien que les correctifs de mai 2026) |
| PoC d'exploit | V4bel/dirtyfrag (fichier C unique) |
| Détection | auditd (règles dans detection/dirtyfrag.rules) |
Capture d'écran de la configuration du laboratoire VirtualBox :
