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