ESET participa en una operación mundial para desarticular el troyano bancario Grandoreiro

INFORME COMPLETO DE LA INVESTIGACIÓN

ESET España ha tenido una participación muy activa durante toda la investigación que ha durado 4 años y que ha finalizado con la detención de varios integrantes del grupo de ciberdelincuentes responsables del troyano bancario, Grandoreiro.  Josep Albors, director de Investigación y Concienciación de ESET España ha sido uno de los expertos de ESET, y de otras empresas y organismos oficiales, que ha colaborado proporcionando inteligencia acerca de estas amenazas, lo que ha permitido a la Policía Federal de Brasil, la desarticulación de la botnet Grandoreiro.

Entre la inteligencia proporcionada encontramos análisis técnicos, información estadística y nombres de dominio y direcciones IP de servidores de comando y control (C&C). Además, gracias a un fallo de diseño en el protocolo de red de Grandoreiro, los investigadores de ESET también pudieron observar su victimología.

Desde ESET España se ha estado informando de muchas de las campañas relacionadas con esta botnet desde el blog de Ontinet, así como en diversas ponencias de prestigiosos eventos sobre ciberseguridad a nivel nacional y webinars.  

Los sistemas automatizados de ESET procesaron decenas de miles de muestras de Grandoreiro. El algoritmo de generación de dominios (DGA) que el malware ha utilizado desde octubre de 2020 produce un dominio principal, y opcionalmente varios dominios a prueba de fallos, por día. El DGA es la única forma que conoce Grandoreiro de informar a un servidor de C&C. Además de la fecha actual, la DGA también acepta configuraciones estáticas – hemos observado 105 configuraciones de este tipo en el momento de escribir este artículo.

Los operadores de Grandoreiro han abusado de proveedores en la nube como Azure y AWS para alojar su infraestructura de red. Los investigadores de ESET proporcionaron datos cruciales para identificar las cuentas responsables de configurar estos servidores. La investigación adicional llevada a cabo por la Policía Federal de Brasil condujo a la identificación y detención de las personas que controlaban estos servidores.

En este blogpost, analizamos cómo obtuvimos los datos para ayudar a las fuerzas de seguridad a ejecutar esta operación de interrupción.

Antecedentes

Grandoreiro es uno de los muchos troyanos bancarios latinoamericanos. Ha estado activo desde al menos 2017 y los investigadores de ESET lo han seguido de cerca desde entonces. Grandoreiro apunta a Brasil y México, y desde 2019 también a España (ver Figura 1). Mientras que España fue el país más atacado entre 2020 y 2022, en 2023 hemos observado un claro cambio de enfoque hacia México y Argentina, siendo este último nuevo para Grandoreiro.

Figura 1. Tasa de detección de Grandoreiro (datos desde enero de 2020)

Desde el punto de vista funcional, Grandoreiro no ha cambiado mucho desde nuestro último blog en 2020. Ofrecemos un breve resumen del malware en esta sección y nos sumergimos en los pocos cambios, principalmente la nueva lógica DGA, más adelante.

Cuando un troyano bancario compromete con éxito una máquina, normalmente emite una petición HTTP GET a un servidor remoto, enviando alguna información básica sobre la máquina comprometida. Aunque las versiones anteriores de Grandoreiro incluían esta función, con el tiempo los desarrolladores decidieron eliminarla.

Grandoreiro monitoriza periódicamente la ventana en primer plano para encontrar una que pertenezca a un proceso del navegador web. Cuando se encuentra una ventana de este tipo y su nombre coincide con cualquier cadena de una lista codificada de cadenas relacionadas con bancos, entonces y sólo entonces el malware inicia la comunicación con su servidor de C&C, enviando peticiones al menos una vez por segundo.

El operador tiene que interactuar manualmente con la máquina comprometida para robar el dinero de la víctima. El malware permite:

  • bloquear la pantalla de la víctima
  • registrar las pulsaciones del teclado,
  • simular la actividad del ratón y el teclado,
  • compartir la pantalla de la víctima, y
  • mostrar ventanas emergentes falsas.

Grandoreiro experimenta un desarrollo rápido y constante. En ocasiones, llegamos a ver varias builds nuevas a la semana, lo que hace difícil seguir la pista. Para demostrarlo, en febrero de 2022, los operadores de Grandoreiro añadieron un identificador de versión a los binarios. En la Figura 2 mostramos la rapidez con la que cambiaba el identificador de versión. De media, hubo una nueva versión cada cuatro días entre febrero de 2022 y junio de 2022. En el intervalo de un mes entre el 24 de mayo de 2022 y el 22 de junio de 2022 seguimos viendo nuevas muestras con tiempos de compilación de PE progresivos, pero que carecían del identificador de versión. El 27 de junio de 2022, el identificador de versión pasó a ser V37 y no hemos vuelto a verlo cambiar desde entonces, lo que nos lleva a concluir que esta característica se eliminó.

Figura 2. Historial de versiones de Grandoreiro entre febrero y junio de 2022

Los troyanos bancarios latinoamericanos tienen muchos puntos en común. Grandoreiro es similar a otros troyanos bancarios latinoamericanos principalmente por la funcionalidad central obvia y en la agrupación de sus descargadores dentro de instaladores MSI. En el pasado, hemos observado algunos casos en los que sus descargadores se compartían con Mekotio y Vadokrist, aunque no en los últimos dos años. El troyano bancario Grandoreiro se distinguía principalmente de las otras familias por su mecanismo único de relleno binario, que engrosa masivamente el ejecutable final (descrito en nuestro blog en 2020). Con el tiempo, los operadores de Grandoreiro añadieron esta técnica antianálisis también a sus descargadores. Para nuestra sorpresa, en el tercer trimestre de 2023, esta característica desapareció por completo de los binarios del troyano bancario y del descargador, y no la hemos vuelto a observar desde entonces.

Desde febrero de 2022, hemos estado rastreando una segunda variante de Grandoreiro que difiere significativamente de la principal. La vimos, en pequeñas campañas, en marzo, mayo y junio de 2022. Basándonos en que la gran mayoría de los dominios de sus servidores de C&C no se resuelven, en que sus características principales cambian con bastante frecuencia y en que su protocolo de red no funciona correctamente, creemos firmemente que se trata de un trabajo en curso, por lo que nos centraremos en la variante principal en esta entrada del blog.

Seguimiento a largo plazo de Grandoreiro

Los sistemas de ESET, diseñados para el rastreo automatizado a largo plazo de familias de malware seleccionadas, han estado monitoreando Grandoreiro desde finales de 2017, extrayendo información de la versión, servidores de C&C, objetivos y, desde finales de 2020, configuraciones de DGA.

Seguimiento de la DGA

La configuración DGA está hardcodeada en el binario de Grandoreiro. Se puede hacer referencia a cada configuración mediante una cadena que denominamos dga_id. Utilizando diferentes configuraciones para la DGA se obtienen diferentes dominios. Más adelante profundizaremos en el mecanismo de la DGA.

ESET ha extraído un total de 105 dga_ids diferentes de las muestras de Grandoreiro que conocemos. 79 de estas configuraciones generaron al menos una vez un dominio que se resolvió en una dirección IP de un servidor de C&C activo durante el curso de nuestro rastreo.

Los dominios generados se registran a través del servicio de DNS dinámico (DDNS) de No-IP. Los operadores de Grandoreiro abusan del servicio para cambiar con frecuencia sus dominios para que se correspondan con la DGA y para cambiar las direcciones IP a voluntad. La gran mayoría de las direcciones IP a las que resuelven estos dominios son proporcionadas por proveedores de la nube, principalmente AWS y Azure. La Tabla 1 ilustra algunas estadísticas sobre las direcciones IP utilizadas para los servidores C&C de Grandoreiro.

Tabla 1. Información estadística sobre las direcciones IP de Grandoreiro C&C desde que iniciamos nuestro rastreo

InformaciónPromedioMínimoMáximo
Número de direcciones C&C IP por día3134
Número de direcciones activas C&C IP por día13127
Tiempo de vida de direcciones C&C IP (en días)51425

Muy poco después de empezar a rastrear los dominios generados y sus direcciones IP asociadas, empezamos a notar que muchos dominios generados por DGAs con diferentes configuraciones se resuelven a la misma dirección IP (como se ilustra en la Figura 3). Esto significa que, en un día determinado, las víctimas comprometidas por las muestras de Grandoreiro con diferentes dga_id se conectaban todas al mismo servidor de C&C. Este fenómeno no fue una coincidencia: lo observamos casi a diario durante nuestro rastreo.

Figura 3. Esquema de una IP solapada en dos configuraciones diferentes de Grandoreiro DGA

En ocasiones mucho más raras, también hemos observado que una dirección IP era reutilizada por un dga_id diferente unos días después. Sólo que esta vez, los parámetros que Grandoreiro utilizó para establecer una conexión (explicados más adelante en el texto) también cambiaron. Esto significa que, mientras tanto, el servidor de C&C debe haber sido reinstalado o reconfigurado.

Nuestra suposición inicial era que el dga_id es único para cada configuración de la DGA. Más tarde se demostró que era incorrecta: hemos observado dos conjuntos de configuraciones diferentes que comparten el mismo dga_id. La tabla 2 muestra ambos, «jjk» y «gh», donde «jjk» y «jjk(2)» corresponden a dos configuraciones DGA diferentes, al igual que «gh» y «gh(2)».

La tabla 2 muestra los grupos que hemos podido observar. Todas las configuraciones de DGA que compartían al menos una dirección IP están en el mismo clúster y se enumeran sus dga_ids asociados. Los clusters que representan menos del 1% de todas las víctimas no se tienen en cuenta.

Tabla 2. Agrupaciones de la DGA de Grandoreiro Grupos de DGA de Grandoreiro

Cluster IDdga_id listTamaño
Cluster
% de todos los servidores C&C % de todas las víctimas
1b, bbh, bbj, bbn, bhg, cfb, cm, cob, cwe, dee, dnv, dvg, dzr, E, eeo, eri, ess, fhg, fox, gh, gh(2), hjo, ika, jam, jjk, jjk(2), JKM, jpy, k, kcy, kWn, md7, md9, MRx, mtb, n, Nkk, nsw, nuu, occ, p, PCV, pif, rfg, rox3, s, sdd, sdg, sop, tkk, twr, tyj, u, ur4, vfg, vgy, vki, wtt, ykl, Z, zaf, zhf6293.6%94%
2jl2, jly22.4%2.5%
3ibr10.8%1.6%
4JYY11.6%1.1%

El cluster más grande contiene el 78% de todos los dga_ids activos. Es responsable del 93,6% de todas las direcciones IP de servidores de C&C y del 94% de todas las víctimas que hemos visto. El único otro cluster que consta de más de 1 dga_id es el cluster 2.

Algunas fuentes afirman que Grandoreiro opera como malware-as-a-service (MaaS). El backend del servidor de C&C de Grandoreiro no permite la actividad simultánea de más de un operador a la vez. Basándonos en la Tabla 2, la gran mayoría de las direcciones IP producidas por DGA pueden agruparse sin un patrón de distribución claro. Por último, teniendo en cuenta los elevados requisitos de ancho de banda del protocolo de red (que analizaremos al final del blogpost), creemos que los diferentes servidores de C&C se utilizan como un sistema primitivo de equilibrio de carga y que es más probable que Grandoreiro esté operado por un único grupo o por unos pocos grupos que cooperan estrechamente entre sí.

Seguimiento de C&C

La implementación de Grandoreiro de su protocolo de red permitió a los investigadores de ESET echar un vistazo detrás de la cortina y echar un vistazo a la victimología. Los servidores de C&C de Grandoreiro entregan información sobre las víctimas conectadas en el momento de la solicitud inicial a cada nueva víctima conectada. Dicho esto, los datos están sesgados por el número de peticiones, sus intervalos y la validez de los datos proporcionados por los servidores de C&C.

Cada víctima conectada al servidor de C&C de Grandoreiro se identifica mediante una login_string, una cadena que Grandoreiro construye al establecer la conexión. Diferentes construcciones utilizan diferentes formatos y diferentes formatos contienen diferente información. En la Tabla 3 resumimos la información que puede obtenerse de la cadena login_string. La columna Ocurrencia muestra un porcentaje de todos los formatos que hemos visto que contienen el tipo de información correspondiente.

Tabla 3. Resumen de la información que puede obtenerse de la cadena de inicio de sesión de una víctima de Grandoreiro

InformaciónOcurrenciaDescripción
Sistema Operativo100%OS de la máquina de la víctima.
Nombre de la máquina100%Nombre de la máquina de las víctimas.
País100%País objetivo de las muestras de Grandoreiro (incluido en la muestra del malware).
Versión100%Versión (version_string) de la muestra de Grandoreiro.
Nombre en código92%Nombre en código del banco que activa la conexión con el C&C (diseñado por los desarrolladores de Grandoreiro).
Uptime25%Tiempo (en horas) que el ordenador de la víctima ha estado en funcionamiento.
Resolución del monitor 8%Resolución del monitor principal de la víctima.
Nombre de usuario8%Nombre de usuario de la víctima.

Tres de los campos merecen una explicación más detallada. El país es una cadena codificada en el binario de Grandoreiro en lugar de información obtenida a través de los servicios apropiados. Por lo tanto, sirve más como país previsto de la víctima.

Nombre en clave del banco es una cadena que los desarrolladores de Grandoreiro asocian a un determinado banco u otra institución financiera. La víctima visitaba el sitio web de ese banco, lo que activaba la conexión C&C.

Version_string es una cadena que identifica una versión específica de Grandoreiro. Está codificada en el malware y contiene una cadena que identifica una serie de compilación específica, una versión (de la que ya hablamos en la introducción) y una marca de tiempo. La Tabla 4 ilustra los diferentes formatos y la información que contienen. Observa que algunas de las marcas de tiempo sólo contienen el mes y el día, mientras que otras contienen también el año.

Tabla 4. Lista de los diferentes formatos de version_string y su análisis sintáctico

Versión de la cadenaBuild IDVersiónTimestamp
DANILODANILON/AN/A
(V37)(P1X)1207P1XV3712/07
(MX)2006MXN/A20/06
fox50.28102020fox50N/A28/10/2020
MADMX(RELOAD)EMAIL2607MADMX(RELOAD)EMAILN/A26/07

Se puede tener la tentación de decir que el ID de compilación identifica realmente al operador. Sin embargo, no creemos que sea así. El formato de esta cadena es muy caótico, a veces sólo hace referencia a un mes en el que probablemente se construyó el binario (como(AGOSTO)2708). Además, creemos firmemente que P1X se refiere a una consola utilizada por el/los operador/es de Grandoreiro llamada PIXLOGGER.

Rastreo de servidores de C&C: conclusiones

En esta sección, nos centramos en lo que hemos encontrado consultando los servidores de C&C. Todos los datos estadísticos que aparecen en esta sección se han obtenido directamente de los servidores de C&C de Grandoreiro, no de la telemetría de ESET.

Las muestras antiguas siguen activas

Cada login_string que observamos contiene la version_string y la gran mayoría de ellas contiene la información de la marca de tiempo (ver Tabla 3 y Tabla 4). Aunque muchas de ellas contienen sólo el día y el mes, como parece ser la elección del desarrollador en ocasiones, la muestra comunicada más antigua fue timestamped 15/09/2020 – es decir, desde el momento en que esta DGA se introdujo por primera vez en Grandoreiro. La muestra más reciente tiene fecha de 23/12/2023.

Distribución del sistema operativo

Dado que todos los formatos login_string contienen información sobre el sistema operativo, podemos hacernos una idea precisa de qué sistemas operativos fueron víctimas, como se ilustra en la Figura 4.

Figura 4. Distribución de sistemas operativos entre las víctimas de Grandoreiro

Distribución por países (prevista)

Ya hemos mencionado que Grandoreiro utiliza un valor codificado en lugar de consultar a un servicio para obtener el país de la víctima. La figura 5 muestra la distribución que hemos observado.

Figura 5. Distribución de los códigos de país entre las víctimas de Grandoreiro

Esta distribución es la esperable de Grandoreiro. Curiosamente, no guarda correlación con el mapa representado en la Figura 1. La explicación más lógica es que los builds no están marcados para parecerse a sus objetivos previstos. Por ejemplo, el aumento de los ataques en Argentina no se refleja en absoluto en el marcado hardcoded. Brasil representa casi el 41% de todas las víctimas, seguido de México con el 30% y España con el 28%. Argentina, Portugal y Perú representan menos del 1%. Curiosamente, hemos visto unas pocas víctimas (menos de 10) marcadas como PM (San Pedro y Miquelón), GR (Grecia) o FR (Francia). Creemos que se trata de erratas o tienen otros significados en lugar de apuntar a esos países.

Se observa también que, aunque Grandoreiro añadió objetivos de muchos países fuera de América Latina ya en 2020, hemos observado pocas o ninguna campaña dirigida a esos países, y la Figura 5 lo corrobora.

Número de víctimas

Hemos observado que el número medio de víctimas conectadas en un día es de 563. Sin embargo, esta cifra contiene ciertamente duplicados. Sin embargo, este número contiene ciertamente duplicados, porque si una víctima permanece conectada durante mucho tiempo, lo que hemos observado que ocurre a menudo, el servidor de C&C de Grandoreiro la reportará en múltiples peticiones.

Para tratar de resolver este problema, definimos una víctima única como aquella con un conjunto único de características identificativas (como el nombre del dispositivo, el nombre de usuario, etc.), omitiendo aquellas que están sujetas a cambios (como el tiempo de actividad). De este modo, obtuvimos una media de 551 víctimas únicas conectadas al día.

Teniendo en cuenta que hemos observado víctimas que se conectaban constantemente a los servidores C&C durante más de un año, hemos calculado una media de 114 nuevas víctimas únicas que se conectan a los servidores C&C cada día. Llegamos a esta cifra descartando las víctimas únicas que ya habíamos observado anteriormente.

Funcionamiento interno de Grandoreiro

Centrémonos, en profundidad, en las dos características más cruciales de Grandoreiro: la DGA y el protocolo de red.

DGA

Los operadores de Grandoreiro han implementado varios tipos de DGA a lo largo de los años, apareciendo la más reciente en julio de 2020. Aunque hemos observado algunos cambios menores, el núcleo del algoritmo no ha cambiado desde entonces.

La DGA utiliza una configuración específica que está codificada en el binario, almacenada como múltiples cadenas. La figura 6 muestra una de estas configuraciones (con dga_id «bbj»), reformateada en JSON para una mejor legibilidad.

Figura 6. Configuración de la DGA Grandoreiro, reformateada en JSON

En la gran mayoría de los casos, el campo base_domain es freedynamicdns.org o zapto.org. Como ya se ha mencionado, Grandoreiro utiliza No-IP para el registro de sus dominios. El campo base64_alpha corresponde al alfabeto base64 personalizado que utiliza la DGA. El campo month_substitution se utiliza para sustituir un número de mes por un carácter.

La dga_table constituye la parte principal de la configuración. Consta de 12 líneas, cada una con 35 campos delimitados por |. La primera entrada de cada línea es el dga_id. La segunda y la última entrada representan el mes al que se destina la línea. Los 32 campos restantes representan cada uno un valor para un día diferente del mes (dejando al menos un campo sin utilizar).

La lógica de la DGA se muestra en la figura 7. En primer lugar, el algoritmo selecciona la línea correcta y la entrada correcta de la misma, tratándola como una clave de cuatro bytes. A continuación, formatea la fecha actual en una cadena y la cifra con la clave mediante un simple XOR. A continuación, antepone el dga_id al resultado, codifica el resultado utilizando base64 con un alfabeto personalizado y elimina cualquier carácter de relleno =. El resultado final es el subdominio que, junto con base_domain, se utilizará como servidor de C&C para el día en curso. La parte resaltada en rojo es un mecanismo a prueba de fallos y lo discutiremos a continuación.

Figura 7. Cálculo de la DGA de Grandoreiro reimplementado en Python

Grandoreiro ha implementado, en algunas versiones, un mecanismo de seguridad para cuando el dominio principal no se resuelve. Este mecanismo no está presente en todas las versiones y su lógica ha cambiado algunas veces, pero la idea básica se ilustra en la Figura 7. Utiliza una configuración que es constante en todas las versiones. Utiliza una configuración que es constante en las muestras que analizamos y que puede generarse mediante el sencillo código que se muestra en la Figura 8. Cada entrada consta de una clave, un prefijo y un dominio base.

El algoritmo a prueba de fallos toma una parte del subdominio principal de C&C. Luego itera sobre todas las entradas de configuración, las cifra utilizando XOR y les añade un prefijo, de forma similar a la parte del algoritmo principal.

Figura 8. Generador de configuración DGA a prueba de fallos reimplementado en Python

Desde septiembre de 2022, hemos empezado a observar muestras que utilizan un DGA ligeramente modificado. El algoritmo sigue siendo casi idéntico, pero en lugar de codificar el subdominio en base64 en el paso final, se le añade un prefijo codificado. Según nuestro seguimiento, este método se ha convertido en el dominante desde aproximadamente julio de 2023.

Protocolo de red

Grandoreiro utiliza RTC Portal, un conjunto de componentes Delphi construidos sobre el SDK RealThinClient que está construido sobre HTTP(S). RTC Portal se dejó de fabricar en 2017 y su código fuente se publicó en GitHub. Esencialmente, RTC Portal permite que uno o más Controles accedan remotamente a uno o más Hosts. Los Hosts y los Controles están separados por un componente mediador llamado Gateway.

Los operadores de Grandoreiro utilizan una consola (que actúa como Control) para conectarse al servidor de C&C (que actúa como Gateway) y comunicarse con las máquinas comprometidas (que actúan como Hosts). Para conectarse a Gateway, se requieren tres parámetros: una clave secreta, la longitud de la clave y un nombre de usuario.

La clave secreta se utiliza para cifrar la solicitud inicial enviada al servidor. Por lo tanto, el servidor también necesita conocer la clave secreta para descifrar la solicitud inicial del cliente.

La longitud de la clave determina la longitud de las claves para cifrar el tráfico, establecidas durante el apretón de manos. El tráfico se cifra utilizando un cifrado de flujo personalizado. Se establecen dos claves diferentes: una para el tráfico entrante y otra para el saliente.

La clave puede ser cualquier cadena. El Gateway requiere que cada componente conectado tenga un nombre de usuario único.

Grandoreiro utiliza dos combinaciones diferentes de valores de clave secreta y longitud de clave, siempre codificados en el binario, y ya hemos hablado de la cadena login_string que se utiliza como inicio de sesión.

La documentación de RTC indica que sólo puede manejar un número limitado de conexiones a la vez. Teniendo en cuenta que cada Host conectado necesita enviar al menos una petición por segundo o de lo contrario su conexión se corta, creemos que la razón por la que Grandoreiro utiliza múltiples servidores C&C es un intento de no sobrecargar a ninguno de ellos.

Conclusión

En este blogpost, hemos proporcionado una mirada detrás de la cortina de nuestro seguimiento a largo plazo de Grandoreiro que ayudó a hacer posible esta operación de interrupción. Hemos descrito en profundidad cómo funciona la DGA de Grandoreiro, cuántas configuraciones diferentes existen simultáneamente y cómo pudimos detectar muchos solapamientos de direcciones IP entre ellas.

También hemos proporcionado información estadística obtenida de los servidores C&C. Esta información proporciona una excelente visión general de la victimología y la selección de objetivos, al tiempo que nos permite ver el nivel real de impacto.

La operación de desarticulación dirigida por la Policía Federal de Brasil tenía como objetivo a individuos que, se cree, están en lo más alto de la jerarquía operativa de Grandoreiro. ESET continuará rastreando otros troyanos bancarios latinoamericanos mientras vigila de cerca cualquier actividad de Grandoreiro tras esta operación de interrupción.

Accede a la investigación en inglés aquí.

ESET España participa en una operación mundial para desarticular el troyano bancario Grandoreiro