
PoC: fuga da container completamente non privilegiata a esecuzione di codice a livello di nodo su Kubernetes tramite CVE-2026-31431 corruzione della cache delle pagine + livelli di immagini condivisi. Validato su Alibaba Cloud ACK, Amazon EKS e Google GKE.
Un proof-of-concept che dimostra come un container completamente non privilegiato possa ottenere esecuzione di codice a livello di nodo su Kubernetes sfruttando il bug di corruzione della page-cache del kernel Linux CVE-2026-31431 tramite layer di immagini condivise.
La primitiva di attacco principale è: qualsiasi DaemonSet privilegiato che condivide layer di immagini con un container controllato dall'attaccante può essere armato per l'escape dal container. Questo PoC utilizza kube-proxy come esempio concreto, ma la tecnica si generalizza a qualsiasi carico di lavoro privilegiato nel cluster.
Validato su Alibaba Cloud ACK, Amazon EKS e Google GKE — un pod non privilegiato scrive [*] success nel filesystem dell'host tramite il DaemonSet privilegiato kube-proxy:
| Alibaba Cloud ACK (kernel 6.6.88) | Amazon EKS (kernel 6.12.79) | Google GKE (kernel 6.12.68) |
|---|---|---|
![]() | ![]() | ![]() |
Nota: Questo repository è pubblicato solo a scopo educativo e difensivo. Utilizzalo esclusivamente su sistemi di tua proprietà o per i quali hai esplicita autorizzazione al test.
CVE-2026-31431 ("Copy Fail") è una vulnerabilità del kernel Linux nel percorso Copy-on-Write (CoW) della page-cache. Una race condition AF_ALG splice permette a un processo non privilegiato di corrompere le pagine della page-cache di un file sola lettura. La corruzione persiste nella cache delle pagine del kernel ed è visibile a qualsiasi processo che successivamente legge o esegue il file — inclusi i processi in altri container o sull'host.
Per tutti i dettagli sulla vulnerabilità originale, consulta copy.fail.
L'attacco sfrutta tre proprietà che comunemente coesistono nei cluster Kubernetes:
privileged: true, hostNetwork: true, capacità estese, ecc.) che eseguono periodicamente binari dalla loro immagine.Quando queste condizioni si allineano, un pod non privilegiato può corrompere un binario in un layer di immagine condiviso, e un DaemonSet privilegiato sullo stesso nodo eseguirà inconsapevolmente il binario corrotto con i suoi privilegi elevati — ottenendo la piena esecuzione di codice a livello di nodo.
Il bersaglio della vulnerabilità NON è limitato a kube-proxy. Qualsiasi DaemonSet privilegiato (agenti di monitoraggio, plugin CNI, collettori di log, agenti di sicurezza, ecc.) la cui immagine del container condivide layer con un'immagine controllata dall'attaccante è un bersaglio valido.
La catena di attacco ha tre fasi: corruzione della page-cache, propagazione cross-container ed esecuzione privilegiata.
Il sottosistema AF_ALG (crittografia) del kernel espone un'interfaccia basata su socket per operazioni crittografiche in spazio utente. L'exploit abusa di una race condition nel modo in cui il kernel gestisce splice() da un file in un socket AF_ALG:
authencesn(hmac(sha256),cbc(aes)).MSG_MORE, dicendo al kernel di aspettarsi più dati.splice() il contenuto del file target da un fd → pipe → socket AF_ALG.L'exploit ripete questa operazione per ogni finestra di 4 byte fino a quando tutte le pagine nella cache del binario target non vengono sovrascritte con un payload personalizzato.
Non è necessaria alcuna autorizzazione di scrittura sul file. Il file su disco rimane invariato — solo la cache delle pagine in memoria viene corrotta.
I runtime dei container utilizzano filesystem overlay. Quando due container condividono lo stesso layer di immagine, il kernel serve le letture dei loro file dalle stesse pagine della page-cache.
L'attaccante costruisce la propria immagine PoC FROM la stessa immagine base del DaemonSet privilegiato target. Poiché entrambi i container condividono lo stesso lower-dir overlay, i binari nel layer condiviso mappano a pagine della page-cache identiche.
Quando il container PoC non privilegiato corrompe la page-cache di un binario, la corruzione è immediatamente visibile al container privilegiato sullo stesso nodo — con zero comunicazione cross-container.
Quando il DaemonSet privilegiato esegue successivamente un binario corrotto (attraverso il suo normale ciclo operativo), il kernel carica le pagine corrotte della page-cache. Il payload dell'attaccante viene eseguito con tutti i privilegi del DaemonSet — includendo potenzialmente:
Il payload in questo PoC (payload/payload.c) monta semplicemente il filesystem root dell'host e scrive un file marker in /root/res come prova dell'esecuzione di codice a livello di nodo.
┌──────────────────────────┐ ┌──────────────────────────┐
│ Container PoC │ │ DaemonSet Privilegiato │
│ (non privilegiato) │ │ (es. kube-proxy, │
│ │ │ agente di monitoraggio)│
│ 1. Apri binario target │ │ │
│ (sola lettura) │ │ │
│ │ │ │
│ 2. Race condition │ │ │
│ AF_ALG splice │ │ │
│ corrompe page-cache │ │ │
│ │ │ │ │
└──────────┼───────────────┘ └──────────────────────────┘
│ │
▼ │
┌─────────────────────┐ │
│ Pagine del Kernel │ │
│ (Page Cache) │ │
│ │◄────────────────────┘
│ Binario del layer │ 3. Il DaemonSet esegue il
│ condiviso │ binario corrotto
│ (CORROTTO) │ → carica pagine corrotte
│ contiene byte │ → payload eseguito con
│ del payload │ privilegi del DaemonSet
└─────────────────────┘
Il PoC è stato validato con successo sulle seguenti piattaforme Kubernetes gestite: