miércoles, 23 de julio de 2014

Antivirus K.O. Evasión de motores heurísticos

Los motores heurísticos utilizados por los antivirus en mayor o menor medida, se encargan de monitorizar entre otras cosas, las llamadas a funciones y librerías que el malware utiliza en su ejecución para realizar ciertas acciones determinadas. Hemos hablado de cómo mover la Import Table a otros offsets, pero la heurística va más allá. El objetivo de esta entrada, sería buscar una alternativa, para migrar las llamadas externas que el ejecutable realiza mediante la Import Table, a las librerías del sistema y finalmente, a sus APIs. Leos de indetectables, hace varios años ya habló de este tema y ciertamente, sigue estando al orden del día.
Para hacer la prueba, yo he decidido utilizar el siguiente código, el cual no es más que un simple Downloader, con posiblemente la API más detectada por los antivirus en Visual Basic, URLDownloadToFileA.

Algo muy especial de Visual Basic 6 y anteriores, es que las llamadas a las librerías y funciones que utiliza un ejecutable no vienen incluidas en la Import Table, como hemos visto que sucede en el resto de aplicaciones con mis anteriores entradas.
¿Entonces cómo las llama?
Utiliza una función llamada DllFunctionCall, la cual carga en la Import Table siempre y cuando en el código fuente, se haya declarado la utilización de una API del sistema. Cuando se ejecuta esta función, trata de cargar dinámicamente el nombre del API a utilizar y la librería a la cual hay que realizar la llamada. Las aplicaciones de Visual Basic compiladas en código nativo, contienen strings en las que se pueden leer las APIs y librerías, pero esto no es del todo fiable, ya que desconocemos si estas están siendo utilizadas de alguna manera por el software. Así que si encontrásemos en un binario de Visual Basic el API DllFunctionCall procedente de la librería MSVBVM60.DLL, tendríamos que desensamblar para saber realmente a quien llama.

Abriremos el binario en OllyDBG y nos iremos directamente a visualizar todas las llamadas inter-modulares que contiene, para tratar de dar con DllFunctionCall.


Gracias a que este binario es tan pequeño, no nos costará nada encontrarla.

Tras presionar Enter para saltar hasta la función, nos encontraremos con un CALL que espera a que el registro EAX le traiga la dirección de memoria donde realizar la llamada. Con lo que decidí colocar un BreakPoint y ejecutar el binario para ver cuál será su próxima acción.

Tras calcular su salto, EAX ahora transporta la dirección del API URLDownloadToFileA que se cargó de forma dinámica.

Tras presionar la tecla Enter para saltar antes de que lo haga la ejecución, llegamos a la librería urlmon.dll, donde se encuentra el API. Debido a que esta función es bastante grande y tendría que recolocar un gran número de llamadas y saltos para lograr migrarla por completo y evitar que se realizasen llamadas externas, he decidido tan solo copiar un pequeño número de instrucciones. La migración de estas instrucciones no rompería el ejecutable, ya que tan solo mueven e insertan datos sobre los registros.

Realizaremos una copia en binario de las direcciones para llevar a cabo la migración a un hueco.

Ya que llevo torturando a los binarios de Visual Basic desde que tengo uso de razón, osea hace poco tiempo jajajaj… sé dónde se encuentran lugares con huecos para mover la función de urlmon.dll. Y justo esa cadena donde se incluye la dirección de compilación “IDEAS POSIBLE POST” es un lugar cojonudo.

Así que llevaré hasta allí, mi apisonadora de NOPs y pienso montar en ese hueco mi chiringuito... no hay quien me pare.

Tras un Binary Paste seleccionando el hueco, migramos parte de la estructura del API.

Como me ha sobrado espacio, puedo incluir sin problemas el salto para redireccionar el flujo a la siguiente instrucción de urlmon.dll, justo al inicio de un bucle que hemos decidido evitarlo para no vernos con posibles complicaciones.

El siguiente paso es hacer el desvío adecuado, en la instrucción JMP donde el registro EAX indicaba la posición a saltar. Ya que DllFunctionCall en este ejecutable no se va a utilizar en otro momento, podemos hardcodear la próxima dirección de memoria a saltar. No obstante, esto no se realizaría de esta manera con un malware complejo, con lo que habría que saltar a otro hueco he incluir un pequeño algoritmo que mediante CMP o TEST, devolviese 1 o 0 para definir un salto al nuevo cálculo del registro EAX o a la dirección que nosotros hemos definido… ¡vamos un IF de los de toda la vida!

Tras copiar todas las modificaciones realizadas…

Al enviar ambas muestras a Virustotal, tanto McAfee como CMC los cuales utilizan firmas heurísticas para esta detección desaparecen, seguidos de antivirus conocidos como F-Prot y Commtouch, que en este caso comparten la misma firma.

Siendo sinceros, la migración de las rutinas a las que llama la Import Table puede llegar a ser un “trabajo de chinos”. Es fácil encontrarse con miles de direcciones. Aplicaciones como la española Themida, tratan de virtualizar en una especie de SandBox todas estas llamadas externas, para solventarlas internamente, con lo que es tan utilizado en temas de evasión antivirus.
No obstante, también es posible encontrar APIs con funciones pequeñas, si recuerdan mi anterior entrada, vimos la sencillez de IsDebuggerPresent. Si todos recuerdan la aplicación Topo, la cual nos ayudó en alguna entrada a buscar huecos en ejecutables o sencillamente a crearlos, esta no cuenta por defecto con ninguna protección Anti-Debugging, pero gracias a que el API IsDebuggerPresent es tan pequeña, podremos agregarla fácilmente redireccionando el Entry Point de la aplicación a una rutina que compruebe la existencia de un Debugger mediante este API.

De tal manera que si ejecutamos Topo desde OllyDbg, terminaremos saltando a una zona vacía y no podremos seguir debuggeando.

Sin embargo, tras hacer doble click sobre el binario, este se ejecutará sin ningún problema.

Por último, podemos cerrar las bocas de aquellos que dicen que Visual Basic 6 tiene un potencial limitado, aunque todos sabemos que las limitaciones nos las ponemos nosotros mismos… o nuestra falta de imaginación. Debido a que es posible ejecutar ristras de opcodes desde este lenguaje sin ningún problema, tal y como muestra la siguiente imagen, un código creado por KarCrack embebiendo la rutina de IsDebuggerPresent.

Se me ocurren ideas, y casualmente no son buenas… como incluir la shellcode de Poison Ivy o la de mi anterior entrada inyectando una Shell en el stub de un Crypter.

Como es lógico, Avira Antivir detecta el compilado como Dropper, por contener un posible malware… aunque tan solo transportemos a un pijo con un polo de Lacoste en opcodes, el antivirus sospechará, y con razón.
No obstante, la evasión antivirus una vez más, es tan sencilla como la utilización de un AVFucker.

¡Espero que les gustase la entrada tanto como a mi prepararla, me voy a tomar unas buenas cervezas belgas a vuestra salud! :)

Saludo 4n4les! 8==D

Fuente: http://www.enelpc.com/2014/07/antivirus-ko-evasion-de-motores.html

No hay comentarios:

Publicar un comentario