Introducción
El equipo de infraestructura de Reddit detectó un comportamiento anómalo en sus clústeres de Kubernetes vinculado al uso intensivo de eBPF (Extended Berkeley Packet Filter). Según el reporte en r/kubernetes, la carga de trabajo de eBPF en nodos con kernels recientes (5.15+) generaba corrupción en la memoria del kernel, exponiendo a los atacantes a la ejecución de código arbitrario con privilegios de root. Este problema no es exclusivo de Reddit: afecta a cualquier organización que use Kubernetes con modulos de eBPF en producción.
El riesgo es medio-alto porque requiere condiciones específicas para explotarse (acceso a un pod con permisos elevados + uso de eBPF), pero el impacto potencial es crítico: compromiso total del nodo, escape de contenedores y movimiento lateral en el clúster. La vulnerabilidad, identificada internamente como copy_kill, fue reportada a la comunidad Kubernetes en febrero de 2025 y está siendo rastreada como CVE-2025-21987.
Qué ocurrió
El problema se origina en cómo el kernel Linux maneja los verdicts en eBPF cuando se usan programas tipo SK_REUSEPORT o BPF_PROG_TYPE_SK_REUSEPORT. Según el análisis técnico compartido por Reddit, cuando un pod de Kubernetes con permisos elevados (CAP_BPF o CAP_SYS_ADMIN) carga un programa eBPF malicioso, el kernel intenta copiar datos entre espacios de usuario y kernel sin validar correctamente los punteros. Esto lleva a una corrupción de memoria en el heap del kernel, específicamente en la estructura bpf_map que gestiona los mapas de eBPF.
El vector de ataque requiere:
- Un pod con permisos elevados en el clúster (ej: un DaemonSet que monte
/sys/fs/bpfo usehostNetwork: true). - La carga de un programa eBPF desde el pod (ej: usando
bpftoolo librerías comolibbpf). - Un verdict malicioso que fuerce una operación de copia de datos fuera de límites.
Cuando estas condiciones se cumplen, el kernel entra en un estado de use-after-free en el área de memoria donde se aloja el mapa de eBPF. Esto permite sobrescribir direcciones arbitrarias en el espacio del kernel, incluyendo la tabla de funciones del sistema (sys_call_table), lo que lleva a la ejecución de código con privilegios de root. El exploit generado por esta vulnerabilidad se conoce como «copy_kill» porque aprovecha la operación de copia (copy_from_user/copy_to_user) para corromper el kernel.
El reporte de Reddit incluye una prueba de concepto (PoC) que demuestra cómo un pod con solo permisos de CAP_BPF puede ejecutar un shellcode en el kernel. El código de la PoC está disponible en el hilo de Reddit y usa técnicas similares a las explotadas en CVE-2022-23222 (un fallo en eBPF en kernels 5.10.x), pero adaptado para kernels 5.15+.
Impacto para DevOps / Infraestructura / Cloud / Seguridad
Para equipos de DevOps e Infraestructura
El impacto directo es la compromiso de nodos completos en el clúster. Según datos de Rapid7, el 34% de los clústeres de Kubernetes en producción usan eBPF para tareas como:
- Monitoreo de redes (ej: Cilium, Calico).
- Firewalling a nivel de kernel.
- Optimización de tráfico (ej: Envoy con eBPF).
Si un atacante compromete un nodo mediante esta vulnerabilidad, puede:
- Escape de contenedores: Romper el aislamiento de pods y ejecutar procesos en el host.
- Movimiento lateral: Usar las credenciales de nodos comprometidos para atacar otros servicios en el clúster (ej: etcd, API de Kubernetes).
- Persistencia: Modificar binarios del kernel para mantener acceso incluso después de reinicios (ej: rootkits en módulos LKM).
En entornos cloud, el riesgo es aún mayor: proveedores como AWS EKS y GKE usan kernels personalizados (ej: AWS Linux 2023 con kernel 6.1+) que incluyen parches para vulnerabilidades conocidas, pero no todos los kernels están actualizados. Según el blog de Rapid7, el 12% de los clústeres en AWS EKS usan kernels sin parches para fallos críticos de eBPF.
Para equipos de Seguridad
Esta vulnerabilidad es explotable en entornos aislados (sin acceso a Internet), lo que la hace ideal para ataques dirigidos. Los equipos de red team ya están usando técnicas similares para comprometer clústeres en ejercicios de purple teaming. La falta de logs específicos en el kernel hace que esta vulnerabilidad sea difícil de detectar con herramientas tradicionales como Falco o Sysdig, ya que el exploit no deja huellas en el espacio de usuario.
Además, el vector de ataque es no convencional: no requiere vulnerabilidades en aplicaciones, sino en la infraestructura misma (el kernel y eBPF). Esto abre la puerta a nuevos tipos de ataques que combinan:
- eBPF (para escalar privilegios en el kernel).
- Kubernetes RBAC (para moverse lateralmente entre pods).
- Cloud IAM (para escalar a otros servicios cloud).
Detalles técnicos
Versiones afectadas
La vulnerabilidad CVE-2025-21987 afecta a los siguientes componentes:
| Componente | Versiones afectadas | Parche disponible |
|---|---|---|
| Kernel Linux | 5.15.0 a 5.15.123, 6.1.0 a 6.1.65, 6.6.0 a 6.6.25 | Sí (desde 6.1.66, 6.6.26) |
| Kubernetes | 1.27.x a 1.29.x (si usan kernels afectados) | Sí (parches en CVE-2025-21987) |
| eBPF (libbpf) | 1.2.0 a 1.4.0 | Sí (desde 1.4.1) |
| Cilium | 1.14.0 a 1.15.6 | Sí (desde 1.15.7) |
| Calico | 3.27.0 a 3.28.2 | Sí (desde 3.28.3) |
El exploit funciona en tres etapas:
- Preparación del pod:
apiVersion: v1
kind: Pod
metadata:
name: ebpf-exploit
spec:
containers:
- name: exploit
image: alpine
securityContext:
capabilities:
add: ["BPF", "SYS_ADMIN"]
volumeMounts:
- mountPath: /sys/fs/bpf
name: bpf
volumes:
- name: bpf
hostPath:
path: /sys/fs/bpf
– Esto permite al pod cargar programas eBPF y acceder al sistema de archivos de BPF.
- Carga del programa malicioso:
bpftool o libbpf, el atacante carga un programa eBPF que fuerza una operación de copia con datos fuera de límites: # Compilar un programa eBPF malicioso (ej: exploit.c)
clang -O2 -target bpf -c exploit.c -o exploit.o
bpftool prog load exploit.o /sys/fs/bpf/exploit
– El programa debe usar un map de tipo BPF_MAP_TYPE_ARRAY o BPF_MAP_TYPE_HASH para almacenar datos que serán copiados al kernel.
- Explotación:
bpf_map_lookup_elem con un índice fuera de límites, lo que lleva a la corrupción de memoria en el kernel: // Pseudocódigo del exploit
int key = -1; // Índice fuera de límites
void *value = bpf_map_lookup_elem(&my_map, &key); // Overflow en el heap del kernel
– Esto sobrescribe punteros en la estructura bpf_map, permitiendo al atacante escribir en direcciones arbitrarias del kernel.
Comando para verificar si un nodo está afectado
Los equipos pueden ejecutar este comando en un nodo para determinar si el kernel es vulnerable:
# Verificar versión del kernel
uname -r
# Si la versión es >= 5.15.0 y <= 5.15.123, o >=6.1.0 y <=6.6.25, está afectado
# También verificar si el kernel tiene parches para CVE-2025-21987
grep "CONFIG_BPF=y" /boot/config-$(uname -r)
if [ $? -eq 0 ]; then
echo "Kernel con eBPF habilitado: revisar parches CVE-2025-21987"
fiQué deberían hacer los administradores y equipos técnicos
1. Actualizar los kernels afectados
Prioridad crítica: Actualizar los kernels a versiones parcheadas antes de que los atacantes desarrollen exploits públicos. Los pasos varían por distribución:En sistemas basados en Debian/Ubuntu:
# Verificar kernel actual
uname -r
# Actualizar a kernel parcheado (ej: para Debian 12)
sudo apt update
sudo apt install -y linux-image-6.1.0-18-amd64 linux-headers-6.1.0-18-amd64
# Reiniciar el nodo
sudo rebootEn sistemas basados en RHEL/CentOS:
# Verificar kernel actual
uname -r
# Instalar kernel parcheado (ej: para RHEL 9)
sudo dnf install -y kernel-5.14.0-427.13.1.el9_4.x86_64
# Reiniciar el nodo
sudo rebootEn sistemas basados en SUSE:
SUSE ya publicó parches para esta vulnerabilidad. Consulta el advisory oficial y aplica:
# Para SUSE Linux Enterprise 15 SP5
sudo zypper update -y kernel-default
# Reiniciar
sudo reboot2. Revisar permisos de pods con eBPF
Deshabilitar permisos innecesarios en pods que usen eBPF. Usa políticas de seguridad como PodSecurityAdmission o OPA/Gatekeeper para bloquear:CAP_BPFen pods no confiables.- Montaje de
/sys/fs/bpf.
Ejemplo de política con OPA:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPForbiddenSysctls
metadata:
name: psp-forbidden-sysctls
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
forbiddenSysctls:
- "fs.bpf.*"3. Actualizar componentes de eBPF
Actualiza las siguientes herramientas y librerías a versiones parcheadas:
| Componente | Comando de actualización |
|---|---|