
Une implémentation Go de dirtyfrag (CVE-2026-43284 / CVE-2026-43500)
Deux bugs. Un shell. Aucune écriture disque.
Portage Go de dirtyfrag (CVE-2026-43284 / CVE-2026-43500).
La classe de bug se trouve dans le sous-système XFRM du noyau Linux. Lorsqu'une page de fichier est splice()ée dans un pipe puis dans un socket chiffré ESP, le noyau déchiffre la charge utile ESP en place - directement dans la page du cache de pages du fichier source. Le fichier est en lecture seule. Le cache de pages ne l'est pas.
dirtyfrag enchaîne deux bugs indépendants exploitant cette primitive :
CVE-2026-43284 - Chemin ESP/XFRM
Installe 48 AS (Associations de Sécurité) en mode transport XFRM via NETLINK_XFRM. Chaque AS encode 4 octets de charge utile du shellcode dans le champ seq_hi de son état de rejeu ESN. Une chaîne vmsplice + splice déclenche le déchiffrement ESP en place pour chaque AS, écrivant ces 4 octets dans l'entrée du cache de pages de /usr/bin/su. 48 déclenchements, 192 octets écrits, aucune condition de concurrence.
CVE-2026-43500 - Chemin RxRPC/rxkad
Effectue une recherche par force brute de 3 clés de session PCBC(fcrypt) hors ligne qui produisent les séquences d'octets cibles lors du déchiffrement. Déclenche une socket AF_RXRPC pour chaque clé afin de patcher l'entrée racine dans /etc/passwd en root::0:0 (nullok). su - accepte alors un mot de passe vide.
Les deux chemins s'exécutent dans un espace de noms utilisateur + réseau (CLONE_NEWUSER | CLONE_NEWNET) pour éviter de nécessiter CAP_NET_ADMIN sur l'hôte.
go build -o dirtyfrag-go .
./dirtyfrag-go
# Forcer un chemin spécifique
./dirtyfrag-go --force-esp
./dirtyfrag-go --force-rxrpc
# Sortie verbeuse
./dirtyfrag-go -v
Le binaire essaie d'abord le chemin ESP. Si /usr/bin/su n'est pas patché après, il se rabat sur le chemin RxRPC (jusqu'à 3 tentatives). En cas de succès, il ouvre un shell root via un nouveau PTY.
L'exploit ne touche que le cache de pages. Les binaires sur disque et /etc/passwd ne sont pas modifiés. Un redémarrage restaure tout. Pour évincer immédiatement sans redémarrer :
echo 1 | tee /proc/sys/vm/drop_caches
esp4, esp6 (chemin ESP) et/ou rxrpc (chemin RxRPC)Tous les noyaux avant les correctifs :
rmmod esp4 esp6 rxrpc
printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' \
> /etc/modprobe.d/dirtyfrag.conf
Le runtime Go est multi-threadé dès le départ, donc unshare(CLONE_NEWUSER) n'est pas autorisé. Le port Go se réexécute lui-même en tant que processus enfant avec SysProcAttr.Cloneflags défini, ce qui appelle clone() avant l'initialisation du runtime Go.
| C (original) | Go |
|---|
| Dépendances externes | Aucune | Aucune |
| Fichier unique | Non | Non |
| Binaire statique | Oui | Oui |
| Chemin RxRPC | Oui | Oui |
| Chemin ESP | Oui | Oui |
| Isolation d'espace de noms | unshare() | réexécution avec Cloneflags |