Análisis del powershell usado por FIN7

El día 24 de Abril de 2017, Fireeye publicó una entrada en su blog con el título “FIN7 Evolution and the Phishing LNK”. En esta entrada detallan toda la cadena de infección seguida, que se podría resumir en:

  1. El usuario recibe un fichero docx o rtf
  2. Dentro se encuentra una imagen que te invita a hacer click en ella
  3. Al hacer click se abre un fichero de tipo LNK
  4. Este LNK ejecuta mshta.exe con argumentos.
  5. Tras la ejecución se “droppean” dos ficheros vbs y uno ps1.
  6. Uno de los vbs ejecuta el FIN7’s HALFBAKED backdoor y el otro comprueba que está powershell arrancado.
  7. El ps1 según Fireeye es un script con múltiples capas y que lanza un shellcode para un Cobalt Strike stager.

A partir de esta información vamos a analizar en detalle el fichero powershell que se droppea y vamos a intentar entender cómo funciona. El documento del que vamos a partir será (podéis descargarlo desde hybridAnalysis):

 $ sha256sum malware_fin7_hybridAnalysis.rtf
39ab32a4cafb41c05ccecda59ebb0b1fcc6e08fd94ecad0ac80914fb2ad67588  malware_fin7_hybridAnalysis.rtf

Una vez ejecutado, vemos en la máquina del laboratorio lo siguiente (pinchar en las imágenes de la entrada para ver una versión ampliada):

Los ficheros los ha droppeado en la ruta C:\Usuarios\john\Intel:

En el fichero ps1 (powershell) nos encontramos con (parte del código base64 se ha quitado para que sea legible):

Al decodificar el base64 nos encontramos con la ejecución de powershell.exe y como argumento otro código base64:

Si repetimos el proceso y volvemos a decodificar el base64 nos encontramos con el siguiente código:

Y ya por último tras decodificar el código anterior nos encontramos con el siguiente código powershell (como vemos hemos tenido que hacer varias iteraciones hasta llegar a él):

Si analizamos el código anterior vemos:

  1. Primero el script llama a la función VirtualAlloc para reservar espacio en memoria.
  2. Después vemos la función Copy para copiar información a la nueva zona de memoria. Lo que copia es un shellcode.
  3. Después lanza un hilo mediante la función CreateThread apuntando a la dirección de memoria devuelta por el VirtualAlloc:

Después de que se haya ejecutado el código powershell si examinamos la memoria del proceso powershell.exe, veremos que el shellcode estará inyectado del siguiente modo (se puede ver ya en el shellcode el dominio donde intentará contactar):

Ahora vamos a ver qué hace el shellcode que inyecta en el propio proceso powershell y ejecuta como un hilo. Para ello lo que hacemos es modificar la llamada a CreateThread y le indicamos que arranque el hilo en estado suspendido. Una vez esté suspendido nos “vinculamos” con x64dbg y nos vamos al “Entry Point” del hilo que va a ejecutar el shellcode. Cuando lo hagamos veremos lo siguiente:

Lo primero que hace el shellcode es recoger de Win32_Thread_Information_Block en la dirección FS:[0x30] la posición del Process Environment Block (PEB). A partir de esa dirección se desplaza 0x00c para obtener el puntero a la estructura _PEB_LDR_DATA.

Después dentro de esta estructura se desplaza 0x14 para obtener el puntero a LIST_ENTRY InmemoryOrderModuleList. Esto proceso lo que permite al shellcode es recorrer los módulos del binario powershell.exe donde esta inyectado y buscar los que le interesan. Después una vez encuentra el módulo busca la función que quiere ejecutar.

El nombre de la función que va a llamar el shellcode está codificado y lo que hace el shellcode es recorrer las funciones de los módulos cargados, codificar el nombre de la función y compararlo con el valor codificado del nombre de función que está buscando, si coincide pasa a ejecutarla, sino continúa recorriendo.

El código encargado de la codificación de los nombres de las funciones es:

Como vemos realiza un desplazamiento de bits (ror edi,D) de los caracteres (en mayúsculas, para pasar a mayúsculas usa las instrucción sub al,20) de la cadena con el nombre de la función. Después va sumando el valor del carácter con el acumulado de lo desplazado y este proceso va carácter a carácter.

Veamos uno a uno los trozos de código que se corresponden a la llamada a las diferentes funciones. El primero que nos encontramos es el trozo de código donde se realiza un push de E553A458 que es el valor del string VirtualAllocEx codificado.

Con esto reserva la memoria en el proceso de powershell:

Después existe otro trozo de código donde la función que se llama es LoadLibraryEx (valor 726774C). Se utiliza para cargar la librería dnsapi para poder realizar la petición DNS:

Otra de las funciones que se decodifica es DNSQuery_UTF8 (valor C99CC96A):

En el caso de que no reciba respuesta del DnsQuery_UTF8() realizará un Sleep (valor E035F044):

Después de realizar la petición DNS solicitando un registro TXT, lo que devuelve el servidor el shellcode comprueba que tenga un tamaño menor de FF y para ello llama a la función lstrlen (valor CC8E00F4).

Si el tamaño es menor de FF pasa a la zona de código:

Hemos visto en esta entrada el paso a paso desde que se ejecuta el powershell, se decodifica varias veces, se inyecta un shellcode en el propio proceso de powershell, como el shellcode busca los módulos y funciones, como están codificados los nombres de las funciones y como realiza peticiones DNS TXT y recoge la respuesta.

Queda pendiente analizar el código que interpreta la respuesta del servidor, y que veremos en una siguiente entrada si el tiempo lo permite. Como siempre esperamos que os sea de utilidad este tipo de información.

Comments

  1. Buenas, al pinchar en el botón de publicar en twitter me salía una cuenta diferente de la vuestra, ponía “vía @secatwork”.

    Saludos.

  2. De dónde conoce el mapping entre LoadLibraryEx y su valor 726774C?

  3. Está puesto como comentario por mi el valor en el debugger. El mapping lo saca en el trozo de código donde hace el ROR edi,D que está en la propia entrada.

  4. Culpa mía, que soy un manazas. Arreglado. ¡Gracias!