Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
harden-docker-seccomp — Mitigazione Docker per CVE-2026-31431 ('Copy Fail'). Include anche template Kubernetes. | Kitploit
Strumenti/GitHubGitHub/devstuff/harden-docker-seccomp
Sicurezza dell'Infrastruttura CloudStrumenti DifensiviSicurezza dei ContenitoriAnalisi delle VulnerabilitàAudit di ConfigurazioneDevSecOps
GitHubdevstuff/harden-docker-seccomp

harden-docker-seccomp

Mitigazione Docker per CVE-2026-31431 ('Copy Fail'). Include anche template Kubernetes.

Vedi Repository
2144 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

harden-docker-seccomp

Script idempotente per bloccare la creazione di socket AF_ALG per tutti i container Docker su un host come mitigazione per CVE-2026-31431 ("Copy Fail").

Contesto

CVE-2026-31431 è un'escalation di privilegi locale nel template crittografico authencesn del kernel Linux, presente nei kernel compilati tra il 2017 e la disponibilità della correzione upstream (commit mainline a664bf3d603d). Un utente non privilegiato può concatenare un'operazione su socket AF_ALG con splice() per eseguire una scrittura controllata di 4 byte nella cache delle pagine di qualsiasi file leggibile, prendendo di mira un binario setuid per ottenere una shell di root. Una proof of concept Python di 732 byte sfrutta questa vulnerabilità in modo affidabile, senza race condition o offset per distribuzione, su ogni principale distribuzione Linux che include un kernel vulnerabile.

Il primo passo obbligatorio dell'exploit è l'apertura di un socket AF_ALG (socket(AF_ALG, SOCK_SEQPACKET, 0)). Bloccare quella syscall tramite seccomp previene lo sfruttamento anche su kernel non patchati. Il profilo seccomp predefinito integrato di Docker non blocca , e non è sufficiente — i cluster testati hanno mostrato che i pod ammessi sotto PSS Restricted potevano comunque aprire socket .

AF_ALG
RuntimeDefault
AF_ALG

Vedi l'advisory del ricercatore originale su https://copy.fail e l'advisory CERT-EU su https://cert.europa.eu/publications/security-advisories/2026-005/ per i dettagli tecnici completi e la disponibilità delle patch per distribuzione.

Ambito di questo strumento

Questo script copre la configurazione globale del daemon Docker Engine. Per Kubernetes, vedi la sezione Kubernetes qui sotto. Per carichi di lavoro bare-metal o VM (non containerizzati), disabilita invece il modulo del kernel algif_aead:

root@kitploit:~
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif.conf
rmmod algif_aead 2>/dev/null || true

Questo approccio non ha alcun impatto su dm-crypt/LUKS, kTLS, IPsec/XFRM, OpenSSL, GnuTLS, NSS o SSH.

Come funziona

  1. Estrae il profilo seccomp predefinito attivo di Docker ispezionando il HostConfig.SecurityOpt di un container di breve durata. Questo evita qualsiasi dipendenza da un URL remoto e garantisce che il profilo di base corrisponda alla versione di Docker effettivamente installata. Un fetch da GitHub da moby/profiles viene usato come fallback solo se l'ispezione del container non produce risultati.

  2. Applica una patch al profilo rimuovendo socket dalla voce allowlist di Docker e riaggiungendolo con un filtro sugli argomenti che consente tutte le famiglie di indirizzi tranne AF_ALG (valore 38) usando SCMP_CMP_NE. Tutto il resto del comportamento seccomp predefinito di Docker viene preservato.

  3. Scrive il profilo patchato atomicamente in /etc/seccomp/docker-block-af-alg.json (file temporaneo + rinomina). Viene saltato se il contenuto su disco è già identico.

  4. Aggiorna /etc/docker/daemon.json per impostare "seccomp-profile" sul percorso del profilo patchato. Il file originale viene salvato come backup in daemon.json.bak alla prima modifica. Viene saltato se già configurato correttamente.

  5. Ricarica dockerd tramite systemctl reload docker (SIGHUP — nessun riavvio richiesto). Viene saltato se nessuno dei due file è cambiato.

  6. Verifica che il blocco sia attivo eseguendo una sonda all'interno di un container, indipendentemente dal fatto che siano state apportate modifiche nei passaggi precedenti.

Lo script è idempotente: eseguirlo più volte produce lo stesso risultato e ricarica Docker solo quando qualcosa è effettivamente cambiato.

Nota: i container --privileged bypassano tutti i profili seccomp indipendentemente da questa configurazione. Controlla separatamente i tuoi file Compose e i comandi di esecuzione per i container privilegiati.

Requisiti

  • Python 3.12+
  • Docker Engine (non Docker Desktop) in esecuzione sull'host
  • CLI docker nel PATH
  • curl nel PATH (solo fallback)
  • systemctl (host systemd)
  • Root / sudo per le scritture in /etc/seccomp e /etc/docker, e per systemctl reload docker

Utilizzo

root@kitploit:~
# Applica la mitigazione e verifica (utilizzo normale)
sudo python3 harden-docker-seccomp.py

# Mostra cosa cambierebbe senza scrivere nulla o ricaricare Docker
sudo python3 harden-docker-seccomp.py --dry-run

# Esegui solo la verifica del container (nessuna modifica alla configurazione)
python3 harden-docker-seccomp.py --verify-only

# Output verboso
sudo python3 harden-docker-seccomp.py --verbose

Output previsto (prima esecuzione)

root@kitploit:~
INFO Written: /etc/seccomp/docker-block-af-alg.json
INFO Updated: /etc/docker/daemon.json
INFO Reloading Docker daemon (SIGHUP)…
INFO Docker daemon reloaded.
INFO Verifying AF_ALG is blocked inside a container…
OK: AF_ALG blocked — [Errno 1] Operation not permitted
INFO All done. CVE-2026-31431 (Copy Fail) mitigation is active.

Output previsto (esecuzioni successive)

root@kitploit:~
INFO Profile unchanged: /etc/seccomp/docker-block-af-alg.json
INFO daemon.json already configured correctly.
INFO No changes — Docker daemon reload not required.
INFO Verifying AF_ALG is blocked inside a container…
OK: AF_ALG blocked — [Errno 1] Operation not permitted
INFO All done. CVE-2026-31431 (Copy Fail) mitigation is active.

Codici di uscita

CodiceSignificato
0Successo — la mitigazione è attiva
1Script non eseguito come root (durante la patch), o errore irreversibile
2Verifica fallita — AF_ALG non è bloccato

Kubernetes

I pod Kubernetes condividono il kernel dell'host, quindi la stessa primitiva del socket AF_ALG è raggiungibile da qualsiasi pod su un nodo vulnerabile. Il seccomp RuntimeDefault non è sufficiente — i cluster testati hanno mostrato che i pod ammessi sotto PSS Restricted potevano comunque aprire socket AF_ALG. È richiesto un profilo Localhost con una regola di deny esplicita.

La mitigazione richiede due cose: il JSON del profilo presente sul filesystem di ogni nodo, e ogni spec di pod che lo referenzi. Le sezioni seguenti coprono entrambe, incluso come iniettare il profilo globalmente senza modificare gli spec dei singoli pod.

Passo 1 — Distribuisci il profilo su ogni nodo

Il kubelet risolve i profili seccomp Localhost relativamente alla sua root seccomp, che per impostazione predefinita è /var/lib/kubelet/seccomp. Il profilo deve esistere a quel percorso su ogni nodo che può pianificare un carico di lavoro.

Applica il ConfigMap e il DaemonSet da questo repository:

root@kitploit:~
kubectl apply -f templates/configmap-seccomp-profile.yaml
kubectl apply -f templates/daemonset-distribute-profile.yaml

Il DaemonSet esegue un container init che copia il profilo dal ConfigMap alla root seccomp del kubelet del nodo, poi parcheggia un container pause minimale così il pod rimane visibile per il monitoraggio della salute. Tollera tutti i taint così viene eseguito anche sui nodi control-plane.

Root seccomp kubelet non standard: RKE2 usa /var/lib/rancher/rke2/agent/kubelet/seccomp. Sovrascrivi il percorso impostando NODE_SECCOMP_ROOT nell'env del container init del DaemonSet prima di applicare.

Verifica che il file sia presente su un nodo:

root@kitploit:~
kubectl -n kube-system exec -it \
  $(kubectl -n kube-system get pod -l app.kubernetes.io/name=distribute-af-alg-seccomp \
    -o jsonpath='{.items[0].metadata.name}') -- \
  cat /var/lib/kubelet/seccomp/block-af-alg.json

Passo 2 — Inietta il profilo in ogni pod (nessuna modifica agli spec dei pod richiesta)

Invece di modificare i singoli spec dei pod o i chart Helm, usa un webhook di ammissione mutante per iniettare seccompProfile automaticamente al momento dell'ammissione. Sono fornite due opzioni: Kyverno e OPA Gatekeeper.

Entrambi gli approcci iniettano il profilo solo quando un pod non ne dichiara già uno, quindi i pod con profili espliciti vengono lasciati intatti.

Importante: I pod esistenti in esecuzione non vengono mutati retroattivamente. Dopo aver applicato la policy, fai un rollout dei tuoi deployment per applicare il profilo iniettato:

root@kitploit:~
kubectl rollout restart deployment -A

Opzione A — Kyverno

Questo template usa l'API MutatingPolicy (policies.kyverno.io/v1), che ha raggiunto la GA in Kyverno 1.17. L'API legacy ClusterPolicy (kyverno.io/v1) è stata deprecata in Kyverno 1.17 (gennaio 2026) ed è prevista per la rimozione in 1.20 (ottobre 2026); non usarla per nuove policy.

L'espressione CEL matchConditions verifica che seccompProfile sia assente prima di mutare, quindi i pod che dichiarano già un profilo vengono lasciati intatti.

root@kitploit:~
# Installa Kyverno (se non già presente)
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm upgrade --install kyverno kyverno/kyverno -n kyverno --create-namespace

# Applica la policy
kubectl apply -f templates/kyverno-mutate-seccomp.yaml

Verifica che un nuovo pod riceva il profilo iniettato:

root@kitploit:~
kubectl run test --image=busybox --restart=Never -- sleep 30
kubectl get pod test -o jsonpath='{.spec.securityContext.seccompProfile}'
# Previsto: {"localhostProfile":"block-af-alg.json","type":"Localhost"}
kubectl delete pod test

Vedi templates/kyverno-mutate-seccomp.yaml.

Opzione B — OPA Gatekeeper

Il CRD di mutazione Assign di Gatekeeper usa una condizione pathTests per iniettare il profilo solo quando spec.securityContext.seccompProfile non esiste già. La mutazione è stabile da Gatekeeper 3.10+; nessun flag di funzionalità è richiesto.

root@kitploit:~
# Installa Gatekeeper (se non già presente)
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
helm repo update
helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper \
  --create-namespace

# Applica la mutazione
kubectl apply -f templates/gatekeeper-assign-seccomp.yaml

Verifica:

root@kitploit:~
kubectl run test --image=busybox --restart=Never -- sleep 30
kubectl get pod test -o jsonpath='{.spec.securityContext.seccompProfile}'
# Previsto: {"localhostProfile":"block-af-alg.json","type":"Localhost"}
kubectl delete pod test

Vedi templates/gatekeeper-assign-seccomp.yaml.

Gatekeeper vs. Kyverno: L'approccio Assign opera a livello di campo e richiede che il webhook di mutazione di Gatekeeper sia abilitato. Il MutatingPolicy di Kyverno con un matchCondition CEL gestisce la condizione inline. Entrambi ottengono lo stesso risultato — preferisci quello già distribuito nel tuo cluster.

Cosa questo non copre

I pod con hostPID: true, hostNetwork: true o securityContext.privileged: true hanno accesso elevato che il solo seccomp non contiene completamente. Controlla quei carichi di lavoro separatamente e rimuovi i privilegi dove possibile.

Note di progettazione dei template

ConfigMap come fonte di verità. Il JSON del profilo vive in configmap-seccomp-profile.yaml invece di essere incorporato nel DaemonSet o duplicato tra i file. Il DaemonSet lo monta e lo copia sul nodo. Aggiornare il profilo significa modificare un ConfigMap e riavviare i pod del DaemonSet — nessun altro file cambia.

Il DaemonSet usa la priorità system-node-critical. Questo garantisce che il pod di distribuzione non venga sfrattato prima che i carichi di lavoro che protegge vengano pianificati, il che lascerebbe i nodi con un file di profilo mancante e i pod bloccati in CreateContainerError.

Gatekeeper esclude kube-system e gatekeeper-system. Iniettare un profilo Localhost nei pod di sistema che potrebbero precedere l'installazione del DaemonSet rischia un riferimento a un profilo rotto se il file non è ancora presente sul nodo. La policy Kyverno non ha bisogno di questa esclusione perché Kyverno gestisce l'ordinamento dei webhook in modo più elegante, ma le regole exclude possono essere aggiunte anche lì se necessario.

Iniezione condizionale, non sovrascrittura. Sia il matchCondition CEL del MutatingPolicy di Kyverno che il test di percorso MustNotExist di Gatekeeper significano che la policy di ammissione agisce solo quando un pod non ha un seccompProfile esistente. I carichi di lavoro che dichiarano già il proprio profilo — inclusi quelli che legittimamente necessitano di AF_ALG tramite una allow-list personalizzata — vengono lasciati intatti.

Riferimenti

  • https://copy.fail — Advisory del ricercatore originale (Xint)
  • https://cert.europa.eu/publications/security-advisories/2026-005/ — Advisory CERT-EU
  • https://www.cve.org/CVERecord?id=CVE-2026-31431 — Record CVE
  • https://security-tracker.debian.org/tracker/CVE-2026-31431 — Tracker di sicurezza Debian
  • https://docs.docker.com/engine/security/seccomp/ — Documentazione seccomp di Docker
  • https://github.com/moby/profiles — Profilo seccomp predefinito canonico di Docker
  • https://kyverno.io/docs/kyverno-policies/ — Documentazione delle policy Kyverno
  • https://open-policy-agent.github.io/gatekeeper/website/docs/mutation/ — Documentazione della mutazione Gatekeeper

Sì, Claude ha fatto la maggior parte del lavoro, ecco la chat

https://gist.github.com/devstuff/3ff3ca0139e2a2da7f1ee5875802f76f

Scarica lo strumento