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
CVE-2026-46331 — pedit COW | Kitploit
Herramientas/GitHubGitHub/v0idnetwork/cve-2026-46331
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónCTFPapers e InvestigaciónAprendizaje y EducaciónExplotación de Binarios
GitHubv0idnetwork/cve-2026-46331

CVE-2026-46331

pedit COW

Ver Repositorio
1hace 1 mesAún no revisado

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

CVE-2026-46331 (pedit COW) – Vulnerabilidad de Envenenamiento de Caché de Páginas en el Editor de Paquetes de Linux net/sched

Resumen Ejecutivo

CVE-2026-46331 (apodado “pedit COW”) es una falla local de escalada de privilegios en el kernel de Linux en el subsistema de control de tráfico. Un usuario no privilegiado (en un espacio de nombres de red no privilegiado) puede configurar el filtro act_pedit (editor de paquetes) para desencadenar una escritura parcial de copia en escritura (COW) en la caché de páginas. En efecto, el kernel escribe datos controlados por el atacante en la imagen en memoria de un archivo sin marcar la página como privada, corrompiendo la copia en caché de ese archivo. Críticamente, el exploit solo requiere CAP_NET_ADMIN (obtenible en un espacio de nombres de usuario) y no modifica el archivo en disco. En la práctica, una prueba de concepto (PoC) funcional llamada packet_edit_meme fue publicada el 17 de junio de 2026, demostrando cómo sobrescribir la imagen en caché de páginas de un binario setuid (por ejemplo, /bin/su) para generar un shell de root. La vulnerabilidad se origina en un cálculo incorrecto del rango COW en tcf_pedit_act() y ha sido corregida en upstream (4 de junio de 2026) moviendo la verificación de la región escribible al bucle por clave.

  • Afectados: Kernels de Linux (aproximadamente v5.18 hasta 7.1-rc6) con act_pedit. Las versiones estables sin parche (incluyendo muchos kernels de distribuciones) son vulnerables.
  • Impacto: Escalada de privilegios local a root mediante la corrupción de la caché de páginas (envenenamiento de caché de páginas). CVSS v3.1: 6.0 (Medio, AV:L/AC:L/PR:H/UI:N/C:N/I:H/A:H).
  • Exploit: La PoC aprovecha un espacio de nombres de usuario+red no privilegiado para obtener CAP_NET_ADMIN, configura un filtro tc pedit y sobrescribe el punto de entrada ELF de un binario setuid en memoria con shellcode.
  • Mitigación: Actualice el kernel (el parche upstream movió skb_ensure_writable() dentro del bucle por clave). Como solución alternativa, bloquee o descargue el módulo act_pedit o deshabilite los espacios de nombres de usuario no privilegiados (por ejemplo, sysctl user.max_user_namespaces=0). Después de la mitigación, vacíe las cachés (echo 3 > /proc/sys/vm/drop_caches) para eliminar cualquier página envenenada.

Este informe proporciona un análisis técnico detallado de CVE-2026-46331: su causa, explotación, detección y estrategias de remediación, con referencias a avisos de proveedores, CVEs y el exploit público.

Resumen de la Vulnerabilidad

Definición: CVE-2026-46331 es un error de escritura fuera de límites en el subsistema Traffic Control (net/sched) del kernel de Linux, específicamente en la acción act_pedit (editor de paquetes). La función tcf_pedit_act() calcula un rango de “copia en escritura” para operaciones de edición de paquetes antes de iterar sobre las claves tipificadas, utilizando una pista estática tcfp_off_max_hint. Sin embargo, algunas claves (por ejemplo, ediciones de cabecera TCP/UDP) determinan su desplazamiento de bytes final solo en tiempo de ejecución. El código nunca vuelve a verificar la capacidad de escritura para estos desplazamientos dinámicos. Como resultado, las escrituras pueden ocurrir fuera de la región pre-COW: parte de la escritura del paquete nunca se hace privada, lo que lleva a un COW parcial. Esta escritura errónea se propaga a la memoria compartida de la caché de páginas de un archivo (si los buffers del paquete hacen referencia a páginas del archivo), corrompiendo la imagen del archivo en caché.

Antecedentes: La acción editor de paquetes (pedit) de Linux permite a los administradores reescribir bytes arbitrarios dentro de las cabeceras de los paquetes (capas de enlace, red o transporte) a medida que los paquetes atraviesan un filtro tc configurado. Funciona especificando un desplazamiento (posiblemente anclado a una cabecera) y un valor/máscara de 32 bits. Internamente, pedit opera sobre socket-buffers (sk_buff) y debe hacer que la memoria del paquete de destino sea escribible antes de modificarlo (a través de skb_ensure_writable() de manera COW). Idealmente, el kernel debería clonar (copia privada) cualquier página compartida antes de escribir para evitar alterar la memoria utilizada en otro lugar.

Causa Raíz: En tcf_pedit_act(), el código calcula erróneamente el rango escribible solo una vez al inicio, utilizando tcfp_off_max_hint (el desplazamiento estático máximo). Esta pista no incluye ningún desplazamiento de cabecera en tiempo de ejecución que las claves tipificadas añaden cuando se procesa el paquete. Claves como TCP o UDP pueden calcular un desplazamiento basado en la posición de la cabecera IP en tiempo de ejecución (por ejemplo, si una clave anterior desplaza la cabecera de red). Por lo tanto, durante el bucle por clave, el desplazamiento real de una clave puede exceder el rango que fue pre-asignado como escribible. El código entonces escribe en la memoria del paquete a través de skb_store_bits(), pero como la página más allá de la región pre-COW no se hizo privada, la escritura corrompe una página que todavía está compartida con la caché de páginas. En resumen, “calcular el rango del paquete escribible demasiado pronto” causa una escritura fuera de límites y entre páginas. Los desplazamientos negativos (por ejemplo, editar cabeceras Ethernet en ingreso) también se manejan incorrectamente, e incluso offset_valid() carecía de una guardia para INT_MIN, agravando la falla.

Por Qué Ocurre: Este error es esencialmente un error de lógica en el cálculo del rango de copia en escritura. El kernel asumió que el desplazamiento máximo estático (conocido en tiempo de carga) era suficiente para todas las ediciones. No actualizó el rango COW cuando se aplicaron claves con desplazamientos dinámicos. Después de una serie de ediciones en cola, la escritura final podría quedar fuera de la región preverificada. Debido a que los buffers de paquetes pueden hacer referencia a páginas de archivos mapeados en memoria (por ejemplo, a través de mecanismos de copia cero), esta escritura “COW parcial” puede alcanzar la caché de páginas de un archivo en disco. En la práctica, la acción del editor de paquetes puede recibir páginas de un sendfile o splice; por lo tanto, una única operación de filtro de paquetes puede escribir indirectamente datos elegidos por el atacante en la imagen en memoria de un archivo, sin alterar el disco.

Análisis Técnico

Componentes y Flujo de Datos: El código vulnerable reside en el subsistema net/sched de Linux (act_pedit.c). Cuando un paquete coincide con una regla pedit configurada, se invoca tcf_pedit_act(). Internamente, llama a skb_ensure_writable(skb, X) exactamente una vez, donde X = tcfp_off_max_hint. Esto hace que los primeros X bytes del paquete sean privados (COW). Luego, en un bucle sobre cada clave (operación de edición), calcula el desplazamiento de escritura real de la clave sumando el desplazamiento de cabecera en tiempo de ejecución al desplazamiento especificado de la clave, y escribe un valor de 32 bits en el paquete. En pseudocódigo:```c u32 off_max = action->tcfp_off_max_hint; skb_ensure_writable(skb, off_max); for (i = 0; i < num_keys; i++) { u32 hdr_off = compute_header_offset(skb, key[i].hdr_type); u32 write_off = hdr_off + key[i].offset; skb_store_bits(skb, write_off, &key[i].value, 4); }

root@kitploit:~
Debido a que `hdr_off` solo se calcula al procesar cada clave, la llamada inicial a `skb_ensure_writable()` no lo tuvo en cuenta. Si `hdr_off + key[i].offset` supera `off_max`, el código recurre a `skb_store_bits()` en fragmentos en lugar del área lineal principal, lo que significa que escribe en una página no hecha privada. Ese es el punto de fallo.

**Superficie de ataque:** La única interfaz necesaria es el **filtro tc** con una acción `pedit`, que normalmente requiere la capacidad **CAP_NET_ADMIN**. Sin embargo, los usuarios comunes pueden obtener CAP_NET_ADMIN dentro de un espacio de nombres de red privado (clonación de espacio de nombres de usuario) sin privilegios reales. Por lo tanto, un usuario no privilegiado puede ingresar a un espacio de nombres de usuario+red y crear una regla `tc pedit` en loopback. La escritura ocurre cuando se procesa un paquete (el atacante normalmente genera tráfico en loopback para activarlo). El límite de confianza (usuario vs. kernel) se cruza porque el kernel confió en su propia configuración de COW, pero los desplazamientos proporcionados por el usuario rompieron esa suposición.

**Mecanismo interno:** Del lado del kernel, la vulnerabilidad se manifiesta como una **escritura fuera de los límites** (CWE-787). Corrompe la memoria del kernel que está mapeada en el espacio de usuario (caché de páginas de archivos). Específicamente, puede sobrescribir el contenido de cualquier página de archivo que esté mapeada en el búfer de socket. En la prueba de concepto, `/bin/su` se mapea mediante mmap al enviarlo al búfer de socket, por lo que el exploit cambia los bytes de su punto de entrada en la memoria. Esto no modifica el archivo en disco, pero cualquier ejecución posterior de ese binario lee la imagen envenenada de la caché. El análisis del blog señala:

> “Debido a que el skb puede hacer referencia a páginas de copia cero introducidas mediante sendfile, esa escritura fuera de los límites puede aterrizar en la memoria compartida de la caché de página que respalda un archivo real. El kernel cree que ha hecho que la memoria del paquete sea segura para modificar; en realidad, la escritura posterior alcanza una región fuera de la que realmente privatizó.”

**Límites de confianza:** El kernel asumió erróneamente que `skb_ensure_writable()` (COW de ruta rápida) garantizaría la seguridad para todas las escrituras posteriores. No volvió a verificar cada clave. El usuario solo controla la configuración del filtro de paquetes y el contenido del paquete; el kernel lo concedió (a través de espacios de nombres de red). Una vez que se violó esa confianza, la escritura escapó a la memoria respaldada por archivos que debería haber estado protegida.

## Análisis de causa raíz

La causa raíz es **el cálculo incorrecto del rango de COW en la acción pedit**. En términos de código, se llamó a un único `skb_ensure_writable()` con una longitud basada en `tcfp_off_max_hint`, luego, dentro del bucle, los desplazamientos reales podían exceder esto. Un pequeño parche (mayo de 2026) lo corrige moviendo `skb_ensure_writable()` *dentro* del bucle, después de que se conoce el desplazamiento real, y agregando comprobaciones y manejo especial para desplazamientos negativos. En otras palabras:

- **Código con error:**  ```c
  skb_ensure_writable(skb, action->tcfp_off_max_hint);
  for each key:
      // compute offset (hdr_off + key_offset)
      skb_store_bits(skb, write_off, ...);
  • Código corregido: ```c for each key: // compute offset (hdr_off + key_offset) skb_ensure_writable(skb, write_off + 3); skb_store_bits(skb, write_off, ...);
    root@kitploit:~

Additionally, the fix ensures that for negative offsets (Ethernet header edits) it uses skb_cow() on headroom, and guards against INT_MIN cases. The commit message (stack.watch summary) states: “Fix by moving skb_ensure_writable() inside the per-key loop where the actual write offset is known, and add overflow checking on the offset arithmetic.”.

Thus, why it exists: during code review or design, the per-key re-calculation was overlooked. The static hint optimization bypassed the need to re-evaluate per key. It appears to be an honest bug rather than a malicious oversight, but its effect is severe because it violates the COW assumption. As TuxCare notes, this bug was merged under the guise of a routine “data corruption” fix, without immediate security context.

Discovery Process

The vulnerability was introduced by kernel commit 8b796475fd78 (May 2022) and remained unnoticed until early 2026. According to sources, the fix (commit 899ee91156e5 on May 31, 2026) was submitted to the netdev mailing list as an ordinary data-corruption patch. The kernel maintainers merged the fix (net-7.1-rc7) on June 4, 2026. Only on June 16, 2026 was CVE-2026-46331 formally assigned (about two weeks after the patch appeared). A fully weaponized public exploit appeared on June 17, 2026 (the packet_edit_meme PoC).

In practice, the sequence was:

  • Fix submitted (mailing list): May 17, 2026 (Zhang Cen patch)
  • Fix merged upstream: June 4, 2026 (net-7.1-rc7)
  • CVE assignment: June 16, 2026 (CNA entered CVE-2026-46331)
  • Public PoC: June 17, 2026 (packet_edit_meme)
  • Patch rollout: Late June 2026 in most distros (Red Hat, Debian, Ubuntu, etc.)

Multiple parties noticed the bug by the open patch. For example, Massimiliano Oldani (cybersecurity researcher) published a detailed write-up and exploit shortly after, noting that “a public, working proof-of-concept exploit named packet_edit_meme appeared on GitHub within 24 hours of CVE assignment”. CloudLinux, TuxCare, and SentinelOne published analyses once the PoC was public and CVEs assigned. The Debian security tracker and PT DBugs also summarized the issue and available advisories (see References).

Attack Scenario

A realistic attack requires minimal preconditions:

  • Attacker capabilities: A local unprivileged user on the target machine. The user must be able to create a new user namespace with network namespace (via unshare(CLONE_NEWUSER|CLONE_NEWNET)), which grants CAP_NET_ADMIN inside that namespace without real root privileges. Unprivileged user namespaces are enabled by default on many kernels (e.g. RHEL, Debian) and can be re-enabled on Ubuntu with an aa-exec workaround.

  • Target conditions: The target must be running a vulnerable Linux kernel (approx. 5.18–7.1-rc6) with the act_pedit module available. If act_pedit is built-in or already loaded, it is immediately exploitable. If it is a module, it auto-loads when a tc pedit rule is configured. The target should not have applied the upstream patch. Notably, it is not necessary for the attacker to have write access to any file; the exploit works by writing through packet filters.

  • Attack chain:

    1. Obtain CAP_NET_ADMIN: The attacker runs something like unshare --map-root-user --net --pid bash to create a new user+net namespace. This grants CAP_NET_ADMIN in that namespace (user mapped to root inside).
    2. Set up networking: The attacker brings up the loopback interface (ifconfig lo up) and optionally spawns a listener (e.g. nc -l 127.0.0.1 9999). This provides a packet flow to use for TC actions.

Impact: If successful, the attacker gains full root privileges locally. The exploit can be done in one command and is deterministic. Additionally, corruption of arbitrary file-backed pages could cause denial-of-service (system crash) if used differently. The published PoC specifically overwrote /bin/su’s entrypoint with shellcode, but any file the attacker can map could be targeted. The chain requires no special timing or race and has been demonstrated on many distros (RHEL, Ubuntu, Debian, etc.).

Proof of Concept (PoC)

A public exploit, packet_edit_meme, is available on GitHub (sgkdev/packet_edit_meme) and targets /bin/su. We describe its essential logic without destructive payloads:```c /* Pseudocode outline of the exploit (simplified) / int main() { / 1. Identify a setuid binary (su) and its ELF entry offset */ int fd = open("/bin/su", O_RDONLY); long entry = elf_entry_offset(fd); if (entry < 0) abort(); printf("Target %s (UID=%d), entry offset 0x%lx\n", "/bin/su", getuid(), entry);

root@kitploit:~
/* 2. Unshare user+net namespace to get CAP_NET_ADMIN locally */
if (unshare(CLONE_NEWUSER | CLONE_NEWNET) < 0) abort();
/* Map UID/GID to root (handled via /proc/self/uid_map, /gid_map) */
// (omit details: write "0 <uid> 1" to /proc/self/uid_map and gid_map, and deny setgroups)

/* 3. Setup environment: bring up loopback and listener */
if (system("ip link set lo up") < 0) abort();
if (system("nc -l 127.0.0.1 9999 &") < 0) abort();

/* 4. Configure a tc pedit action via netlink (simplified) */
// Assume 'pedit_write' sends a packet-edit command to the kernel.
// The key offsets below are chosen such that they exceed the initial COW range.

char shellcode[/*size=48*/] = {
    // (assembly for setgid(0); setuid(0); execve("/bin/sh").., padded to 36 or 48 bytes)
};
size_t total = sizeof(shellcode), sent = 0;
while (sent < total) {
    int chunk = min(PEDIT_MAX_WRITE, total - sent);
    /* Issue TC pedit action to write next chunk */
    if (pedit_write(fd, entry + sent, &shellcode[sent], chunk) != 0) {
        fprintf(stderr, "pedit_write failed\n");
        exit(1);
    }
    sent += chunk;
}
/* 5. Trigger execution of su (in original namespace) */
execl("/bin/su", "su", NULL);  // This will run the poisoned binary as root
return 0;

}

root@kitploit:~
Este pseudocódigo ilustra el flujo: abrir `/bin/su`, descompartir espacios de nombres (unshare) para obtener CAP_NET_ADMIN, configurar loopback y reglas TC pedit, luego llamar a una función `pedit_write(fd, offset, data, len)` (en el PoC real esto usa llamadas netlink internamente) para sobrescribir la caché de páginas del objetivo. Finalmente, se ejecuta el binario, generando un shell root.

El PoC real es más elaborado (manejo de mapas UID/GID, escucha de red y bytes de shellcode a nivel de syscall), pero el concepto central es el anterior. Enfatizamos **no ejecutar este exploit** excepto en un entorno de pruebas seguro, y no apuntar a ningún sistema real. Lo anterior es solo para demostración.

**Nota:** Si no existiera un PoC público y seguro de usar, lo diríamos explícitamente. En este caso, el PoC es público, y lo describimos conceptualmente. Hemos omitido los bytes de shellcode sin procesar y los detalles reales de netlink por brevedad y seguridad.

## Flujo de Explotación

1. **Punto de entrada:** El atacante debe primero obtener CAP_NET_ADMIN. Típicamente, esto significa crear un espacio de nombres de usuario+red (`unshare`) desde un proceso no privilegiado, lo que otorga CAP_NET_ADMIN local al espacio de nombres.

2. **Acceso inicial:** Dentro de este espacio de nombres, el atacante puede usar herramientas normales (`ip`, `tc`) para configurar el control de tráfico. La ruta de código `act_pedit` del kernel ahora es alcanzable para los paquetes.

3. **Desencadenante:** El atacante configura un `tc filter ... action pedit` en la interfaz loopback. Este filtro coincide con paquetes (por ejemplo, coincidencia 0) y especifica una o más **claves tipadas** con tipos de cabecera (IP, TCP) y desplazamientos. Los desplazamientos se eligen de modo que *después de que el kernel calcule la base de la cabecera dentro del bucle*, el desplazamiento final de escritura supere el rango inicial de COW.

4. **Explotación:** Cuando se procesa un paquete que coincide con el filtro, el kernel llama a `tcf_pedit_act()`. Realiza un `skb_ensure_writable()` *insuficiente* y luego itera sobre las claves. Para al menos una clave, la escritura aterriza en una página que *no* fue clonada en una copia privada. Esto causa una **escritura fuera de los límites** en la caché de páginas compartida. Si el búfer de socket fue preparado para referenciar páginas de un archivo (mediante sendfile/splice), esa escritura corrompe esas páginas del archivo.

5. **Post-explotación:** El shellcode del atacante ha sido escrito en la caché de páginas del binario objetivo (por ejemplo, `/bin/su`). El atacante (en el espacio de nombres original) ejecuta entonces `/bin/su`. El kernel lee la imagen en memoria (con la carga útil inyectada) y ejecuta el shellcode, otorgándole al atacante un shell root. En este punto, se ha producido un compromiso total del sistema.

6. **Impacto:** El atacante obtiene privilegios de root. Los datos confidenciales podrían sobrescribirse pero no filtrarse directamente. La integridad se rompe por completo (el atacante puede cambiar la imagen en memoria de cualquier archivo). La disponibilidad también puede verse afectada (escribir incorrectamente páginas críticas podría bloquear procesos o el sistema). Métricas CVSS: Medio en general (CVSS 3.1=6.0), pero el impacto real es root local severo.

Este flujo se resume diagramáticamente:```mermaid
flowchart LR
    A[Attacker (unprivileged user)] --> B[Unshare into user+net namespace<br>(gains CAP_NET_ADMIN)]
    B --> C[Configure TC pedit filter on lo]
    C --> D{Packet processing by kernel}
    D --> E[act_pedit computes wrong COW range]
    E --> F[skb_store_bits writes beyond COW'd region]
    F --> G[Page cache of target file is corrupted]
    G --> H[Attacker executes poisoned setuid binary]
    H --> I[Root shell obtained]

Indicadores de Compromiso (IoCs)

  • Escrituras inesperadas en caché de página: Archivos del sistema (especialmente ejecutables) que muestran alteraciones en memoria sin cambios en disco (por ejemplo, herramientas de hash o monitores de integridad verían una discrepancia en memoria).
  • Cargas de módulos: El módulo act_pedit aparece en lsmod inesperadamente en sistemas que normalmente no usan tc pedit. (Ej: lsmod | grep act_pedit no está vacío en servidores web.)
  • Uso de tc: Comandos tc inusuales o mensajes netlink de procesos sin privilegios. Los registros de auditoría pueden mostrar CAP_NET_ADMIN otorgado a un proceso no root.
  • Escucha en red: Un listener en puertos de loopback (ya que el exploit enlaza un socket para forzar el procesamiento de paquetes). Por ejemplo, netstat -tulnp que muestra nc o un listener personalizado en 127.0.0.1 podría ser una señal.
  • Registros del kernel: Oops o advertencias que involucran tcf_pedit_act, skb_ensure_writable, o soft lockups durante tráfico intenso en loopback o errores en el procesamiento de tc. (Estos serían inusuales e indicativos de corrupción.)

Por ejemplo, un IOA son archivos corruptos en la caché de página: una lista de verificación de triaje podría incluir verificar el contenido del archivo en memoria vs disco, especialmente para binarios setuid después de una intensa actividad de tc. Otro es creación de nuevos namespaces: monitorear llamadas a unshare(CLONE_NEWUSER|CLONE_NEWNET) podría marcarse. En resumen, los defensores deben vigilar cualquier: uso de act_pedit, uso de userns y modificaciones repentinas de ejecutables en RAM.

Detección

Para detectar intentos de explotación:

  • SIEM/Análisis de registros: Alertar sobre configuraciones tc o mensajes netlink que añadan un filtro act_pedit. Por ejemplo, las reglas Sigma podrían buscar eventos que contengan TCA_ACT_KIND: pedit o similar. Monitorear registros de auditoría para capset CAP_NET_ADMIN de procesos no root, o escrituras en /proc/*/uid_map.
  • IDS/IPS: Es poco probable que tengan firmas específicas (no hay firma de red para un exploit local), pero heurísticas: tráfico con paquetes TCP/UDP inesperados en loopback concurrente con alertas de integridad del host. Posiblemente detectar las ediciones específicas de paquetes si es posible instrumentar.
  • EDR: Vigilar procesos que leen /bin/su (u otros binarios sensibles) y de repente los ejecutan en conjunto con llamadas al sistema namespace/unshare. Alertar sobre cualquier proceso que abra un binario setuid y cree un userns.
  • WAF/Dispositivos de red: No aplicable (ataque local).
  • Monitoreo de integridad de archivos: Comparar la imagen en memoria de binarios críticos con sus sumas de verificación en disco. Si ocurren discrepancias (y no hay actualizaciones), activar alerta. (Como señala CloudLinux, vaciar las cachés después de un compromiso solo es contención; la remediación real requiere reconstruir el host.)
  • Herramientas de integridad del kernel: Usar Módulos de Seguridad de Linux o eBPF para imponer que solo ciertos procesos puedan adjuntar filtros TC, o que no se pueda engañar a skb_ensure_writable() (aunque no existe una verificación incorporada conocida).

En resumen, los defensores deben registrar y auditar el uso de namespaces de usuario, comandos tc y cargas de módulos. Un enfoque clave: rechazar o registrar cualquier invocación de tc pedit por usuarios no confiables. En hosts comprometidos, verificar si se ha aplicado /etc/modprobe.d/disable-act_pedit.conf (debería hacerse de forma preventiva).

Mitigación

Aplicar parches: La solución principal es una actualización del kernel. Todas las distribuciones principales han lanzado actualizaciones en junio de 2026. Actualizar a un kernel parcheado (Linux 7.1.0 o posterior, o backports de la distribución) es la solución definitiva.

Cambios de configuración: Si no es posible parchear de inmediato, implementar mitigaciones:

  • Deshabilitar act_pedit: Si sus cargas de trabajo no requieren tc pedit, incluya el módulo en la lista negra. Por ejemplo: echo 'install act_pedit /bin/true' | sudo tee /etc/modprobe.d/disable-act_pedit.conf lsmod | grep -w act_pedit && sudo rmmod act_pedit
    root@kitploit:~

Esto asegura que la acción no se pueda cargar. (Esto es recomendado por CloudLinux y TuxCare.) No aplicar en hosts que usen legítimamente tc pedit.

  • Restringir los espacios de nombres de usuario: Eliminar el vector de ataque de espacios de nombres no privilegiados. En RHEL/Alma/Debian: ``` sudo sysctl -w user.max_user_namespaces=0 echo 'user.max_user_namespaces = 0' | sudo tee /etc/sysctl.d/99-pedit-cow.conf
    root@kitploit:~

En Ubuntu 22.04+: ``` sudo sysctl -w kernel.unprivileged_userns_clone=0 echo 'kernel.unprivileged_userns_clone = 0' | sudo tee /etc/sysctl.d/99-pedit-cow.conf

root@kitploit:~
Esto evita que los usuarios sin privilegios creen el espacio de nombres de usuario necesario para obtener CAP_NET_ADMIN.  Nota: deshabilitar los espacios de nombres puede romper los contenedores sin raíz y algunas aplicaciones en entorno de pruebas.

- **Eliminar la caché de páginas (Contención):** Si sospecha que el exploit se ejecutó, las copias en memoria de los binarios pueden estar envenenadas.  Inmediatamente elimine las cachés para desalojarlos:  ```
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"

Esto fuerza la recarga de páginas desde el disco. Precaución: Si un atacante ya tenía acceso root, borrar los cachés no eliminará ninguna persistencia que haya instalado. Trate dichos sistemas como comprometidos.

  • Mínimo privilegio: Audite y restrinja quién puede usar tc. El exploit solo necesita CAP_NET_ADMIN; asegúrese de que solo administradores de confianza tengan esta capacidad. Use RBAC o contenerización para limitar las concesiones de capacidad.

  • Controles de red: Aunque no es directamente explotable a través de la red, asegúrese de que el uso de loopback esté monitorizado. Bloquear 127.0.0.1 con un firewall no es práctico, pero asegúrese de que solo el tráfico de localhost se use para las manipulaciones de TC.

  • Avisos de proveedores: Consulte los avisos oficiales de su sistema operativo. Red Hat tiene RHSA-2026:27354 (y relacionados) para RHEL 8/9/10, Debian tiene DSA-6355-1, la página de CVE de Ubuntu enumera los kernels corregidos, etc. (Ver Referencias).

Mitigación

La mitigación a largo plazo implica asegurarse de que todos los sistemas afectados tengan kernels actualizados. Se deben instalar los paquetes de kernel que contienen la corrección y reiniciar los sistemas. Para contenedores o sistemas que no puedan reiniciarse, considere soluciones de actualización en vivo (ej., KernelCare) que tienen parches preparados.

Además, el diseño del sistema debe asumir que las interfaces de kernel accesibles desde el espacio de usuario pueden cambiar con el tiempo. Restringir CAP_NET_ADMIN y filtrar el uso de tc son buenas prácticas más allá de este error.

Si se produjo un compromiso, reconstruya el sistema. La vulnerabilidad envenena solo el caché de páginas, pero un atacante con root puede haber realizado otras acciones maliciosas; es necesario realizar una validación forense. No confíe en los escaneos de integridad de archivos después del exploit, porque como se mencionó, el PoC deja intactos los archivos en el disco. Reiniciar y aplicar parches es la vía de mitigación segura.

Evaluación del Impacto

  • Confidencialidad: Sin fuga de datos directa, ya que este error no lee datos sensibles del kernel. Solo escribe datos del atacante en la memoria. CVSS v3.1 califica el Impacto en la Confidencialidad como Ninguno (C:N).
  • Integridad: Alto (I:H). Un atacante puede alterar el contenido en memoria de páginas arbitrarias respaldadas por archivos (ej., ejecutables, archivos de configuración) sin permiso. Esto permite una violación completa de la integridad de esos archivos en el sistema en ejecución.
  • Disponibilidad: Alto (A:H). Sobrescribir memoria gestionada por el kernel o estructuras de datos críticas podría bloquear procesos o todo el sistema. Incluso si no se explota para shellcode, el error podría usarse para corromper páginas vitales y causar denegación de servicio.
  • Alcance: Sin cambios (componente vulnerable = vector de ataque = alcance de la víctima) ya que el exploit es local.

Dados estos factores, un vector CVSS v3.1 típico es AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H, lo que da una Puntuación Base de 6.0 (Medio). Sin embargo, tenga en cuenta que CVSS no captura que esta vulnerabilidad otorga escalada de privilegios a root, lo que en la práctica es crítico. (Algunas fuentes calcularon CVSSv4 para errores similares; ej., PT DBugs lista 8.5 en CVSSv4).

La gravedad suele calificarse como Importante/Crítica por los proveedores. El aviso de Red Hat para este CVE lo etiqueta como Importante, y AWS lo marca como Medio (CVSS 6.0). En cualquier caso, debido a que se obtiene acceso root, el riesgo práctico es mayor en sistemas multiusuario o compartidos.

CVEs Relacionados

Esta vulnerabilidad pertenece a una familia de errores de envenenamiento del caché de páginas. Otros CVEs notables incluyen:

  • CVE-2022-0847 (“Dirty Pipe”): Un error LPE similar en Linux 5.8+ donde splice() en una tubería podía escribir en el caché de páginas más allá de los límites de COW. También permitía sobrescribir archivos en memoria (sin cambio en disco).
  • CVE-2016-5195 (“Dirty COW”): Una falla más antigua en /proc/self/mem copy-on-write que permitía escritura local en mapeos de solo lectura.
  • CVE-2020-14386 (“Dirty Frag”): Una falla en el procesamiento de paquetes XFRM/ESP (criptografía) que provocaba escrituras entre páginas en el caché de páginas.
  • CVE-2023-4099 (“Dirty Clone”): Otro error de kernel relacionado con netfilter.

Cada uno de estos implica una ruta rápida del kernel escribiendo en memoria que creía poseer exclusivamente, pero no era así. CVE-2026-46331 es único en que ocurre en net/sched pedit action y aprovecha los espacios de nombres de usuario para eludir las restricciones de privilegios. A diferencia de DirtyPipe o Dirty COW, no se necesita ningún proceso privilegiado auxiliar (como un sistema mal configurado): un solo usuario no privilegiado puede desencadenarlo.

Cronología

  • 2022-05-10: Error introducido por el commit 8b7964... en el kernel principal.
  • 2026-05-17: Parche enviado a la lista de correo netdev (Zhang Cen).
  • 2026-05-31: Parche principal (commit 899ee91156e5) completado.
  • 2026-06-04: Parche fusionado en mainline (net-7.1-rc7).
  • 2026-06-16: CVE-2026-46331 asignado oficialmente.
  • 2026-06-17: PoC público (packet_edit_meme) publicado.
  • 2026-06-19 a 06-26: Parches y avisos publicados por los proveedores (serie Red Hat RHSA-2026:27xxx, Debian DSA-6355, USNs de Ubuntu, etc.). Anuncios de actualización en vivo de CloudLinux y KernelCare.
  • Después del 06-26: Cobertura en noticias, blogs, análisis técnico (TuxCare, SentinelOne, etc.) y análisis de cronología (el informe de Oldani).

Referencias

  • Parche del kernel de Linux y resumen del NVD
  • Avisos de Red Hat/CISA/Ubuntu (a través de NVD/OSV)
  • Blog de CloudLinux (mitigación de CVE-2026-46331)
  • Análisis de TuxCare (blog pedit-COW)
  • Entrada de la base de datos de vulnerabilidades de SentinelOne
  • Artículo de CyberPress sobre pedit COW
  • Resumen de la base de datos de Positive Technologies (dbugs)
  • Página de CVE de Amazon Linux
  • Seguimiento de seguridad de Debian
  • Blog de mitigación de CloudLinux (lista negra de módulos, drop_caches)

Todas las referencias provienen de fuentes confiables (avisos de proveedores, análisis publicados, entradas CVE/NVD).

Conclusiones Clave

  • COW parcial es peligroso: Siempre actualice el rango de COW para desplazamientos dinámicos. En act_pedit, calcular la posibilidad de escritura demasiado pronto permitió la corrupción del caché de páginas.
  • Los espacios de nombres de usuario eluden privilegios: Los espacios de nombres no privilegiados permitieron CAP_NET_ADMIN, lo que permite que un usuario local llegue al subsistema TC. Deshabilitar userns puede mitigar muchos exploits emergentes del kernel.
  • El envenenamiento del caché de páginas es potente: A diferencia de los exploits basados en disco, estos ataques no dejan rastros en el disco. Las herramientas de integridad de archivos no pueden detectarlos.
  • Defensa en profundidad: Monitorear el uso de TC, restringir CAP_NET_ADMIN y aplicar parches de kernel rápidamente son esenciales. Mitigaciones como la lista negra de módulos pueden ganar tiempo antes de la implementación completa del parche.
  • Ciclo de vida de la vulnerabilidad: El CVE se asignó después de que el parche fuera público (un "N-day"). Esto resalta la brecha de riesgo entre el parche ascendente y la adopción de versiones estables. Las organizaciones deberían rastrear los commits ascendentes, no solo los CVEs.
Descargar herramienta
  • Configure TC pedit action: Using the tc command or netlink, the attacker creates a qdisc and filter on lo that matches all packets (e.g. match u32 0 0) and attaches a pedit action with specially crafted keys. Each key has a dynamic header type (e.g. IP header for an L4 offset) and an offset chosen so that the actual write position (header start + offset) lies just beyond the range skb_ensure_writable() covered.
  • Generate traffic: The attacker sends data (for example, via echo '' > /dev/udp/127.0.0.1/53) to trigger the filter. The kernel calls tcf_pedit_act(), allocates a COW range, then iterates the keys. At least one key’s write falls outside the pre-COW’d region, causing the write to go into the shared pagecache.
  • Page-cache poisoning: In parallel, the attacker has opened a target file (typically a setuid binary) in the socket. For instance, the published PoC mmaps /bin/su into the socket via sendfile or similar, so the packet buffer references that file’s pages. The out-of-bounds write then corrupts the in-memory copy of /bin/su (specifically the ELF entry point).
  • Privilege escalation: After the exploit writes its payload, the attacker (or parent process in the original namespace) executes the poisoned binary (/bin/su). Because the kernel has inadvertently injected shellcode that does setgid(0); setuid(0); execve("/bin/sh"), running su drops a root shell. The file on disk was never altered, so no on-disk file integrity tools will show a change.
  • Registros de privilegios eliminados: Los registros de auditoría de Linux (auditd) que muestran programas obteniendo CAP_NET_ADMIN a través de userns o escribiendo en /proc/[pid]/uid_map.