23 mayo 2012

Reversing malware tales: IsDebuggerPresent ?

Llevo tiempo queriendo iniciar una saga de posts sobre análisis de malware donde tratar los distintos tipos de análisis, ya sean por comportamiento (sandbox, herramientas tipo processmonitor, etc) o vía debugger.

Así mismo me fijé como objetivo que fuese sobre muestras 'in the wild'.

Debo agradecer a Javi, del GDT,  su amabilidad a la hora de proveerme de muestras que ellos tienen disponibles por su ímproba labor en la investigación de delitos informáticos.

Hoy voy a hablar de algo que encontré a la hora de analizar una de las muestras que me facilitaron. Es muy típico de un programa que está orientado a 'cosas oscuras' que incorpore algún tipo de técnica para protegerse de miradas excesivamente curiosas. Muchos utilizan 'packers' para ofuscar el código y otros, como del que vamos a hablar hoy, sencillas técnicas para detectar la presencia de debuggers.

En concreto esta muestra hace uso de la función IsDebuggerPresent() para detectar si está siendo ejecutado a través de un debugger.

¿Cómo detectar que se está haciendo uso de de esta función? El primer paso es abrir la muestra con Ollydbg y ver las llamadas a la API que emplea el malware:


Olly nos muestra las diferentes funciones que emplea este espécimen de Malware y de entre toda la lista, nos encontramos con:


Con lo que tenemos la certeza de que este espécimen, en algún punto, va a intentar averiguar si está siendo analizado por un debugger. Evidentemente esto es bastante sospechoso.

Vamos a poner un breakpoint para tener el control justo cuando el malware vaya a hacer uso de dicha función.


Y pulsamos F9 para lanzar el programa, que se detendrá justo cuando se vaya a hacer uso de la función


Si agrandamos la imagen (click en ella) podemos ver que Olly nos indica que el programa está pausado justo en la función IsDebuggerPresent().

Esta función pertenece a otro módulo (kernel32) por lo que deberemos retornar al programa principal para ver que sucede justo después de esa llamada.

Para ello vamos al menú 'Debug' y seleccionamos 'Execute till user code' o pulsamos ALT+F9


Lo que nos devolverá al programa principal justo después de la llamada a IsDebuggerPresent()


Vemos que, justo después, lo que hace el programa es verificar si EAX vale 0 (TEST EAX, EAX), en EAX está almacenado el resultado de la función IsDebuggerPresent() y como en este caso es cierto, el programa se está ejecutando en un debugger, el valor de EAX es 1

Podemos leer en la descripción de IsDebuggerPresent() lo siguiente:
'If the current process is running in the context of a debugger, the return value is nonzero.'

También vemos que, como el resultado de TEST EAX, EAX no es 0, el flag Z no se activa y permanece a 0


Si pulsamos F7, iremos a la siguiente línea de ensamblador que es un salto condicional JNZ 


Como podemos ver si agrandamos la imagen, olly en la parte inferior nos indica que 'Jump is taken', es decir que el va a saltar porque JNZ significa 'Jump if NOT Z' y como el resultado de TEST EAX, EAX no ha activado el flag Z, hará ese salto condicional que nos lleva a una rutina de exit. Obviamente esto no es lo que queremos ya que nos perderemos la parte divertida donde empiezan los fuegos artificiales.

¿Como resolvemos esta situación? Muy fácil, tan solo tenemos que, en ese punto, hacer doble click sobre el flag Z y cambiar su valor a 1, de esa forma el Jump no se hará y el programa seguirá su curso esperado.


Una vez cambiado el flag Z, podemos ver que Olly nos dice que no se hará el salto.


Como hemos visto saltarse esta 'protección' es extremadamente fácil, en este punto podríamos cambiar ese JNZ por NOPs y salvar el fichero con las modificaciones para que la protección quede desactivada para siempre.

No obstante, hay un método más fácil. Existe un plugin para Olly llamado 'Hide Debugger' que directamente lidia con este tipo de 'protecciones' para evitar que el debugger sea detectado. No solo se ocupa de IsDebuggerPresent() sino de otras técnicas que se emplean habitualmente.

4 comments :

aorteguita dijo...

Hay mucho software legítimo que utiliza esta función para los mismos propósitos, ya me la he encontrado varias veces en software de compañías grandes cómo forma de protección (...).

Longinos Recuero Bustos dijo...

Me parece una propuesta interesante y te animo a que continúes con la saga de post de este tipo. Si así lo hicieras, cuenta con un fiel seguidor.

Invitado dijo...

Hombre, un software que como unica tecnica antidebug llame a esa funcion no solo tiene delito, es que me esta incluso avisando de donde empieza la parte buena... Tecnicas hay mil, un doc reciente: http://pferrie.host22.com/papers/antidebug.pdf

mercano dijo...

MUY BUENO