
CVE-2020-16899 - Logica di rilevamento della vulnerabilità Microsoft Windows TCP/IP e regola
Il 13 ottobre, Microsoft ha annunciato una vulnerabilità critica nello stack IPv6 di Windows, che consente a un attaccante di inviare pacchetti appositamente predisposti che provocano un immediato BSOD (Blue Screen of Death) sulle versioni più recenti di Windows 10 e Windows Server 2019. Sebbene questa vulnerabilità non sembri consentire l'esecuzione di codice all'attaccante, potrebbe essere utilizzata per effettuare attacchi denial-of-service di massa contro le versioni vulnerabili di Windows. La logica di rilevamento per la versione RCE più impattante di questa vulnerabilità è disponibile in CVE-2020-16898: "Bad Neighbor".
Questo documento è stato preparato da McAfee Advanced Threat Research. Ha lo scopo di fornire informazioni preziose per amministratori di rete e personale addetto alla sicurezza che desiderano comprendere meglio questa vulnerabilità e difendersi dallo sfruttamento. La firma qui prodotta deve essere attentamente valutata e testata in ambienti di staging prima di essere utilizzata in produzione e potrebbe trarre beneficio da una messa a punto specifica per la distribuzione target.
Le informazioni fornite nel presente documento sono soggette a modifiche senza preavviso e sono fornite "COSÌ COME SONO", con tutti i loro difetti, senza garanzie o assicurazioni circa l'accuratezza o l'applicabilità delle informazioni a qualsiasi situazione o circostanza specifica e a proprio rischio. Inoltre, non possiamo garantire alcun parametro di prestazione o efficacia per le firme.
La vulnerabilità è il risultato di una lettura fuori dai limiti (out-of-bounds read) che può verificarsi quando lo stack IPv6 di Windows elabora pacchetti ICMPv6 Router Advertisement (Tipo = 134) contenenti uno o più record Option DNSSL (Tipo Option = 31). Lo scopo del record DNSSL è fornire una lista di ricerca di suffissi di nomi DNS, contenuti nel suo ultimo campo. Poiché questa Search List può contenere più nomi DNS terminati da null uno dopo l'altro, il campo (e quindi l'intero record) può variare notevolmente in dimensione. Per gestire ciò, il record Option DNSSL contiene un proprio campo Length. Tuttavia, poiché la Length è conteggiata in incrementi di 8 byte, almeno uno dei nomi di dominio nella Search List può avere un padding aggiuntivo di null per preservare l'allineamento a 8 byte del record. È nell'elaborazione di questi null che si trova la vulnerabilità.
Per ogni nome di dominio nella Search List, lo stack IPv6 di Windows alloca un buffer di 256 byte. Poiché l'RFC 1035 limita i nomi di dominio a 255 byte, questo sarebbe tipicamente sufficiente a contenere un nome di dominio più il suo terminatore null. Tuttavia, il codice responsabile del consumo dei null finali alla fine di ogni nome di dominio ha un limite superiore pari ai byte rimanenti nell'Option, che può superare i 256 byte. Il risultato è che il codice che consuma i null può erroneamente consumare più byte di quelli allocati per il buffer, provocando una lettura fuori dai limiti. Nel caso in cui il buffer si trovi alla fine di una pagina di memoria, questa lettura OOB può causare un BSOD.
La firma Suricata per questa vulnerabilità si trova in cve-2020-16899.rules e contiene la seguente logica:
alert icmp any any -> any any (msg:"Potential CVE-2020-16899 Exploit"; lua:cve-2020-16899.lua; sid:202016899; rev:1;)
Il corrispondente script Lua può essere trovato in cve-2020-16899.lua. Contiene la logica necessaria per analizzare correttamente il layer ICMPv6 e identificare il potenziale sfruttamento di CVE-2020-16899, come segue:
Una volta individuato l'inizio del layer ICMPv6, testiamo il primo byte del layer per assicurarci che sia un pacchetto ICMPv6 Router Advertisement - se non lo è, usciamo.
Poiché le primitive di Suricata non sono state aggiornate per analizzare le Option ICMPv6, saltiamo semplicemente al 17° byte del layer ICMPv6, poiché è lì che dovrebbero iniziare le Option, se presenti (i primi 16 byte sono campi a lunghezza fissa, secondo l'RFC 4443). Da lì, iteriamo su ogni Option fino a quando non esauriamo i byte nel pacchetto. Per ogni Option, iniziamo ispezionando il primo byte, che corrisponde al campo Option Type. Sebbene ignoriamo tutte le Option che non sono DNSSL, per Option Type = 31 (DNSSL), controlliamo se la Length (secondo byte nell'Option) è maggiore o uguale a 35, la lunghezza minima necessaria per attivare la vulnerabilità: