
Un PoC per CVE-2018-7249
Un problema è stato scoperto in secdrv.sys come fornito in Microsoft Windows Vista, Windows 7, Windows 8 e Windows 8.1 prima di KB3086255, e come fornito in Macrovision SafeDisc. Due chiamate opportunamente temporizzate a IOCTL 0xCA002813 possono causare una condizione di competizione che porta a un use-after-free. Quando sfruttata, un utente malintenzionato non privilegiato può eseguire codice arbitrario nel kernel.
La vulnerabilità è stata segnalata a Microsoft e, poiché non interessa un sistema Windows aggiornato (solo versioni precedenti a KB3086255), non prenderanno alcuna misura. È stato testato e sfruttato con successo su Windows 7 x86.
Correlato anche a CVE-2018-7250.

Questo documento riporta la mia piccola ricerca sul driver secdrv.sys. Tutti i comportamenti descritti del driver sono stati ottenuti tramite reverse engineering e potrebbero essere errati/imprecisi.
L'offset 0x4 del buffer di input per l'IOCTL (0x0CA002813) contiene un numero che chiamerò TYPE. La funzione handler principale di questo IOCTL (0x0CA002813), sub_11A88, riceve 3 diversi tipi: 0x96, 0x97 e 0x98.
Dopo che il tipo di IOCTL 0x96 ha allocato un nuovo chunk e lo ha inizializzato, ma non completamente, copia il chunk in modalità utente. 16 bit nel chunk appena allocato non sono stati inizializzati e contengono dati da precedenti allocazioni PagedPool. I bit non inizializzati vengono poi copiati in modalità utente all'indirizzo .text:00011BE9 dall'istruzione REP MOVSD. Codice PoC qui.
Quando viene chiamato il tipo di IOCTL 0x97, trova il chunk necessario, precedentemente allocato con il tipo 0x96, tramite il suo tag. Se l'allocazione è già stata liberata dall'IOCTL tipo 0x97, DeviceIoControl restituisce un errore. La vulnerabilità qui è che l'allocazione utilizzata dal tipo 0x97 può essere liberata DURANTE la sua operazione (poiché non vengono utilizzati meccanismi di sincronizzazione) causando così un use-after-free se la competizione viene vinta. Se un utente malintenzionato riesce a liberare il chunk durante l'operazione del tipo di IOCTL 0x97 (usando il tipo 0x98) e ad allocare un nuovo chunk, controllato da lui, nella stessa identica posizione di memoria, può sovrascrivere un puntatore a un'altra struttura, che contiene un puntatore a funzione che può essere utilizzato per dirottare il flusso di esecuzione del driver ed eseguire codice arbitrario in ring 0. Poiché la routine di crittografia viene eseguita su un buffer fornito dall'utente, che può essere di dimensioni enormi, la crittografia può richiedere molto tempo per essere eseguita, fornendo così una finestra temporale perfetta affinché l'IOCTL tipo 0x98 possa liberare il chunk mentre è ancora in uso. La finestra temporale può essere così lunga (più di 1 secondo!) che la competizione può essere vinta in modo affidabile al primo tentativo. L'use-after-free inizia a .text:00011B68 e la chiamata effettiva, che verrà dirottata per saltare allo shellcode, avviene a .text:00011B86.
I passaggi per sfruttare con successo questa vulnerabilità sono i seguenti:
OS: Windows 7 Kernel Version 7600 MP (1 procs) Free x86 compatible Built by: 7600.16385.x86fre.win7_rtm.090713-1255 VM: 4GB RAM, 1 CPU Hardware: Windows 10 Pro 64 bit, Motherboard Gigabyte Z370 HD3, 16GB RAM, Intel i5-8400 2.80GHz (6 CPUs)