Como mola poner un título en inglés, y luego redactar el
artículo en español. Sobre todo en estos tiempos en los que se puso tanto de
moda el vender humo, ya hasta el que usa la palabra “postureo”, me incita a
pensar que se junta con gente muy cool… ¡No
lo soporto! ¡Dudo hasta de entrecomillar esas mierdas! ¡Puta invasión Hipster!
Hoy quería hablaros sobre un
sapo que me he comprado, bueno, ya me pongo serio.
Existen varios métodos para evitar el tener que declarar un API en la Import Table de un binario, y sin
embargo llegar a utilizarla. Métodos como Call
API By Name, Call API By Hash,
embeber una Shellcode suelen ser los
más habituales. En el caso que expongo, el API se encuentra declarada, pero no
con el nombre de la misma.
La idea que se me había ocurrido, trata de probar a llamar a
las funciones que exportan las librerías, utilizando los números ordinales que
las referencian, en lugar de a sus nombres. Este método por cuestiones de
compatibilidad suele ser desaconsejado, ya que es posible que dependiendo del
sistema operativo donde el binario se ejecute, pueda llegar a no funcionar. Esto
existe sencillamente porque se encuentran multitud de funciones sin nombre, y
esta sería la única forma de poder llamarlas. No obstante, podemos utilizar mi
anterior método
DAF para embeber las librerías que necesitemos en el sistema a modo Dropper, antes de ejecutar el malware en
cuestión.
Para la prueba de concepto quería empezar con algo sencillo,
aunque posiblemente muy detectado. Con lo que se me ocurrió generar el “stage 1”,
la primera etapa de conexión del payload
de Metasploit “reverse_tcp”.
Para la ejecución de la ShellCode,
he compilado un binario desarrollado… ¿cómo
no? en Visual Basic 6, para no
perder la costumbre, mediante el uso de CallWindowProcA.
La herramienta Pestudio,
abrirá el camino para identificar de forma rápida el número ordinal que utiliza
en mi sistema la función CallWindowProcA
de la librería user32.dll. La
siguiente imagen muestra las APIs que esta librería exporta.
El número ordinal 1531
nos dará acceso a invocarla, con lo que realizaré los cambios en el código
anteriormente utilizado para llamarla.
Tras comprobar ambos binarios, se muestra como se realiza la
llamada en este caso. Algo físicamente más complejo de detectar que mi anterior
publicación del Método
Mmove, en el que se migraban los nombres de las funciones, a otros huecos.
Comprobando con Metasploit,
si este último binario realmente funciona.
Ahora solo queda enviar las muestras a un Scanner Online.
¡Esto funciona muñeca!
Como es lógico, algún antivirus debía de detectar la muestra, más que nada
porque se encuentra la ristra de opcodes
que forman el payload embebido sin ningún
tipo de codificación o cifrado. Para evitar estas detecciones, lo más seguro es
que bastase con darle uso a una herramienta como Abronsius Code Ofuscator, que
utilicé anteriormente en la creación de 4n4lCrypter.
No podía dejar escapar esta oportunidad, para añadir una
detección que saldrá en la próxima versión de 4n4lDetector, sobre este
tipo de binarios compilados en Visual
Basic x, que utilicen la invocación
de las APIs mediante sus números ordinales.
¡Hasta aquí todo chahi
piruleta! Pero realmente lo divertido, sería modificar un binario ya
detectado del cual no tenemos acceso a sus fuentes, para llevar a cabo un
limpiado de detecciones como venía haciendo tiempo atrás.
Así que como Visual
Basic 6, internamente es un poco tedioso a la hora de hacer las llamadas a
las APIs, ya que las carga de forma dinámica a través de otra función llamada DllFunctionCall. Me he pasado “temporalmente”
a un lenguaje, el cual deja de lado las marranadas en su Import Table, Assembler.
Algo muy sencillo, un Downloader
que utilizará tres APIs. La muy quemada URLDownloadToFile,
ShellExecute y ExitProcess. ¡El trío de las
blacklist!
Para el POC, he subido una calculadora de Windows a Google
Drive.
Es salir de Visual
Basic, y asombra lo maravilloso que es compilar binarios de 2KB… jajajaa
He vuelto a utilizar Pestudio
para leer los ordinales de estas nuevas funciones, las cuales proceden de
librerías diferentes.
La primera prueba la haré con URLDownloadToFile, así que vuelta a un editor PE. Ya saben que yo soy
de utilizar LordPE, así que
abriremos el binario con este, nos dirigiremos a su tabla de importaciones y le
daremos a editar.
Eliminaremos los bytes del Hint y el nombre de la API,
y agregaremos en ThunkValue el
ordinal en hexadecimal, sumado a (0x80000000),
con el cual se representa este tipo de dato.
Tras comprobar que este nuevo ejecutable funciona sin problemas,
se realiza el envío de ambas muestras.
Jajajaa… a mí personalmente me hace gracia. No pude evitar
ponerme algo de música, unas 10 horas de Vaina Loca,
una hora por antivirus saltado con tal de evadirme.
Ya que estaba con el ritmo en las venas, decidí quitarme de
encima también las declaraciones de ShellExecute
y ExitProcess. Así que hice lo propio
con LordPE. Una nota importante, tras
revisar el binario modificado con este software, me di cuenta de que no realizaba
el borrado completo del nombre de la función, sino que tan solo ponía a byte nulo el primero del nombre, evitando
su lectura. No obstante, es sencillo terminar de dejarlo limpio con un editor
hexadecimal.
Tras comprobar que el binario sigue cumpliendo con su
función. Lo envío de vuelta al Scanner Online.
Dr. Web se baja
del carro. Realmente los dos que quedan, es posible que utilicen alguna rutina
de detección basada en la URL, con lo que seguro es bastante sencillo evitarles
ofuscando la cadena.
Saludos 4n4les! ;)
Excelente entrada German
ResponderEliminarLlamar a la API por ordinal, con el nombre, con un hash del nombre o con ¿una shell? (que es eso de obtener la direccion de memoria de una funcion de una librería con una shell?) es lo mismo, solamente que se evita hardcodear los nombres de las APIs. Llamar por ejemplo a WriteProcessMemory en ejecucion termina siendo igual de detectable usando cualquier metodo.
ResponderEliminarEfectivamente, es más sencillo detectar el binario por comportamiento... pero prueba a utilizar un antivirus doméstico, no sé, Avira Antivir por ejemplo. Tiene buenas rutinas genéricas, pero en su mayoría se basa en detecciones por firmas y con poco que modifiques, se consigue evadir las condicionales. Si funcionase todo tan bien como dices, a día de hoy los trilladísimos RunPE, no tendrían nada que hacer.
EliminarSaludos!
Es que ya no tienen nada que hacer. Es un método sobreexplotado en el 2006, Estamos a 2015. Si todo funcionara tan bien como decís, todo estaría super activo, pero si te fijas bien, esta todo super muerto, no sale malware nuevo, no infectan nada critico, ni siquiera copypastean zeus, etc.
Eliminarhttps://underc0de.org/foro/malware/los-crypters-genericos-ya-se-extinguieron/
Ya leí ese artículo anteriormente. Será que al ver cientos de muestras indetectables y nuevas al día, me causa estragos.
Eliminarta bueno hay que considerar las variaciones
ResponderEliminarsegun el sistema operativo
Vamos por partes:
ResponderEliminarLo de que los crypters estan muertos..... estara muertos los tipicos en vb6 con el tipico runpe, pero hay un monton de nuevas familias de crypters y sino busca " Hallaj runpe" por poner un ejemplo.
Y ahora mi duda existencial, lo de los ordinales no es generico, es decir en un win10 el CallWindowProcA es 1532, creo que en ejemplo es un win 7, como mejora yo le pondria una extraccion de los ordinales que se necesiten nada mas arrancar para hacerlo multi windows.
En este caso de CallWindowProcA, podríamos utilizar el ordinal 1532. Ya que en Windows 7 coincide con CallWindowProcW (su declaración en Unicode). La he comprobado y es funcional.
Eliminarhttp://s15.postimg.org/6lrjoyom3/image.png
Se podría utilizar un Dropper o un Downloader, que identificase el sistema operativo antes de instalar el malware. Sería algo más sencillo.
Saludos! :)
grande capo grande vomo
ResponderEliminarVamos Germán ánimo no dejes el blog! Ansío otro post tuyo para empaparme de sabiduría!!! Mil gracias!!!!
ResponderEliminarPedazo de post makina. Un saludo
ResponderEliminar