Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
harden-docker-seccomp — Mitigação do Docker para CVE-2026-31431 ('Copy Fail'). Inclui também modelos Kubernetes. | Kitploit
Ferramentas/GitHubGitHub/devstuff/harden-docker-seccomp
Segurança de Infraestrutura em NuvemFerramentas DefensivasSegurança de ContêineresAnálise de VulnerabilidadesAuditoria de ConfiguraçãoDevSecOps
GitHubdevstuff/harden-docker-seccomp

harden-docker-seccomp

Mitigação do Docker para CVE-2026-31431 ('Copy Fail'). Inclui também modelos Kubernetes.

Ver Repositório
21há 3 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

harden-docker-seccomp

Script idempotente para bloquear a criação de sockets AF_ALG para todos os contêineres Docker em um host como mitigação para CVE-2026-31431 ("Copy Fail").

Contexto

A CVE-2026-31431 é uma escalada de privilégio local no template criptográfico authencesn do kernel Linux, presente em kernels compilados entre 2017 e a disponibilidade da correção upstream (commit mainline a664bf3d603d). Um usuário sem privilégios pode encadear uma operação de socket AF_ALG com splice() para realizar uma escrita controlada de 4 bytes no cache de páginas de qualquer arquivo legível, visando um binário setuid para obter um shell root. Uma prova de conceito em Python de 732 bytes explora isso de forma confiável, sem corridas ou offsets por distribuição, em todas as principais distribuições Linux que possuem um kernel afetado.

O primeiro passo obrigatório do exploit é abrir um socket AF_ALG (socket(AF_ALG, SOCK_SEQPACKET, 0)). Bloquear essa syscall via seccomp impede a exploração mesmo em kernels sem correção. O perfil seccomp padrão integrado do Docker não bloqueia , e não é suficiente — clusters testados mostraram que pods admitidos sob PSS Restricted ainda podiam abrir sockets .

AF_ALG
RuntimeDefault
AF_ALG

Consulte o advisory do pesquisador original em https://copy.fail e o advisory da CERT-EU em https://cert.europa.eu/publications/security-advisories/2026-005/ para detalhes técnicos completos e disponibilidade de correção por distribuição.

Escopo desta ferramenta

Este script cobre a configuração global do daemon do Docker Engine. Para Kubernetes, consulte a seção Kubernetes abaixo. Para cargas de trabalho bare-metal ou VM (não containerizadas), desative o módulo do kernel algif_aead em vez disso:

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

Essa abordagem não tem impacto em dm-crypt/LUKS, kTLS, IPsec/XFRM, OpenSSL, GnuTLS, NSS ou SSH.

Como funciona

  1. Extrai o perfil seccomp padrão integrado ativo do Docker inspecionando o HostConfig.SecurityOpt de um contêiner de curta duração. Isso evita qualquer dependência de uma URL remota e garante que o perfil base corresponda à versão do Docker realmente instalada. Uma busca no GitHub em moby/profiles é usada como fallback apenas se a inspeção do contêiner não retornar nada.

  2. Corrige o perfil removendo socket da entrada de allowlist do Docker e o adicionando novamente com um filtro de argumento que permite todas as famílias de endereços exceto AF_ALG (valor 38) usando SCMP_CMP_NE. Todo o resto do comportamento seccomp padrão do Docker é preservado.

  3. Grava o perfil corrigido atomicamente em /etc/seccomp/docker-block-af-alg.json (arquivo temporário + rename). Ignorado se o conteúdo no disco já for idêntico.

  4. Atualiza /etc/docker/daemon.json para definir "seccomp-profile" como o caminho do perfil corrigido. O arquivo original é copiado para daemon.json.bak na primeira modificação. Ignorado se já estiver configurado corretamente.

  5. Recarrega o dockerd via systemctl reload docker (SIGHUP — sem necessidade de reinicialização). Ignorado se nenhum dos arquivos foi alterado.

  6. Verifica se o bloqueio está ativo executando uma sonda dentro de um contêiner, independentemente de quaisquer alterações feitas nas etapas acima.

O script é idempotente: executá-lo várias vezes produz o mesmo resultado e só recarrega o Docker quando algo realmente mudou.

Nota: Contêineres --privileged ignoram todos os perfis seccomp, independentemente desta configuração. Audite seus arquivos Compose e comandos de execução para contêineres privilegiados separadamente.

Requisitos

  • Python 3.12+
  • Docker Engine (não Docker Desktop) em execução no host
  • CLI docker no PATH
  • curl no PATH (apenas fallback)
  • systemctl (host systemd)
  • Root / sudo para gravações em /etc/seccomp e /etc/docker, e para systemctl reload docker

Uso

root@kitploit:~
# Aplicar a mitigação e verificar (uso normal)
sudo python3 harden-docker-seccomp.py

# Mostrar o que mudaria sem gravar nada ou recarregar o Docker
sudo python3 harden-docker-seccomp.py --dry-run

# Re-executar apenas a verificação do contêiner (sem alterações de configuração)
python3 harden-docker-seccomp.py --verify-only

# Saída detalhada
sudo python3 harden-docker-seccomp.py --verbose

Saída esperada (primeira execução)

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.

Saída esperada (execuções subsequentes)

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.

Códigos de saída

CódigoSignificado
0Sucesso — a mitigação está ativa
1Script não executado como root (ao corrigir), ou erro irrecuperável
2Falha na verificação — AF_ALG não está bloqueado

Kubernetes

Os pods do Kubernetes compartilham o kernel do host, portanto, o mesmo primitivo de socket AF_ALG é acessível a partir de qualquer pod em um nó afetado. O seccomp RuntimeDefault não é suficiente — clusters testados mostraram que pods admitidos sob PSS Restricted ainda podiam abrir sockets AF_ALG. Um perfil Localhost com uma regra de negação explícita é necessário.

A mitigação requer duas coisas: o JSON do perfil presente no sistema de arquivos de cada nó, e cada spec de pod referenciando-o. As seções abaixo cobrem ambos, incluindo como injetar o perfil globalmente sem modificar specs de pods individuais.

Etapa 1 — Distribuir o perfil para cada nó

O kubelet resolve perfis seccomp Localhost em relação à sua raiz seccomp, que por padrão é /var/lib/kubelet/seccomp. O perfil deve existir nesse caminho em cada nó que possa agendar uma carga de trabalho.

Aplique o ConfigMap e o DaemonSet deste repositório:

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

O DaemonSet executa um contêiner init que copia o perfil do ConfigMap para a raiz seccomp do kubelet do nó e, em seguida, estaciona um contêiner pause mínimo para que o pod permaneça visível para monitoramento de saúde. Ele tolera todos os taints para que também seja executado em nós do plano de controle.

Raiz seccomp do kubelet não padrão: RKE2 usa /var/lib/rancher/rke2/agent/kubelet/seccomp. Substitua o caminho definindo NODE_SECCOMP_ROOT no env do contêiner init do DaemonSet antes de aplicar.

Verifique se o arquivo está presente em um nó:

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

Etapa 2 — Injetar o perfil em cada pod (sem alterações no spec do pod)

Em vez de modificar specs de pods individuais ou Helm charts, use um webhook de admissão mutante para injetar seccompProfile automaticamente no momento da admissão. Duas opções são fornecidas: Kyverno e OPA Gatekeeper.

Ambas as abordagens só injetam o perfil quando um pod ainda não declara um, portanto, pods com perfis explícitos são deixados intactos.

Importante: Pods existentes em execução não são mutados retroativamente. Após aplicar a política, reinicie seus deployments para aplicar o perfil injetado:

root@kitploit:~
kubectl rollout restart deployment -A

Opção A — Kyverno

Este template usa a API MutatingPolicy (policies.kyverno.io/v1), que atingiu GA no Kyverno 1.17. A API legada ClusterPolicy (kyverno.io/v1) foi descontinuada no Kyverno 1.17 (janeiro de 2026) e está planejada para remoção no 1.20 (outubro de 2026); não a use para novas políticas.

A expressão CEL matchConditions verifica se seccompProfile está ausente antes de mutar, portanto, pods que já declaram um perfil são deixados intactos.

root@kitploit:~
# Instalar Kyverno (se ainda não estiver presente)
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm upgrade --install kyverno kyverno/kyverno -n kyverno --create-namespace

# Aplicar a política
kubectl apply -f templates/kyverno-mutate-seccomp.yaml

Verifique se um novo pod recebe o perfil injetado:

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

Consulte templates/kyverno-mutate-seccomp.yaml.

Opção B — OPA Gatekeeper

O CRD de mutação Assign do Gatekeeper usa uma condição pathTests para injetar o perfil apenas quando spec.securityContext.seccompProfile ainda não existe. A mutação é estável desde o Gatekeeper 3.10+; nenhum feature flag é necessário.

root@kitploit:~
# Instalar Gatekeeper (se ainda não estiver 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

# Aplicar a mutação
kubectl apply -f templates/gatekeeper-assign-seccomp.yaml

Verifique:

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

Consulte templates/gatekeeper-assign-seccomp.yaml.

Gatekeeper vs. Kyverno: A abordagem Assign opera no nível do campo e requer que o webhook de mutação do Gatekeeper esteja habilitado. O MutatingPolicy do Kyverno com um matchCondition CEL lida com o condicional inline. Qualquer um alcança o mesmo resultado — prefira o que já estiver implantado em seu cluster.

O que isso não cobre

Pods com hostPID: true, hostNetwork: true ou securityContext.privileged: true têm acesso elevado que o seccomp sozinho não contém completamente. Audite essas cargas de trabalho separadamente e remova privilégios quando possível.

Notas de design do template

ConfigMap como fonte da verdade. O JSON do perfil reside em configmap-seccomp-profile.yaml em vez de ser embutido no DaemonSet ou duplicado entre arquivos. O DaemonSet o monta e o copia para o nó. Atualizar o perfil significa editar um ConfigMap e reiniciar os pods do DaemonSet — nenhum outro arquivo muda.

O DaemonSet usa prioridade system-node-critical. Isso garante que o pod de distribuição não seja despejado antes que as cargas de trabalho que ele protege sejam agendadas, o que deixaria nós com um arquivo de perfil ausente e pods travados em CreateContainerError.

O Gatekeeper exclui kube-system e gatekeeper-system. Injetar um perfil Localhost em pods do sistema que podem ser anteriores à instalação do DaemonSet arrisca uma referência de perfil quebrada se o arquivo ainda não estiver presente no nó. A política do Kyverno não precisa dessa exclusão porque o Kyverno lida com a ordenação de webhooks de forma mais graciosa, mas regras exclude podem ser adicionadas lá também, se necessário.

Injeção condicional, não substituição. Tanto o matchCondition CEL do MutatingPolicy do Kyverno quanto o teste de caminho MustNotExist do Gatekeeper significam que a política de admissão só age quando um pod não tem seccompProfile existente. Cargas de trabalho que já declaram seu próprio perfil — incluindo aquelas que legitimamente precisam de AF_ALG via uma allowlist personalizada — são deixadas intactas.

Referências

  • https://copy.fail — Advisory do pesquisador original (Xint)
  • https://cert.europa.eu/publications/security-advisories/2026-005/ — Advisory da CERT-EU
  • https://www.cve.org/CVERecord?id=CVE-2026-31431 — Registro da CVE
  • https://security-tracker.debian.org/tracker/CVE-2026-31431 — Rastreador de segurança do Debian
  • https://docs.docker.com/engine/security/seccomp/ — Documentação de seccomp do Docker
  • https://github.com/moby/profiles — Perfil seccomp padrão canônico do Docker
  • https://kyverno.io/docs/kyverno-policies/ — Documentação de políticas do Kyverno
  • https://open-policy-agent.github.io/gatekeeper/website/docs/mutation/ — Documentação de mutação do Gatekeeper

Sim, o Claude fez a maior parte do trabalho, aqui está o chat

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

Baixar ferramenta