
PoC : évasion de conteneur totalement non privilégiée vers l'exécution de code au niveau du nœud sur Kubernetes via la corruption du page-cache CVE-2026-31431 + couches d'images partagées. Validé sur Alibaba Cloud ACK, Amazon EKS et Google GKE.
Une preuve de concept démontrant comment un conteneur totalement non privilégié peut obtenir l'exécution de code au niveau du nœud sur Kubernetes en exploitant la vulnérabilité CVE-2026-31431 du noyau Linux (corruption du cache de pages) via des couches d'images conteneur partagées.
La primitive d'attaque de base est la suivante : tout DaemonSet privilégié partageant des couches d'images avec un conteneur contrôlé par l'attaquant peut être utilisé comme arme pour une évasion de conteneur. Ce PoC utilise kube-proxy comme exemple concret, mais la technique se généralise à toute charge de travail privilégiée du cluster.
Validé sur Alibaba Cloud ACK, Amazon EKS et Google GKE — un pod non privilégié écrit [*] success sur le système de fichiers de l'hôte via le DaemonSet privilégié kube-proxy :
| Alibaba Cloud ACK (noyau 6.6.88) | Amazon EKS (noyau 6.12.79) | Google GKE (noyau 6.12.68) |
|---|---|---|
![]() | ![]() | ![]() |
Avertissement : Ce dépôt est publié à des fins exclusivement éducatives et défensives. Utilisez-le exclusivement sur des systèmes que vous possédez ou pour lesquels vous disposez d'une autorisation explicite de test.
CVE-2026-31431 (« Copy Fail ») est une vulnérabilité du noyau Linux dans le chemin Copy-on-Write (CoW) du cache de pages. Une condition de course splice AF_ALG permet à un processus non privilégié de corrompre les pages du cache de pages d'un fichier en lecture seule. La corruption persiste dans le cache de pages du noyau et est visible par tout processus qui lit ou exécute ensuite le fichier — y compris les processus d'autres conteneurs ou de l'hôte.
Pour tous les détails sur la vulnérabilité d'origine, voir copy.fail.
L'attaque exploite trois propriétés qui coexistent couramment dans les clusters Kubernetes :
privileged: true, hostNetwork: true, des capacités étendues, etc.) qui exécutent périodiquement des binaires de leur image.Lorsque ces conditions sont réunies, un pod non privilégié peut corrompre un binaire dans une couche d'image partagée, et un DaemonSet privilégié sur le même nœud exécutera sans le savoir le binaire corrompu avec ses privilèges élevés — aboutissant à une exécution complète de code au niveau du nœud.
La cible de la vulnérabilité n'est PAS limitée à kube-proxy. Tout DaemonSet privilégié (agents de surveillance, plugins CNI, collecteurs de journaux, agents de sécurité, etc.) dont l'image conteneur partage des couches avec une image contrôlée par l'attaquant est une cible viable.
La chaîne d'attaque comporte trois étapes : corruption du cache de pages, propagation entre conteneurs et exécution privilégiée.
Le sous-système AF_ALG (crypto) du noyau expose une interface basée sur des sockets pour les opérations cryptographiques de l'espace utilisateur. L'exploit abuse d'une condition de course dans la façon dont le noyau gère splice() d'un fichier vers une socket AF_ALG :
authencesn(hmac(sha256),cbc(aes)).MSG_MORE, indiquant au noyau d'attendre plus de données.splice() le contenu du fichier cible d'un fd → pipe → socket AF_ALG.L'exploit répète cette opération pour chaque fenêtre de 4 octets jusqu'à ce que toutes les pages en cache du binaire cible soient écrasées par un payload personnalisé.
Aucune permission d'écriture sur le fichier n'est nécessaire. Le fichier sur disque reste inchangé — seul le cache de pages en mémoire est corrompu.
Les runtimes de conteneurs utilisent des systèmes de fichiers overlay. Lorsque deux conteneurs partagent la même couche d'image, le noyau sert leurs lectures de fichiers à partir des mêmes pages du cache de pages.
L'attaquant construit son image PoC FROM la même image de base que le DaemonSet privilégié ciblé. Comme les deux conteneurs partagent le même lowerdir overlay, les binaires de la couche partagée correspondent à des pages du cache de pages identiques.
Lorsque le conteneur PoC non privilégié corrompt le cache de pages d'un binaire, la corruption est immédiatement visible pour le conteneur privilégié sur le même nœud — sans aucune communication entre conteneurs.
Lorsque le DaemonSet privilégié exécute ensuite un binaire corrompu (au cours de son cycle de fonctionnement normal), le noyau charge les pages corrompues du cache de pages. Le payload de l'attaquant s'exécute avec tous les privilèges du DaemonSet — pouvant inclure :
Le payload de ce PoC (payload/payload.c) monte simplement le système de fichiers racine de l'hôte et écrit un fichier marqueur dans /root/res comme preuve de l'exécution de code au niveau du nœud.
┌──────────────────────────┐ ┌──────────────────────────┐
│ PoC Container │ │ Privileged DaemonSet │
│ (unprivileged) │ │ (e.g. kube-proxy, │
│ │ │ monitoring agent, etc.)│
│ 1. Open target binary │ │ │
│ (read-only) │ │ │
│ │ │ │
│ 2. AF_ALG splice race │ │ │
│ corrupts page cache │ │ │
│ │ │ │ │
└──────────┼───────────────┘ └──────────────────────────┘
│ │
▼ │
┌─────────────────────┐ │
│ Kernel Page Cache │ │
│ │◄────────────────────┘
│ Shared-layer binary │ 3. DaemonSet executes the
│ (CORRUPTED) │ corrupted binary
│ contains attacker's │ → loads corrupted pages
│ payload bytes │ → payload runs with
└─────────────────────┘ DaemonSet's privileges
Le PoC a été validé avec succès sur les plateformes Kubernetes gérées suivantes :