BBTok apunta a Brasil: Desofuscación Del Cargador .NET con dnlib y PowerShell

octubre 21, 2024
G DATA Blog

 

BBTok apunta a Brasil: Desofuscación Del Cargador .NET con dnlib y PowerShell

Desglosamos la cadena de infección completa de la amenaza BBTok dirigida a Brasil y demostramos cómo desofuscar la DLL del cargador usando PowerShell, Python y dnlib.

En una compleja cadena de infección que comienza con un correo electrónico que contiene una imagen ISO, este malware destaca por su forma de compilar código C# directamente en la máquina infectada. También utiliza una técnica conocida como AppDomain Manager Injection para avanzar en la ejecución. Los artículos de Checkpoint y TrendMicro describen una cadena de infección similar y la atribuyen al banquero BBTok, pero hasta donde sabemos, nadie ha publicado aún un análisis sobre el cargador ofuscado basado en .NET llamado Trammy.dll.

El cargador escribe un archivo de registro con palabras desconocidas en las máquinas infectadas, para lo cual proporcionamos una tabla de traducción para que los encargados de responder a incidentes puedan decodificar los registros.

La ofuscación de Trammy.dll, que utiliza una variante de ConfuserEx, impide que las herramientas automáticas actuales recuperen las cadenas. Proporcionamos los scripts y comandos necesarios para desofuscarlas.

Intrusión que utiliza el motor de compilación de Microsoft

Recientemente, descubrimos varias imágenes ISO maliciosas [F1-4] en nuestra telemetría, aparentemente dirigidas a entidades brasileñas. Un comentario en Virustotal menciona que se envían por correo electrónico. Todas estas ISO [F1-4] contienen un archivo de acceso directo de Windows (LNK) [F5] y una carpeta (ver figura 1). Dentro de la carpeta encontramos un ejecutable [F6] , un archivo XML [F7] , un PDF [F8] y un archivo ZIP [F9] .  

El archivo LNK [F5] , DANFE10103128566164.pdf.lnk , se vincula al ejecutable [F6] en la carpeta y pasa el archivo XML [F7] como entrada junto con la opción –nologo. Todos los archivos dentro de la ISO [F1] se denominan «DANFE10103128566164» , que incluye el acrónimo en portugués «DANFE». El acrónimo significa » Documento Auxiliar de la Nota Fiscal Electrónica » y se refiere a una factura digital que generalmente se distribuye en formato PDF entre empresas brasileñas.  

Los atacantes aprovechan esto disfrazando el archivo LNK [F5] con el ícono PDF que está incrustado dentro del ejecutable estándar de Microsoft Edge (msedge.exe) del sistema para atraer a los objetivos a que lo ejecuten. 

Figura 1: Contenido de la imagen ISO

El ejecutable, DANFE10103128566164.exe [F6] , es una versión 4.7.3190.0 (MSBuild.exe) de Microsoft Build Engine firmada de forma válida. El malware lo utiliza para compilar código C# malicioso incrustado en el archivo XML [F7] de la máquina infectada (consulte la figura 2). El resultado del proceso de compilación es una DLL .NET [F13] que se coloca y se ejecuta en la carpeta TEMP local con un nombre aleatorio. Dado que el código C# simple está incluido en el archivo XML [F7] , el análisis es sencillo. 

Figura 2: Archivo de proyecto XML [F7] para Microsoft Build Engine que contiene el código C# malicioso

En primer lugar, la DLL .NET recién compilada [F13] abre el PDF señuelo [F8] que muestra una factura DANFE al usuario de destino. Después, extrae el archivo ZIP [F9] y copia Microsoft Build Engine [F6] a C:\ProgramData\regid.5498-06.com.microsoft [P1] a través de PowerShell. Por último, aprovecha una omisión de UAC utilizando ProgID junto con el binario de sistema elevado automáticamente computerdefaults.exe para ejecutar Microsoft Build Engine [F6] una vez más.  

Esta vez, sin embargo, MSBuild.exe [F6] no compila nuevamente el código C#, sino que ejecuta otra DLL, Trammy.dll [F10] , basada en el archivo de configuración del proyecto [F11] . Ambos se extraen del archivo ZIP mencionado anteriormente [F9] . Para evitar la ejecución consecutiva de la omisión de UAC, crea un mutex local llamado TiiSbtvhvbCMW .  

La figura 3 muestra una descripción general completa de esta parte de la cadena de infección.

Figura 3: Etapa 1: Utilización de Microsoft Build Engine para ejecutar archivos DLL .NET; las letras y números entre corchetes son referencias a la tabla IoC

Inyección de AppDomain Manager

El archivo de configuración [F11] declara la clase SacApp.SacAppde Trammy.dll [F10] como AppDomainManager (ver figura 4). Un AppDomainManager es responsable de personalizar el AppDomain de una aplicación, que es un entorno aislado para el código administrado. 

Esto significa que la declaración SacApp.SacAppcomo AppDomainManager lleva a la ejecución de código malicioso en InitializeNewDomain()un método estándar que ha sido anulado por SacApp.SacApp [F10] . Esta técnica se conoce como AppDomain Manager Injection . 

Figura 4: La clase SacApp.SacApp está registrada como AppDomainManagerType en el archivo .config [F11]

Desofuscación de Trammy.dll

DANFE10103128566164.dll [F10] no está empaquetado, sino ofuscado con ConfuserEx . Tiene el nombre de módulo Trammy.dll. Las herramientas de desofuscación específicas como NoFuserEx y de4dot-cex eliminan el aplanamiento del flujo de control, pero no recuperan automáticamente las cadenas.

Hay cinco métodos de decodificación de cadenas y cada uno toma un entero como clave que utiliza para calcular la cadena desofuscada. Después de aplicar de4dot-cex a la DLL, recuperamos todas estas claves utilizando dnlib y Python. Este código busca pares de ldc_i4instrucciones cally y devuelve los ldc_i4operandos. Esto puede devolver más que las claves de decodificación de cadenas, pero no importa para los pasos que siguen.

Utilizamos la función de edición IL de DnSpy para eliminar las comprobaciones antirreversión de los cinco métodos de decodificación de cadenas. Cada método comienza con una declaración if que comprueba si el llamador es el ensamblado actual. Si no es el ensamblado actual, se devolverá una cadena vacía. Reemplazar la declaración if con instrucciones NOP nos permite ejecutar el código desde PowerShell.

Recuperamos las cadenas de forma dinámica para cada método utilizando los siguientes comandos de PowerShell. La variable $numses un array de todas las claves que extrajimos con el script anterior. Los métodos de decodificación de cadenas tienen dos características que se deben tener en cuenta.

  1. Se encuentran en el tipo global <Module>y no se puede acceder a ellos a través de [namespace.ClassName]::methodname(). Por lo tanto, resolvemos los métodos de decodificación de cadenas a través de su token (aquí 0x6000005).
  2. Los métodos de decodificación de cadenas tienen un tipo de retorno genérico, por lo que debemos proporcionar el tipo de retorno a través de MakeGenericMethod([string]).

El último comando crea una asignación de las claves para los métodos de decodificación de cadenas a las cadenas desofuscadas. El try-catch se traga cualquier mensaje de error que se imprima debido a claves incorrectas.

Repetimos estos comandos para todos los métodos de decodificación de cadenas hasta que tengamos un result.txt fusionado que contenga todas las claves y cadenas decodificadas. Este archivo también tendrá asignaciones vacías que eliminamos reemplazando la expresión regular ^.*:\r\n$por nada. Transformamos el resultado en un diccionario de Python reemplazando ^(-?\d+):(.*)$por \1:r’\2′,(sintaxis de Notepad++). Luego modificamos ligeramente el script de Python anterior para que reemplace calllas instrucciones para las funciones de decodificación de cadenas con ldstrinstrucciones y la cadena desofuscada adecuada como operando.

Ejecutamos el script en Trammy.dll y desofuscamos las cadenas con éxito. Como paso final, utilizamos Simple Assembly Explorer para eliminar las llamadas indirectas seleccionando el perfil «Nada» en el desofuscador y habilitando la opción «Llamada directa».

Las figuras 5 y 6 muestran el SacApp.SacApp.InitializeNewDomainmétodo antes y después de aplicar la desofuscación de cadenas y la eliminación de llamadas indirectas.

Figura 5: Clase AppDomainManager personalizada después de eliminar la ofuscación del flujo de control con de4dot-cex

Figura 6: Clase AppDomainManager personalizada después de de4dot-cex, desofuscación de cadenas y eliminación de llamadas indirectas, los métodos isAdmin y MainMalcode se renombraron manualmente

Análisis de Trammy.dll

Trammy.dll [F10] inicia la ejecución en el método InitializeNewDomain()de SacApp.SacAppporque ha sido declarado como AppDomainManager por la configuración [F11] . 

Primero, abre el PDF señuelo [F8] . Luego, verifica si se debe ejecutar el código malicioso. Se deben cumplir dos condiciones

  1. No debe existir un archivo llamado C:\ProgramData\internal_drive_version2.3.4.txt  : es un archivo vacío que se creará más adelante. 
  2. hxxp://ipwho(dot)is/ debe informar que la IP es brasileña

Mientras que la primera condición garantiza que el código se ejecute solo una vez, la segunda verificación confirma que el malware se ejecuta en el área objetivo, Brasil. De esa manera, los sistemas sandbox automáticos no pueden determinar la malicia a menos que utilicen direcciones IP o servidores proxy brasileños. 

Traducción de archivos de registro

El malware crea un archivo de registro en C:\ProgramData\log.txt [P3] que codifica las etapas de ejecución con claves específicas .palabras.

Entrada de registroSignificado
COMENZARLas comprobaciones 1. y 2. tuvieron éxito y se ejecutó la rutina maliciosa principal.
ADMINISTRACIÓNEl malware tenía derechos de administrador
RIntentó crear un mutex ‘KOKKIIKKKOOOO’ 
MTX_FEl mutex ‘KOKKIIKKKOOOO’ se creó correctamente
CPCCProxy se descargó e instaló como servicio
yoSe extrajo la información del sistema operativo
ESSe creó el servicio que ejecuta automáticamente la carga útil de Delphi como un explorador falso [F14]

Además, los posibles mensajes de excepción y sus seguimientos de pila se escriben en el registro.

Esto significa que quienes responden a incidentes pueden localizar este archivo de registro para descubrir qué le hizo el malware al sistema infectado.

Información exfiltrada del sistema operativo

Trammy.dll [F10] obtiene la siguiente información a través de Windows Management Instrumentation (WMI) del ManagementObject Win32_OperatingSystem : 

  • Versión del sistema operativo
  • Nombre CS
  • Subtítulo
  • Versión
  • Número de serie
  • Número de compilación
  • Arquitectura Os

Además, obtiene el número de serie de todos los objetos Win32_PhysicalMedia y añade la cadena ‘VM’ siempre que el número de serie sea nulo, probablemente utilizado como indicador de que el malware se está ejecutando en una máquina virtual. El malware también obtiene una lista de todos los programas antivirus. La información resultante se envía a la siguiente URL [U1] 

hxxps://contador(punto)danfajuda(punto)com/contador/save.php

Descarga, descifrado y persistencia

A continuación, Trammy.dll [F10] programa una tarea que agrega la carpeta C:\ProgramData a las exclusiones de Windows Defender. 

La DLL contacta al directorio abierto hxxps://fileondemandd(dot)site/ [U2] (ver figura 8) y descarga el archivo ZIP filea.tat [F12] .

Figura 8: índice del almacenamiento de archivos que contiene el archivo ZIP filea.tat

El archivo está protegido con contraseña. La contraseña es vsfdefender y no se ha cambiado en mucho tiempo, por ejemplo, los archivos del artículo de Checkpoint de hace un año también usan esta contraseña (Checkpoint llama a los ejemplos BBTok con los nombres de archivo fe, fe2 y fe235). Sin embargo, esta contraseña solo funciona con los archivos que utiliza el malware. Si se intenta descomprimir todo el archivo con esta contraseña, aparecen mensajes de error de «contraseña incorrecta». Esto podría ser intencional para evitar la fuerza bruta de la contraseña del archivo.

Obtuvimos siete archivos del archivo ZIP [F12] . Seis de ellos (CCProxy.exe [F15] , wke.dll [F16] , Web.exe [F17] , CCProxy.ini, AccInfo.ini y LeftTime.ini) pertenecen a la aplicación CCProxy desarrollada por Youngzsoft Co., Ltd que se puede utilizar, por ejemplo, para filtrar y monitorear el tráfico de red. Trammy.dll [F10] los extrae todos a C:\Program Files\SearchIndexer [P4] excepto Web.exe [F17] que permanece sin usar. CCProxy.exe [F15] , enmascarado como Searchlndexer.exe (con una «L» minúscula en lugar de una «i» mayúscula), es la aplicación principal y está registrada como un servicio local que se inicia automáticamente al iniciar Windows. CCProxy.ini y AccInfo.ini configuran CCProxy para aceptar conexiones HTTP desde localhost en el puerto 8118, que se utiliza para disfrazar la comunicación con el servidor CnC [U3] . 

El archivo wke.dll [F16] es superfluo porque solo lo requiere el archivo Web.exe [F17] que no se extrae . El séptimo archivo se llama explorer.exe [F14] y se compiló con Embarcadero Delphi 11.0 Alexandria. Trammy.dll [F10] lo extrae a la carpeta de datos del programa y lo registra también como un servicio local. En artículos anteriores ( enlace 1 , enlace 2 ), la carga útil de Delphi era BBTok.

Después de establecer la persistencia, Trammy.dll [F10] crea el archivo vacío internal_drive_version2.3.4.txt [P2] , que se utiliza para determinar si el código ya se ha ejecutado. A continuación, Trammy.dll [F10] muestra la advertencia de caducidad de la licencia de Windows predeterminada y reinicia el sistema. Al reiniciar, el servicio CCProxy se inicia con su configuración personalizada y se llama al falso explorer.exe [F14] con un filea.tat [F12] renombrado como argumento. La Figura 9 muestra la descripción general de esta parte de la cadena de infección.

En nuestro próximo artículo, describiremos cómo la carga útil de Delphi [F14] se comunica con el servidor CNC [U3] a través de CCProxy utilizando el SDK Realthinclient . 

Figura 9: Etapa 2: Descarga y persistencia

Hashes

[F1] DANFE10103128566164.iso
09027fa9653bdf2b4a291071f7e8a72f14d1ba5d0912ed188708f9edd6a084fe

[F2] DANFE10103124952781.iso
2ff420e3d01893868a50162df57e8463d1746d3965b76025ed88db9bb13388af

[F3] DANFE10103122718132.iso
5e5a58bfabd96f0c78c1e12fa2625aba9c84aa3bd4c9bb99d079d6ccb6e46650

[F4] DANFE10103121443891.iso
dc03070d50fdd31c89491d139adfb211daf171d03e9e6d88aac43e7ff44e4fef

[F5] DANFE10103128566164.pdf.lnk
ddf84fdc080bd55f6f2b409e596b6f7a040c4ab1eb4b965b3f709a0f7faa4e02

[F6] DANFE10103128566164.exe – MSBuild legítimo
b60eb62f6c24d4a495a0dab95cc49624ac5099a2cc21f8bd010a410401ab8cc3

[F7] DANFE10103128566164.xml
7566131ce0ecba1710c1a7552491120751b58d6d55f867e61a886b8e5606afc3

[F8] DANFE10103128566164.pdf – documento señuelo
ac044dd9ae8f18d928cf39d24525e2474930faf8e83c6e3ad52496ecab11f510

[F9] DANFE10103128566164.zip
276a1e9f62e21c675fdad9c7bf0a489560cbd959ac617839aeb9a0bc3cd41366

[F10] DANFE10103128566164.dll – Trammy.dll
24fac4ef193014e34fc30f7a4b7ccc0b1232ab02f164f105888aabe06efbacc3

[F11] DANFE10103128566164.exe.config: registra AppDomainManager
8e7f0a51d7593cf76576b767ab03ed331d822c09f6812015550dbd6843853ce7

[F12] filea.tat – archivo ZIP
7559c440245aeeca28e67b7f13d198ba8add343e8d48df92b7116a337c98b763

[F13] DLL .NET después de la compilación de [F7]
a3afed0dabefde9bb8f8f905ab24fc2f554aa77e3a94b05ed35cffc20c201e15

[F14] explorer.exe falso: carga útil de Delphi
35db2b34412ad7a1644a8ee82925a88369bc58f6effc11d8ec6d5f81650d897e

[F15] Searchlndexer.exe – CCProxy
27914c36fd422528d8370cbbc0e45af1ba2c3aeedca1579d92968649b3f562f7

[F16] wke.dll
2d2c2ba0f0d155233cdcbf41a9cf166a6ce9b80a6ab4395821ce658afe04aaba

[F17] Web.exe
cb1d2659508a4f50060997ee0e60604598cb38bd2bb90962c6a51d8b798a03b6 

URL

[U1] Panel de malware
hxxps://contador.danfajuda(punto)com/contador/save.php?

[U2] Almacenamiento de archivos
hxxps://fileondemandd(punto)site/

[U3] Puerta de enlace del portal RTC
hxxp://pingservice(punto)blogdns(punto)com/myPath 

Caminos

[P1] C:\ProgramData\regid.5498-06.com.microsoft\

[P2] C:\ProgramData\unidad_interna_versión2.3.4.txt

[P3] C:\ProgramData\log.txt

[P4] C:\Archivos de programa\SearchIndexer\ 

Enlace https://www.gdatasoftware.com/blog/2024/09/38039-bbtok-deobfuscating-net-loader  Blog de G DATA De Marius Benthin, Karsten Hahn