Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
copy-fail-blocker — BPF-LSM mitigación para CVE-2026-31431 (Copy Fail) — deniega la creación de sockets AF_ALG en todo el clúster | Kitploit
Herramientas/GitHubGitHub/cozystack/copy-fail-blocker
Herramientas DefensivasSeguridad de ContenedoresAnálisis de VulnerabilidadesSeguridad de RedesSeguridad en la Nube
GitHubcozystack/copy-fail-blocker

copy-fail-blocker

BPF-LSM mitigación para CVE-2026-31431 (Copy Fail) — deniega la creación de sockets AF_ALG en todo el clúster

Ver Repositorio
345hace 3 mesesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

copy-fail-blocker

Mitigación BPF-LSM para CVE-2026-31431 ("Copy Fail") y la variante RxRPC de Dirty Frag, y para vulnerabilidades similares de escalada de privilegios que dependen del acceso de espacio de usuario a una ruta criptográfica in-place del lado del kernel accesible a través de las familias de sockets AF_ALG o AF_RXRPC.

Un pequeño DaemonSet adjunta un único programa BPF-LSM al hook socket_create en cada nodo. El programa devuelve -EPERM para cualquier llamada socket(AF_ALG, ...) o socket(AF_RXRPC, ...) de espacio de usuario, independientemente de las capacidades del proceso, el namespace o el perfil seccomp. Los llamadores internos del kernel sock_create_kern() (p. ej. fs/afs, la pila IPsec) sí pueden pasar, por lo que los usuarios legítimos dentro del kernel siguen funcionando.

Probado en Talos Linux (que incluye CONFIG_BPF_LSM=y y bpf en la pila LSM predeterminada desde v1.10), funciona en cualquier distribución con la misma configuración de kernel.

Por qué

Copy Fail (CVE-2026-31431) es un fallo lógico en algif_aead que permite a un usuario local sin privilegios realizar una escritura de 4 bytes en la caché de páginas de cualquier binario setuid, logrando root con un script Python de 732 bytes. El exploit solo necesita AF_ALG + splice(), ambos accesibles desde cualquier proceso sin privilegios por defecto. El fix en mainline es a664bf3d603d.

Dirty Frag es una clase de vulnerabilidad posterior divulgada en mayo de 2026 por la misma línea de investigación. Encadena dos bugs que "ensucian" el miembro frag de sk_buff — xfrm-ESP Page-Cache Write y RxRPC Page-Cache Write. La variante RxRPC realiza un descifrado pcbc(fcrypt) in-place sobre una página de caché de páginas fijada con splice() dentro de rxkad_verify_packet_1() y alcanza root sin necesidad de crear namespaces de usuario, lo que la convierte en la mitad más explotable universalmente de la cadena en distribuciones endurecidas. El fix de xfrm-ESP llegó a netdev como f4c50a4034e6 (2026-05-07); las distribuciones aún están haciendo backport al momento de escribir esto, y RxRPC no tiene fix público todavía — consulta el write-up upstream para la cronología de divulgación.

Ambos exploits dependen de abrir un socket en la familia afectada. Hasta que los fixes del kernel lleguen a tu distribución, la superficie de ataque se puede eliminar impidiendo que el espacio de usuario cree sockets AF_ALG o AF_RXRPC. Comparado con las alternativas:

MitigaciónCobertura¿Reinicio?¿Persiste?
Línea de comandos del kernel module_blacklist=af_alg,rxrpc (manejadores de familia, no solo algif_aead)todo el hostsísí
/etc/modprobe.d/*.conf con install af_alg /bin/false + install rxrpc /bin/false y rmmod de los módulos ya cargados (coincide con la guía upstream de Dirty Frag — ten en cuenta que blacklist simple no detiene el autoload request_module() dentro del kernel, solo install … /bin/false lo hace)todo el hostnosí (mientras el archivo esté presente)
Kernel personalizado sin CRYPTO_USER_API / AF_RXRPCtodo el hostsísí
Perfil seccomp personalizado por podsolo cargas de trabajo etiquetadasnosí
copy-fail-blocker (este proyecto)espacio de usuario en todo el hostnomientras el DS se ejecute

Este proyecto es la opción sin reinicio. Ejecútalo en todo el clúster y luego planifica los fixes permanentes del kernel en tu cadencia habitual de parches.

Nota sobre la variante ESP de Dirty Frag. La mitad xfrm-ESP Page-Cache Write de Dirty Frag no se cierra con este DaemonSet — se activa a través de netlink XFRM + UDP_ENCAP_ESPINUDP, no mediante una familia de sockets dedicada, y un filtro BPF-LSM limpio para ella rompería el IPsec legítimo en el host o requeriría lógica consciente de namespaces de usuario. Actualmente no se rastrea aquí — se aceptan contribuciones. En distribuciones endurecidas que bloquean namespaces de usuario sin privilegios (p. ej. la política AppArmor predeterminada de Ubuntu), la variante ESP es inalcanzable de todos modos y el bloqueo de RxRPC aquí es suficiente.

Cómo funciona

bpf/blocker.c es un programa BPF-LSM corto:

root@kitploit:~
SEC("lsm/socket_create")
int BPF_PROG(block_socket_family, int family, int type, int protocol,
             int kern, int ret)
{
    if (ret)
        return ret;
    /* kern != 0 significa sock_create_kern() — deja pasar a los llamadores del kernel. */
    if (!kern && (family == AF_ALG || family == AF_RXRPC))   // 38, 33
        return -EPERM;
    return 0;
}

El cargador Go (main.go, ~40 líneas) carga el programa y lo adjunta mediante bpf(BPF_LINK_CREATE). El enlace se mantiene durante toda la vida del pod. En SIGTERM, el enlace se cierra y el hook se desadjunta.

Requiere un kernel compilado con CONFIG_BPF_LSM=y y bpf en la pila LSM activa (lsm=...,bpf en la línea de comandos del kernel). Talos Linux incluye ambos habilitados por defecto desde v1.10.

Instalación

kubectl

root@kitploit:~
kubectl apply -f https://raw.githubusercontent.com/cozystack/copy-fail-blocker/v0.3.0/manifests/copy-fail-blocker.yaml

Para el último commit en main (puede incluir cambios no publicados):

root@kitploit:~
kubectl apply -f https://raw.githubusercontent.com/cozystack/copy-fail-blocker/main/manifests/copy-fail-blocker.yaml

Helm

El chart no se publica como artefacto OCI (la ruta del registro se comparte con la imagen del contenedor). Instala desde un checkout etiquetado:

root@kitploit:~
git clone --branch v0.3.0 https://github.com/cozystack/copy-fail-blocker
cd copy-fail-blocker
helm upgrade --install copy-fail-blocker charts/copy-fail-blocker \
  --namespace kube-system

O mediante los atajos del Makefile:

root@kitploit:~
make apply         # helm upgrade --install en kube-system
make diff          # previsualiza los cambios contra el clúster
make delete        # desinstala
make manifest      # regenera manifests/copy-fail-blocker.yaml

El DaemonSet debe ejecutarse con privilegios (carga programas BPF y escribe en bpffs). Colócalo en un namespace con el Estándar de Seguridad de Pods privilegiado, o en kube-system, que es privilegiado por defecto.

Verificación

Desde cualquier pod en un nodo cubierto:

root@kitploit:~
python3 -c '
import errno, socket
# Pasa cada familia con un tipo que el create() específico de la familia
# realmente soporte (AF_ALG → SOCK_SEQPACKET, AF_RXRPC → SOCK_DGRAM) para que
# en un nodo SIN este hook la llamada tenga éxito (FAIL: socket creado)
# o falle con un errno distinto de EPERM — ambos aparecen como FAIL abajo.
# Con el hook activo, security_socket_create() devuelve -EPERM antes de que
# se ejecute pf->create(), por lo que el tipo no importa; aun así pasamos
# el correcto para mantener el diagnóstico de FAIL inequívoco.
for name, family, stype in [("AF_ALG",   38, socket.SOCK_SEQPACKET),
                            ("AF_RXRPC", 33, socket.SOCK_DGRAM)]:
    try:
        socket.socket(family, stype, 0)
        print(f"FAIL: {name} socket created")
    except OSError as e:
        if e.errno == errno.EPERM:
            print(f"OK ({name}): blocked with EPERM")
        else:
            print(f"FAIL: {name} got {e.errno} ({e.strerror}), expected EPERM")'

Salida esperada:

root@kitploit:~
OK (AF_ALG): blocked with EPERM
OK (AF_RXRPC): blocked with EPERM

Cualquier otro errno (p. ej. ESOCKTNOSUPPORT 94, EAFNOSUPPORT 97) significa que el hook no está activo en ese nodo — investiga antes de asumir que estás cubierto.

Compilación

root@kitploit:~
make image                                       # docker buildx build + push
make image REGISTRY=ghcr.io/myorg TAG=v0.3.0     # etiqueta personalizada
make image PUSH=0 LOAD=1                         # compila localmente sin push

make image actualiza charts/copy-fail-blocker/values.yaml con el digest de imagen resuelto para que el chart siempre fije por digest.

Las dependencias de compilación viven en el Containerfile (clang, libbpf-dev, Go). El host local solo necesita docker buildx, helm, yq (mikefarah), kubectl y helm-diff.

Configuración

charts/copy-fail-blocker/values.yaml:

ClavePredeterminadoNotas
image.repositoryghcr.io/cozystack/copy-fail-blockerActualizado automáticamente por make image
image.tagvX.Y.Z@sha256:...Fijado por digest, valor actual en values.yaml
priorityClassNamesystem-node-criticalGarantiza que el daemon sobreviva a desalojos
tolerations[{operator: Exists}]Se ejecuta en cada nodo, incluidos los contaminados
resources.requests5m CPU / 16Mi memoryHuella en reposo después del adjunto

Limitaciones

  • El hook solo vive mientras el pod se ejecuta. En el reinicio del pod hay una ventana corta (segundos) donde AF_ALG y AF_RXRPC de espacio de usuario vuelven a ser accesibles. Para la mayoría de los modelos de amenaza esto es aceptable; si no, considera fijar el enlace BPF a bpffs (no implementado actualmente — se aceptan contribuciones).
  • Cualquiera con CAP_BPF y CAP_SYS_ADMIN en el host puede desadjuntar el hook. Esto no sustituye las restricciones de privilegios en todo el clúster.
  • No bloquea algif_skcipher / algif_hash / etc. El programa rechaza toda la familia AF_ALG, pero solo se sabe que algif_aead es explotable actualmente. Si un CVE futuro necesita un filtro más fino (p. ej. hookear bind() e inspeccionar salg_type), esto es sencillo de añadir.
  • Sin efecto en procesos que ya tienen un socket AF_ALG o AF_RXRPC abierto. Los sockets existentes siguen funcionando hasta que se cierran.
  • No cubre la variante ESP de Dirty Frag. Esa ruta se alcanza a través de netlink XFRM y UDP_ENCAP_ESPINUDP, no mediante una familia de sockets dedicada — no se rastrea actualmente, se aceptan contribuciones. Consulta la nota en Por qué.
  • Los clientes AF_RXRPC de espacio de usuario quedan bloqueados. RxRPC es el protocolo de red de AFS. La protección !kern significa que el módulo fs/afs (kAFS) del árbol sigue funcionando ya que abre sus sockets mediante sock_create_kern(). Las herramientas AFS de espacio de usuario (p. ej. daemons de espacio de usuario de OpenAFS) que abren un socket AF_RXRPC directamente mediante socket(2) serán denegadas — no despliegues este DaemonSet en nodos que ejecuten dichas herramientas.

Licencia

Apache License 2.0 — consulta LICENSE.

Descargar herramienta