
Strumento automatizzato di verifica dei difetti per 6 CVE di dnsmasq (CVE-2026-2291, 4890, 4891, 4892, 4893, 5172)
Strumento black-box automatizzato per verificare 6 vulnerabilità di dnsmasq (maggio 2026). Invia pacchetti di attacco a un DUT attivo e riporta PASS/FAIL — non è necessario l'accesso al codice sorgente.
# Set DUT DNS to your laptop's WAN IP via GUI first, then:
sudo python3 dnsmasq_cve_verify.py --laptop <YOUR_WAN_IP> --dut <DUT_LAN_IP> --dut-pass <SSH_PASS>
# Example:
sudo python3 dnsmasq_cve_verify.py --laptop 10.0.0.211 --dut 192.168.1.1 --dut-pass '12345Asdf@'
| CVE | CVSS | Tipo | Vettore di attacco | Funzionalità interessata |
|---|---|---|---|---|
| CVE-2026-2291 | 9.2 | Overflow del buffer heap | Remoto | extract_name() — sempre attiva |
| CVE-2026-5172 | 7.5 | Lettura fuori dai limiti / crash | Remoto | extract_addresses() — sempre attiva |
| CVE-2026-4890 | 7.5 | DoS loop infinito | Remoto | Parsing del bitmap NSEC (--dnssec) |
| CVE-2026-4891 | 5.3 | Lettura heap fuori dai limiti | Remoto | Validazione RRSIG (--dnssec) |
| CVE-2026-4892 | 8.4 | Overflow heap → root | Locale/Adiacente | CLID DHCPv6 (--dhcp-script + DHCPv6) |
| CVE-2026-4893 | 5.3 | Bypass della validazione | Remoto | Controllo sorgente ECS (--add-subnet) |
Causa principale: union bigname dichiara char name[MAXDNAME], ma i caratteri di escape possono espandere un nome fino a 2*MAXDNAME+1 byte, causando un overflow dell'heap.
Metodo di test: Invia query DNS contenenti nomi di dominio con caratteri ad alto bit (0x80+) che vengono internamente convertiti in escape \DDD (4 byte per byte di input). Se dnsmasq crasha o smette di rispondere, è vulnerabile.
Comportamento corretto: Rifiuta i nomi sovradimensionati senza errori (FORMERR/REFUSED) oppure utilizza un buffer ingrandito.
Causa principale: Un campo rdlen falsificato consente a extract_name() di far avanzare il puntatore oltre la fine del record. L'underflow dei byte rimanenti produce un valore enorme → lettura fuori dai limiti massiccia → crash.
Metodo di test: Invia risposte DNS con record CNAME in cui rdlen è più piccolo del nome effettivamente codificato. Se dnsmasq crasha, è vulnerabile.
Comportamento corretto: Verifica che il puntatore rimanga entro il limite rdlen dichiarato dopo extract_name().
Causa principale: Il parsing del bitmap di tipo NSEC avanza di p[1] invece di p[1]+2 (manca la dimensione dell'header della finestra). Con bitmap_length=0, il puntatore non avanza mai → loop infinito.
Metodo di test: Invia un record NSEC appositamente costruito con window=0, bitmap_length=0. Se dnsmasq smette di rispondere a TUTTE le query (si blocca, non crasha), è vulnerabile. Sfruttabile PRIMA della validazione RRSIG.
Comportamento corretto: Avanza di p[1]+2 e salta i bitmap a lunghezza zero.
Causa principale: rdlen in RRSIG non viene validato rispetto alla dimensione minima (18 + nome del firmatario). La lunghezza della firma calcolata va in underflow negativo → viene trattata come enorme → lettura fuori dai limiti.
Metodo di test: Invia record RRSIG con rdlen=10 (molto al di sotto del minimo di 31+ byte). Crash = vulnerabile.
Comportamento corretto: Valida rdlen >= fixed_fields + signer_name_length prima di calcolare la lunghezza della firma.
Causa principale: I CLID DHCPv6 (fino a 65535 byte) vengono codificati in esadecimale tramite sprintf("%.2x") in daemon->packet (5131 byte). Un CLID di 3000 byte → stringa esadecimale di 6000 byte → overflow. Il processo helper gira come root.
Metodo di test: Invia SOLICIT DHCPv6 con un Client Identifier di 3000 byte. Richiede adiacenza IPv6 e --dhcp-script configurato. Crash dell'helper = vulnerabile.
Comportamento corretto: Tronca o valida la lunghezza del CLID prima della codifica esadecimale.
Nota: Alcune build vengono compilate con -DNO_DHCP6 e NON sono interessate da questa CVE.
Causa principale: process_reply() passa la lunghezza del record OPT (~23 byte) invece della lunghezza completa del pacchetto a check_source(). Tutti i controlli dei limiti falliscono → la funzione restituisce sempre 1 (valido).
Metodo di test: Invia query DNS con l'opzione EDNS Client Subnet contenente prefissi sorgente spoofati. Se dnsmasq rispecchia l'ECS senza validazione, è vulnerabile.
Comportamento corretto: Passa la lunghezza completa del pacchetto a check_source(), consentendo i corretti controlli dei limiti secondo la RFC 7871 Sezione 9.2.
Aggiornare a dnsmasq 2.92rel2 (consigliato)
dnsmasq_cve_verify.py)Lo strumento QA principale. Viene eseguito sul laptop di test, invia pacchetti di attacco al DUT e riporta un chiaro PASS/FAIL per ogni CVE. Non è necessaria alcuna modifica del DUT oltre all'accesso SSH in sola lettura per l'ispezione dello stato.
┌─────────────────────────────────────────────────────────────────────┐
│ Testing Laptop │
│ │
│ LAN interface WAN interface │
│ <LAPTOP_LAN_IP> <LAPTOP_WAN_IP> │
│ │ │ │
│ │ ┌────┴──────────────┐ │
│ │ │ Malicious DNS │ │
│ │ │ Server (port 53) │ │
│ │ └────┬──────────────┘ │
│ │ │ │
└────────┼───────────────────────────────┼────────────────────────────┘
│ LAN subnet │ WAN subnet
│ │
┌────────┼───────────────────────────────┼────────────────────────────┐
│ │ │ │
│ LAN: <DUT_LAN_IP> WAN: <DUT_WAN_IP> │
│ (LAN gateway) (WAN uplink) │
│ │
│ DUT (Linksys Router) │
│ dnsmasq (any version < 2.92rel2) │
│ │
│ resolv-file=/etc/resolv.conf │
│ → nameserver <LAPTOP_WAN_IP> ← set via GUI, forwards to us │
│ │
└─────────────────────────────────────────────────────────────────────┘
Data flow:
1. Tool sends DNS query to DUT LAN IP (port 53)
2. DUT's dnsmasq can't resolve locally → forwards upstream to LAPTOP_WAN_IP
3. Our malicious server on WAN interface replies with exploit payload
4. DUT's dnsmasq processes the malicious response → crash/hang/survive
5. Tool checks DUT state via SSH (read-only)
Esempio di configurazione (i tuoi IP saranno diversi):
| Ruolo | IP (esempio) |
|---|---|
| Laptop LAN | 192.168.1.254 |
| Laptop WAN | 10.0.0.211 |
| DUT LAN | 192.168.1.1 |
| DUT WAN | 10.0.0.214 |