
Herramienta automatizada de verificación de defectos para 6 CVEs de dnsmasq (CVE-2026-2291, 4890, 4891, 4892, 4893, 5172)
Herramienta automatizada de caja negra para verificar 6 vulnerabilidades de dnsmasq (mayo de 2026). Envía paquetes de ataque a un DUT en vivo e informa PASS/FAIL — sin necesidad de acceso al código fuente.
# Configure el DNS del DUT con la IP WAN de su portátil a través de la GUI primero, luego:
sudo python3 dnsmasq_cve_verify.py --laptop <SU_IP_WAN> --dut <IP_LAN_DUT> --dut-pass <CONTRASEÑA_SSH>
# Ejemplo:
sudo python3 dnsmasq_cve_verify.py --laptop 10.0.0.211 --dut 192.168.1.1 --dut-pass '12345Asdf@'
| CVE | CVSS | Tipo | Vector de ataque | Función afectada |
|---|---|---|---|---|
| CVE-2026-2291 | 9.2 | Desbordamiento de búfer en el heap | Remoto | extract_name() — siempre activo |
| CVE-2026-5172 | 7.5 | Lectura fuera de límites / caída | Remoto | extract_addresses() — siempre activo |
| CVE-2026-4890 | 7.5 | Bucle infinito DoS | Remoto | Análisis de mapa de bits NSEC (--dnssec) |
| CVE-2026-4891 | 5.3 | Lectura OOB en heap | Remoto | Validación RRSIG (--dnssec) |
| CVE-2026-4892 | 8.4 | Desbordamiento de heap → raíz | Local/Adyacente | CLID DHCPv6 (--dhcp-script + DHCPv6) |
| CVE-2026-4893 | 5.3 | Omisión de validación | Remoto | Verificación de fuente ECS (--add-subnet) |
Causa raíz: union bigname declara char name[MAXDNAME] pero los caracteres escapados pueden expandir un nombre a 2*MAXDNAME+1 bytes, causando desbordamiento de heap.
Método de prueba: Envía consultas DNS que contienen nombres de dominio con caracteres de bit alto (0x80+) que se escapan internamente como \DDD (4 bytes por byte de entrada). Si dnsmasq se cuelga o deja de responder, es vulnerable.
Comportamiento corregido: Rechaza nombres sobredimensionados correctamente (FORMERR/REFUSED) o usa un búfer ampliado.
Causa raíz: Un campo rdlen falsificado permite que extract_name() avance el puntero más allá del final del registro. El desbordamiento negativo de los bytes restantes produce un valor enorme → lectura OOB masiva → caída.
Método de prueba: Envía respuestas DNS con registros CNAME donde rdlen es menor que el nombre codificado real. Si dnsmasq se cuelga, es vulnerable.
Comportamiento corregido: Valida que el puntero se mantenga dentro del límite declarado de rdlen después de extract_name().
Causa raíz: El análisis del mapa de bits NSEC avanza según p[1] en lugar de p[1]+2 (falta el tamaño del encabezado de ventana). Con bitmap_length=0, el puntero nunca avanza → bucle infinito.
Método de prueba: Envía un registro NSEC manipulado con window=0, bitmap_length=0. Si dnsmasq deja de responder a TODAS las consultas (se cuelga, no se cuelga), es vulnerable. Explotable ANTES de la validación RRSIG.
Comportamiento corregido: Avanza según p[1]+2 y omite mapas de bits de longitud cero.
Causa raíz: rdlen en RRSIG no se valida contra el tamaño mínimo (18 + nombre del firmante). La longitud de firma calculada se desborda negativamente → se trata como enorme → lectura OOB.
Método de prueba: Envía registros RRSIG con rdlen=10 (muy por debajo del mínimo de 31+ bytes). Caída = vulnerable.
Comportamiento corregido: Valida que rdlen >= campos_fijos + longitud_nombre_firmante antes de calcular la longitud de la firma.
Causa raíz: Los CLID DHCPv6 (hasta 65535 bytes) se codifican en hexadecimal mediante sprintf("%.2x") en daemon->packet (5131 bytes). CLID de 3000 bytes → cadena hexadecimal de 6000 bytes → desbordamiento. El proceso auxiliar se ejecuta como root.
Método de prueba: Envía SOLICIT DHCPv6 con un identificador de cliente de 3000 bytes. Requiere adyacencia IPv6 y --dhcp-script configurado. Caída del auxiliar = vulnerable.
Comportamiento corregido: Trunca o valida la longitud del CLID antes de la codificación hexadecimal.
Nota: Algunas compilaciones se compilan con -DNO_DHCP6 y NO se ven afectadas por esta CVE.
Causa raíz: process_reply() pasa la longitud del registro OPT (~23 bytes) en lugar de la longitud completa del paquete a check_source(). Todas las comprobaciones de límites fallan → la función siempre devuelve 1 (válido).
Método de prueba: Envía consultas DNS con la opción EDNS Client Subnet que contiene prefijos de origen falsificados. Si dnsmasq devuelve ECS sin validación, es vulnerable.
Comportamiento corregido: Pasa la longitud completa del paquete a check_source(), lo que permite comprobaciones de límites adecuadas según RFC 7871 Sección 9.2.
Actualice a dnsmasq 2.92rel2 (recomendado)
dnsmasq_cve_verify.py)La herramienta QA principal. Se ejecuta en la computadora de pruebas, envía paquetes de ataque al DUT, e informa PASS/FAIL claro para cada CVE. No se necesita modificación del DUT más allá del acceso SSH de solo lectura para la inspección del estado.
┌─────────────────────────────────────────────────────────────────────┐
│ Computadora de pruebas │
│ │
│ Interfaz LAN Interfaz WAN │
│ <IP_LAN_PORTATIL> <IP_WAN_PORTATIL> │
│ │ │ │
│ │ ┌────┴──────────────┐ │
│ │ │ Servidor DNS │ │
│ │ │ malicioso (puerto │ │
│ │ │ 53) │ │
│ │ └────┬──────────────┘ │
│ │ │ │
└────────┼───────────────────────────────┼────────────────────────────┘
│ Subred LAN │ Subred WAN
│ │
┌────────┼───────────────────────────────┼────────────────────────────┐
│ │ │ │
│ LAN: <IP_LAN_DUT> WAN: <IP_WAN_DUT> │
│ (puerta de enlace LAN) (enlace WAN) │
│ │
│ DUT (Router Linksys) │
│ dnsmasq (cualquier versión < 2.92rel2) │
│ │
│ resolv-file=/etc/resolv.conf │
│ → nameserver <IP_WAN_PORTATIL> ← establecido mediante GUI, nos reenvía │
│ │
└─────────────────────────────────────────────────────────────────────┘
Flujo de datos:
1. La herramienta envía una consulta DNS a la IP LAN del DUT (puerto 53)
2. El dnsmasq del DUT no puede resolver localmente → reenvía a IP_WAN_PORTATIL
3. Nuestro servidor malicioso en la interfaz WAN responde con el payload de exploit
4. El dnsmasq del DUT procesa la respuesta maliciosa → caída/cierre/supervivencia
5. La herramienta verifica el estado del DUT mediante SSH (solo lectura)
Ejemplo de configuración (sus IPs serán diferentes):