Una historia de autopsia: cómo revirtimos a Hancitor



Para aquellos que ya han jugado lo suficiente con los rompecabezas de crackme , trajimos un troyano nuevo. En la naturaleza, el descargador Hancitor todavía se encuentra en su hábitat natural: los correos no deseados. Actualmente, se usa activamente para descargar el troyano bancario Panda, que es una modificación del famoso Zeus.

Una fría tarde de verano, nos encontramos con él cara a cara, mirando correos no deseados. Si desea ver qué tiene el malware debajo del capó, lea nuestro nuevo análisis inverso.

Nuestro documento malicioso se ve así:



De manera predeterminada, las macros están bloqueadas, por lo que el sistema advierte: "Las macros se han deshabilitado". Sin embargo, el contenido del mensaje dice que se deben incluir macros. Bueno, hagámoslo. Después de hacer clic en el botón Habilitar contenido, la computadora está infectada. Ahora veamos qué tipo de macro se ejecuta y cómo ocurre exactamente la infección. Esto se puede hacer inmediatamente en Word yendo a la pestaña Ver-> Vacros \ Ver Macros.



Puede hacerlo de manera más profesional: use olevba del paquete de oletools. Puede instalar el paquete allí en el enlace. A continuación, escriba olevba doc_file –c –decode> source.txt y obtenga la fuente macro.



Por el código, quiero decir inmediatamente que el troyano pertenece a la clase de descargadores. El guión simplemente se desinfla desde algún lugar hasta el Malwara. Para probar esto, decodifiquemos las cadenas base64. Es más conveniente para nosotros hacer esto inmediatamente a través de Hiew, para no copiar y pegar cien veces. Para hacer esto, utilizamos un complemento especial, que se describe aquí . Esto es lo que sucedió:



Este es un script malicioso, dividido en dos partes y guardado como 1.hta. En principio, no estamos particularmente interesados ​​en cómo funciona. Todo es bastante común. El único punto importante es determinar la URL en la que se descarga el archivo malicioso. Intentemos encontrarlo, ya que esta información puede ser útil para la seguridad . Pueden agregar reglas de red para bloquear solicitudes en tales URL, lo que puede salvar a la empresa de la infección.

Ja! No hay enlaces Pero, ¿de dónde viene el archivo 6.exe, que comienza 1.hta? Es hora de echar otro vistazo a nuestro archivo de acoplamiento en la vista, pero con más cuidado:



Sí, un exe-shnik está integrado en el documento del muelle. Sí, y muy empaquetado. Vamos a explicar lo que está pasando. La macro suelta el script malicioso 1.hta en la carpeta Temp y lo inicia, y 1.hta, a su vez, inicia 6.exe desde su directorio. Está claro que 6.exe es el mismo PE-shnik empaquetado que vemos en la pantalla. Pero ahora nos preguntamos cómo cae 6.exe en% temp%. Y esto sucede debido a una característica interesante en la suite de Microsoft Office. El hecho es que en cualquier documento OLE, se puede incrustar cualquier otro archivo en el formato Ole10Native.

Si este es el caso, al inicio, MS-Office coloca el archivo creado de esta manera en la carpeta% temp% bajo el nombre especificado en el encabezado de la estructura Ole10Native. Echemos un vistazo a este objeto. El complemento nos ayudó al FAR-manager: OLE2Viewer . Abrimos nuestro documento malicioso en el complemento, vaya al directorio ObjectPool \ _1593522492 y vea esto:



Copie este archivo (Ole10Native) y ábralo en hiew.



Aquí vemos con qué nombre nuestro objeto OLE: 5c.pif se colocará en la carpeta% temp%. Ahora volvamos a nuestra macro. Su tarea es lanzar un exe-shnik borracho.



De hecho, para ser precisos, la macro no siempre inicia el archivo descartado a través de 1.hta, pero también de esta manera: Shell "cmd.exe / c ping localhost -n 100 &&" y Environ ("Temp") & "\ 6 .pif ", vbOcultar



El método de lanzamiento, como vemos, depende de la presencia de los siguientes procesos en el sistema: bdagent.exe y PSUAMain.exe. ¿Por qué entonces necesitas ping localhost -n 100? Y este es un antiguo truco griego para crear un retraso artificial, por si acaso. Por lo general, sus variaciones se utilizan para la autoextracción.

En esta etapa, examinamos el funcionamiento de un documento malicioso. Nos quedó claro que el documento en sí no pertenece al malware del tipo Trojan-Downloader, como parecía a primera vista, pero es adecuado para el tipo Trojan-Dropper. Esto es lo que sucedió en el inicio:



Ahora queda por desmontar la carga útil. Ya nos dimos cuenta de que nuestro troyano está empaquetado, por lo que debemos descomprimirlo primero. Por lo general, este proceso se divide en dos etapas:
1. Eliminar el volcado desempaquetado + restaurar la tabla de importación.
2. Análisis y purificación de variables globales.

Necesitamos la segunda etapa porque hay muchas funciones API que, como resultado de su trabajo, nos devuelven valores que no se repiten. Por ejemplo, CreatHeap nos devolverá un descriptor de montón, que luego se utilizará para el trabajo. Muy a menudo hay verificaciones de tipo en el código: si el descriptor del montón == 0, obtenga el descriptor del montón, de lo contrario use uno ya inicializado . Pero en el momento del volcado, la variable que contiene el descriptor dado ya fue inicializada por él y en ese momento el descriptor era válido. Cuando intentamos iniciar el volcado, la variable con nuestro descriptor contendrá el valor anterior, es decir, no será igual a 0, lo que significa que la prueba pasará.

Después de eso, tan pronto como el programa intente usar este descriptor, el sistema operativo lanzará una excepción y el programa se bloqueará con un error. Por lo tanto, para evitar esto, debe poner a cero estas variables. Por lo general, se encuentran en una sección de datos que se puede escribir. ¿Probablemente sugiera abrir esta sección en el editor hexadecimal y sobrescribir todo con ceros? Tiene razón en parte, pero no debe realizar acciones precipitadas. Hay troyanos que verifican las variables no en 0, sino en un DWORD aleatorio. Y dependiendo de si la prueba se está probando o no, se toman varias medidas. No tienes que ir muy lejos por ejemplos. Solo mire el Cridex (recientemente ha desaparecido en algún lugar de los radares, aparentemente ha sido completamente actualizado a EMOTETA).

Entonces, ejecutemos nuestra muestra (en una máquina virtual, por supuesto). También es deseable que el tráfico que salga de la máquina virtual pase por una VPN.

Lanzamos nuestro troyano, y simplemente se cuelga en el proceso. Genial Por lo general, los troyanos hacen las cosas rápidamente, y luego terminan inmediatamente y se autodestruyen. Por lo tanto, debe buscar lugares en el código responsables de estas acciones, detenerlos y luego volcarlos. En nuestro caso, podemos hacerlo así como así.

Para el volcado, utilizamos la maravillosa utilidad: Process Dump, que se puede encontrar aquí . Esta utilidad no solo encuentra todos los módulos ejecutables ocultos y los vuelca, sino que también restaura la tabla de importación. La utilidad debe ejecutarse como administrador de la siguiente manera: pd / pid xxxx, donde xxxx es la identificación del proceso troyano. Después de eso, la utilidad volcará todos los módulos de proceso. Eliminamos los adicionales y esto es lo que queda:



El nombre del archivo ejecutable del proceso troyano es 1.exe. Resulta que el troyano desempaquetado se encuentra en 0x2C0000. Ábrelo en hiew:



¡Solo un ojo feliz! Ahora el archivo está desempaquetado, es claramente visible. La tabla de importación también fue reconocida. Vamos a abrirlo en IDA-PRO.



Ya cambiamos el nombre de algunas funciones mientras ordenamos la muestra. Lo primero con lo que comienza el troyano es determinar la dirección de carga de su módulo. Y realmente: ¿cómo sabía en qué dirección desempacó su trozo? Esto se hace con una vieja técnica probada: voltear una página de memoria a 0x1000 en relación con la dirección actual hasta que encontremos los bytes "MZ". Esto funciona porque los módulos ejecutables siempre cargan el sistema operativo en una dirección que es un múltiplo de 0x1000. Compruébalo por ti mismo. En nuestro caso, se establece un límite de 100 stripping.



Si alguien no entiende dónde hay un retroceso, entonces aquí es donde:
resultado + = 0xFFFFF000 es equivalente a resultado - = 0x1000.

Después de recibir la dirección de descarga de su módulo, el troyano desempaquetado recibe las direcciones de las funciones necesarias para su funcionamiento. Para empezar, se buscan las direcciones de dos funciones: LoadLibraryA y GetProcAddress. Conociendo las direcciones de estas funciones, puede usarlas para obtener el resto. Estas funciones están en la biblioteca kernel32. Su dirección se obtiene leyendo el primer elemento (zero - ntdll, primer kernelbase, etc.) de la lista de anillos que describe todos los módulos cargados en el orden de inicialización con la estructura _LDR_DATA_TABLE_ENTRY. El puntero a la lista se extrae del PEB.



Habiendo recibido la dirección kernel32.dll (comenzando con Windows 7 - kernelBase.dll), el troyano puede analizar manualmente su tabla de exportación y encontrar las dos funciones necesarias, que se realiza de manera predecible en la subrutina sub_EF1E60.



Ahora eche un vistazo a la función que llamamos getHeap.



Aquí estamos observando solo la situación que se describió anteriormente. En el momento del volcado, la variable hHeap contenía un valor de 600000h. Por lo tanto, no se llamará a GetProcessHeap. En cambio, el programa irá a la etiqueta loc_EF11DD, donde se llama a HeapAlloc con un identificador no válido, lo que nos dará un error. Por lo tanto, tomamos el editor hexadecimal y ponemos a cero este número. Contamos seis lugares similares.

A continuación, comienza la diversión. El troyano genera una identificación única de "cliente" basada en el número de serie del disco duro y la dirección MAC. Información recibida aquí:



También obtenemos lo siguiente: dirección IP, versión del sistema operativo, nombre de red y nombre de usuario. En base a todo esto, se genera una solicitud HTTP para el panel de administración, cuya dirección aún no conocemos. No está en las líneas (incluso en la forma desempaquetada). Pero no está allí, porque está encriptado en la configuración. Su dirección se puede extraer del código:



La configuración pesa 0x2008 bytes y tiene el siguiente formato: los primeros 8 bytes son la clave RC4, 0x2000 bytes son los datos cifrados.



El hecho de que se utilice el algoritmo de cifrado RC4 queda claro en la siguiente lista:



Tenga en cuenta que los primeros 8 bytes por sí solos no son la clave para RC4. La clave es el hash SHA1 de estos bytes. También debe prestar atención al indicador 0x280011 de la función CryptDeriveKey. MSDN tiene un descargo de responsabilidad con respecto a este indicador:



De esto queda claro que los 16 bits altos de esta bandera establecen el tamaño de la clave en bits. Es decir, en bytes, el tamaño de la clave es: (0x280011 >> 16) / 8 = 5. Por lo tanto, la clave serán los primeros cinco bytes del hash de los primeros ocho bytes de la configuración. Volquemos la configuración y escribamos un script de Python que lo descifre por nosotros. El guión se ve así:



El resultado de su trabajo fue el archivo config.rc4. Ábrelo en hiew:



Vemos una lista descifrada de áreas administrativas. La primera palabra es "19nep07" - número de compilación. Se le asignan 16 bytes. A continuación hay una lista de URL de administrador separadas por "|".

Entonces, la primera llamada al panel de administración tendrá este formato:
GUID = 3068075364164635648 & BUILD = 19nep07 & INFO = WIN-56G04BL06SL @ WIN -56G04BL06SL \ Reverse & IP = 35.0.127.52 & TYPE = 1 & WIN = 6.1 (x32



Luego, la solicitud generada se envía primero en la lista del panel de administración.



Luego, la respuesta del administrador se lee, por supuesto, si aún está viva. La respuesta debe estar codificada en base64. Si este no es el caso, se toma el siguiente administrador de la lista. A veces, los administradores en vivo devuelven una respuesta extraña:



Es familiar, ¿no es así? Sí, estos son los mismos números ! De hecho, un autor sabe por qué el administrador comienza a devolverlos. En forma normal, el comando regresa. Desafortunadamente, es imposible decir con total certeza cuál será el formato de respuesta, ya que no hay tráfico, todos los administradores están muertos. El archivo decodificado se decodifica adicionalmente a 0x7A:



La respuesta debe contener un comando. Si no es así, hay una apelación al siguiente panel de administración. El código del comando está codificado como "x:", donde x es la letra que codifica un comando específico. Hay 7 de ellos: 'r', 'l', 'e', ​​'b', 'd', 'c', 'n'. Considere los comandos "b" y "r".

Los manejadores de estos comandos tienen la misma función. Lo nombramos como GetExe. Así es como se ve:



Creo que todo está claro aquí. El troyano realiza una solicitud http y el archivo ejecutable se devuelve en respuesta en forma comprimida, que luego se descomprime. Entonces las variaciones son posibles. En el caso del comando "b", se producen las siguientes tres acciones:

1. Creación del proceso svchost en forma congelada



2. Inyección en el espacio de direcciones del proceso del módulo descargado



3. Transferencia de control al módulo inyectado



En el caso del comando r, se producen las siguientes tres acciones:
1. Descargando el archivo ejecutable llamando a la función GetExe.
2. Guardar el archivo descargado en una carpeta temporal con un nombre aleatorio.
3. Inicie un archivo descartado.



Hecho

PD La próxima vez podemos analizar el Panda o alguna criptor. Escriba en los comentarios en qué malware está más interesado (por supuesto, para fines de investigación).

Source: https://habr.com/ru/post/es418185/


All Articles