
Automatisiertes Tool zur Verifizierung von Schwachstellen für 6 dnsmasq-CVEs (CVE-2026-2291, 4890, 4891, 4892, 4893, 5172)
Automatisiertes Blackbox-Tool zur Verifizierung von 6 dnsmasq-Schwachstellen (Mai 2026). Sendet Angriffspakete an ein aktives DUT und meldet PASS/FAIL – ohne Zugriff auf den Quellcode.
# 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 | Typ | Angriffsvektor | Betroffenes Feature |
|---|---|---|---|---|
| CVE-2026-2291 | 9.2 | Heap-Pufferüberlauf | Remote | extract_name() – immer aktiv |
| CVE-2026-5172 | 7.5 | OOB-Read / Absturz | Remote | extract_addresses() – immer aktiv |
| CVE-2026-4890 | 7.5 | Endlosschleifen-DoS | Remote | NSEC-Bitmap-Parsing (--dnssec) |
| CVE-2026-4891 | 5.3 | Heap-OOB-Read | Remote | RRSIG-Validierung (--dnssec) |
| CVE-2026-4892 | 8.4 | Heap-Überlauf → Root | Lokal/Benachbart | DHCPv6-CLID (--dhcp-script + DHCPv6) |
| CVE-2026-4893 | 5.3 | Validierungsumgehung | Remote | ECS-Quellprüfung (--add-subnet) |
Grundursache: union bigname deklariert char name[MAXDNAME], aber escapte Zeichen können einen Namen auf 2*MAXDNAME+1 Bytes erweitern, was einen Heap-Überlauf verursacht.
Testmethode: Sendet DNS-Anfragen mit Domainnamen, die Zeichen mit hohem Bit (0x80+) enthalten, die intern als \DDD escapt werden (4 Bytes pro Eingabebyte). Wenn dnsmasq abstürzt oder nicht mehr antwortet, ist es verwundbar.
Verhalten nach dem Patch: Lehnt überdimensionierte Namen ordnungsgemäß ab (FORMERR/REFUSED) oder verwendet einen vergrößerten Puffer.
Grundursache: Ein verfälschtes rdlen-Feld lässt extract_name() den Zeiger über das Record-Ende hinaus verschieben. Ein Underflow der verbleibenden Bytes erzeugt einen riesigen Wert → massiver OOB-Read → Absturz.
Testmethode: Sendet DNS-Antworten mit CNAME-Records, bei denen rdlen kleiner ist als der tatsächlich kodierte Name. Wenn dnsmasq abstürzt, ist es verwundbar.
Verhalten nach dem Patch: Validiert, dass der Zeiger nach extract_name() innerhalb der deklarierten rdlen-Grenze bleibt.
Grundursache: Das Parsen der NSEC-Typ-Bitmap erhöht den Zeiger um p[1] statt um p[1]+2 (fehlende Fenster-Header-Größe). Bei bitmap_length=0 bewegt sich der Zeiger nie weiter → Endlosschleife.
Testmethode: Sendet einen präparierten NSEC-Record mit window=0, bitmap_length=0. Wenn dnsmasq auf ALLE Anfragen nicht mehr reagiert (hängt, stürzt nicht ab), ist es verwundbar. Vor der RRSIG-Validierung ausnutzbar.
Verhalten nach dem Patch: Erhöht um p[1]+2 und überspringt Bitmaps mit Länge null.
Grundursache: rdlen in RRSIG wird nicht gegen die Mindestgröße (18 + Signer-Name) validiert. Die berechnete Signaturlänge läuft negativ unter → wird als riesig behandelt → OOB-Read.
Testmethode: Sendet RRSIG-Records mit rdlen=10 (weit unter dem Minimum von 31+ Bytes). Absturz = verwundbar.
Verhalten nach dem Patch: Validiert rdlen >= fixed_fields + signer_name_length, bevor die Signaturlänge berechnet wird.
Grundursache: DHCPv6-CLIDs (bis zu 65535 Bytes) werden per sprintf("%.2x") hex-kodiert in daemon->packet (5131 Bytes) geschrieben. Eine 3000-Byte-CLID → 6000-Byte-Hex-String → Überlauf. Der Helper-Prozess läuft als Root.
Testmethode: Sendet ein DHCPv6-SOLICIT mit 3000-Byte-Client-Identifier. Erfordert IPv6-Nachbarschaft und konfiguriertes --dhcp-script. Absturz des Helpers = verwundbar.
Verhalten nach dem Patch: Kürzt oder validiert die CLID-Länge vor der Hex-Kodierung.
Hinweis: Einige Builds werden mit -DNO_DHCP6 kompiliert und sind von dieser CVE NICHT betroffen.
Grundursache: process_reply() übergibt die OPT-Record-Länge (~23 Bytes) statt der vollen Paketlänge an check_source(). Alle Grenzwertprüfungen schlagen fehl → die Funktion gibt immer 1 (gültig) zurück.
Testmethode: Sendet DNS-Anfragen mit der EDNS-Client-Subnet-Option, die gefälschte Quellpräfixe enthält. Wenn dnsmasq ECS ohne Validierung zurücksendet, ist es verwundbar.
Verhalten nach dem Patch: Übergibt die volle Paketlänge an check_source(), wodurch ordnungsgemäße Grenzwertprüfungen gemäß RFC 7871 Abschnitt 9.2 ermöglicht werden.
Upgrade auf dnsmasq 2.92rel2 (empfohlen)
dnsmasq_cve_verify.py)Das primäre QA-Tool. Läuft auf dem Test-Laptop, sendet Angriffspakete an das DUT und meldet für jede CVE ein eindeutiges PASS/FAIL. Über den schreibgeschützten SSH-Zugriff zur Zustandsprüfung hinaus sind keine Änderungen am DUT erforderlich.
┌─────────────────────────────────────────────────────────────────────┐
│ 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 │
│ │
└─────────────────────────────────────────────────────────────────────┘
Datenfluss:
Beispielaufbau (Ihre IPs weichen ab):
| Rolle | IP (Beispiel) |
|---|---|
| Laptop-LAN | 192.168.1.254 |
| Laptop-WAN | 10.0.0.211 |
| DUT-LAN | 192.168.1.1 |
| DUT-WAN | 10.0.0.214 |
Die wichtigste Anforderung: Laptop-WAN-IP und DUT-WAN-IP müssen im selben Subnetz liegen, damit das DUT den Laptop als Upstream-DNS-Server erreichen kann.