Aparentemente, el grupo Sednit ha estado desarrollando nuevos componentes para agregar a la familia de malware Zebrocy.
Este grupo, también conocido como APT28, Fancy Bear, Sofacy o STRONTIUM, ha estado operando desde al menos 2004 y ha sido noticia con frecuencia en los últimos años.
El día 20 agosto de 2019, Sednit lanzó una nueva campaña dirigida a sus víctimas habituales - embajadas y Ministerios de Asuntos Exteriores de los países de Europa Oriental y Asia central.
Esta última campaña comenzó con un correo electrónico de phishing que contenía un archivo adjunto malicioso, el cual da inicio a una larga cadena de downloaders que termina con un backdoor. Un ejemplo de estos correos fue subido a VirusTotal el día 22 agosto, dos días después del envío del correo. Una descripción general del vector de ataque fue publicada recientemente por Telsy TRT.
Sin embargo, tenemos algunas piezas adicionales de este rompecabezas que pueden ser de ayuda para obtener un panorama más completo de esta reciente campaña del grupo Sednit.
Como predijeron otros colegas investigadores, el grupo Sednit agregó un nuevo lenguaje de desarrollo a su conjunto de herramientas, más específicamente a su downloader: el lenguaje Nim. Sin embargo, sus desarrolladores también han estado ocupados mejorando su downloader en Golang, así como reescribiendo su backdoor de Delphi a Golang.
Un compromiso complicado
La Figura 1 muestra los diferentes pasos que conducen a que una víctima se vea comprometida, desde el correo electrónico malicioso recibido inicialmente en la bandeja de entrada hasta que es desplegado el backdoor en los blancos de ataque considerados "suficientemente interesantes" por los operadores.

Figura 1. Resumen de la cadena de compromiso
Cuando una víctima es blanco de ataque de los componentes de Zebrocy, la cadena suele ser bastante ruidosa. Esto es así porque, en este caso, la víctima tiene al menos seis componentes maliciosos que han sido droppeados en la computadora antes de que se ejecute el payload final. Dichas actividades pueden fácilmente provocar diferentes tipos de alertas por parte de un producto de seguridad.
El documento adjunto al correo electrónico de phishing está en blanco, pero referencia a una plantilla remota, wordData.dotm, alojada en Dropbox. Al abrir este documento en Word, se descarga wordData.dotm, como se ve en la Figura 2, y lo incorpora al entorno de trabajo del documento asociado, incluido cualquier contenido activo que pueda contener la plantilla.

Figura 2. Documento de Word vacío descargando una plantilla remota
El archivo wordData.dotm contiene macros maliciosas que luego se ejecutan. (Dependiendo de la versión de Microsoft Word, las macros de VBA están deshabilitadas de manera predeterminada y se requiere la acción del usuario para habilitarlas). También contiene un archivo ZIP embebido que las macros droppearon y extrajeron.
Como se muestra en la Figura 1, las macros en wordData.dotm abren otro documento (lmss.doc que se desempaquetó del archivo extraído desde wordData.dotm). Las macros en lmss.doc ejecutan lmss.exe (el nuevo downloader en Nim de Zebrocy, también extraído del archivo embebido en wordData.dotm) en lugar de wordData.dotm, ejecutando el downloader directamente.
Sin embargo, es importante notar que lmss.doc, que contiene el código VBA que ejecuta el nuevo downloader en Nim, también incorpora un ejecutable codificado en base64. De acuerdo con sus Propiedades de documento, lmss.doc fue creado en enero de 2019 y modificado el día 20 agosto; unas horas antes de comenzar la campaña.

Figura 3. Fechas de creación y última modificación de lmss.doc
El ejecutable embebido en lmss.doc es un downloader en AutoIt (SHA-1: 6b300486d17d07a02365d32b673cd6638bd384f3), el cual fue utilizado en una campaña pasada que se llevó adelante en un tiempo cercano a la creación de lmss.doc. En este caso, el downloader en AutoIt es ignorado y no tiene ningún otro propósito más que el de aumentar el tamaño del documento. Probablemente, el operador olvidó eliminar el downloader previamente embebido (no sería la primera vez que los operadores de Sednit cometen errores).
Los downloaders
Los operadores de Sednit han utilizado varios downloaders escritos en diferentes idiomas. Esta campaña utiliza la extensión más reciente de esa lista: un downloader escrito en el relativamente nuevo lenguaje Nim. Es un binario sencillo de descargar y ejecutar con dos pequeños detalles agregados. El primero probablemente sea utilizado como un truco anti-sandbox y comprueba que la primera letra del archivo ejecutado (letra 1 aquí o 0x6C en hexadecimal) no ha cambiado.

Figura 4. Verificación de nombre de archivo
El segundo es un tipo de ofuscación donde el operador reemplaza las letras de marcador de posición en una string con las correctas, en los desplazamientos definidos. Como se ve en la Figura 5, el downloader reconstruye la string de la URL de descarga correcta con este método para evitar herramientas básicas de análisis estático, que de otro modo podrían ubicar la string de la URL.

Figura 5. Salida Hex-Rays de las strings de desofuscación
Por ejemplo, la cadena o-ps-c..ll está "parcheada" en tres desplazamientos por s,v y d respectivamente, para proporcionar ospsvc.dll. En el caso de la URL, dado que el comienzo de la cadena en el downloader es h@@p://, las herramientas que buscan http:// no lo detectarán.
El downloader en Nim obtiene su payload de la librería de vínculos dinámicos (DLL), denominada ospsvc.dll, en C:\ProgramData\Java\Oracle\, y la ejecuta como un servicio a través de regsvr32/s.
ospsvc.dll es un downloader escrito en Golang, y diferente a otros downloaders del grupo Sednit vistos en el pasado.
Los anteriores downloaders en Golang de Sednit han sido descritos en detalle por otros investigadores [1] [2] [3] y parece ser que los desarrolladores de Sednit han reescrito su downloader anterior de Delphi en Golang. Los anteriores downloaderes recopilan mucha información sobre la computadora de la víctima y la envían a su servidor de C&C. Sin embargo, este nuevo es bastante ligero en términos de sus capacidades de recopilación de datos, como se describe a continuación.
Su función main_init() contiene librerías que se inicializan y no necesitan más explicaciones debido a sus nombres (consulte este artículo para obtener más información).

Figura 6. Salida Hex-Rays de funciones inicializadas en main_init() utilizando el plugin IDAGolangHelper
Dado que la DLL se ejecuta como un servicio, a través del downloader en Nim, debemos mirar main_DllRegisterServer() en lugar de main_main(). Las strings y la clave se apilan y se pueden descifrar con un simple loop XOR. Este simple cifrado es bastante eficiente contra herramientas que extraen strings apiladas de binarios estáticamente.

Figura 7. Salida de IDA Pro de strings cifradas apiladas
Además de descargar la siguiente etapa del malware, tomar capturas de pantalla del escritorio de la víctima y ejecutar comandos recibidos del servidor C&C son las funciones principales de este malware.
Las capturas de pantalla se toman cada 35 segundos durante los primeros minutos de la ejecución de este downloader, y luego se envían al servidor de C&C en forma codificada en base64. El nombre de host y los valores %USERPROFILE% también se envían al servidor C&C codificado en base64. La respuesta del servidor C&C también es sencilla: es una concatenación de strings codificadas en base64, separadas por "|".
<spaces>|<cmd to execute>|<name of the binary to drop>|<binary to drop>
Según nuestra telemetría, este downloader se ha utilizado para ejecutar tres piezas diferentes de malware. El primero es el dumper que describimos en nuestro artículo anterior de Zebrocy. El segundo es el habitual backdoor en Delphi: también se ejecuta como un servicio a través del mismo comando utilizado por el downloader en Nim. El tercero que vimos es un nuevo backdoor descargado y ejecutado en la máquina de la víctima, como se describe en la siguiente sección.
El nuevo backdoor
Análisis
El nuevo backdoor de Zebrocy no está escrito en Delphi como estamos acostumbrados, sino en Golang. Hasta donde sabemos, esta es la primera vez que se ve este backdoor, pero comparte muchas similitudes con el escrito en Delphi.
Al mirar nuevamente el código main_init() de la función de inicialización de la librería (Figura 8) podemos ver nuevas entradas. Un algoritmo AES, codificación hexadecimal y capacidades de captura de pantalla son las entradas principales que se agregaron.

Figura 8. Diferencia entre el backdoor y las funciones de downloader inicializadas en main_init()
Nótese que image_png_init reemplaza image_jpeg_init para tomar capturas de pantalla. Las imágenes en formato JPG suelen tener un tamaño más pequeño que el formato PNG.
El backdoor se inicia con un argumento que es una string codificada en hexadecimal. Todos menos el último fragmento de seis bytes de la string está cifrada con XOR con la clave almacenada en los últimos seis bytes de la string. El siguiente fragmento en Python describe la lógica de descifrado.
key = arg[-6:].decode('hex')
enc = arg[:-6].decode('hex')
''.join(chr(ord(i) ^ ord(j)) for i, j in zip(itertools.cycle(key), enc))
Es la dirección del servidor C&C, que luego se cifra y se almacena en el disco. Ese cifrado se realiza utilizando el algoritmo AES-128 ECB con una clave generada a partir del nombre de host. Por lo tanto, no hay posibilidad de obtener este servidor C&C simplemente mirando el binario. No hay persistencia definida en los downloaders, como hemos visto en el pasado, ni el backdoor tiene presenta un mecanismo de persistencia.
Este nuevo backdoor tiene varias capacidades que también se vieron anteriormente en el backdoor en Delphi de Zebrocy:
- manipulación de archivos como creación, modificación y eliminación
- capacidades de captura de pantalla
- enumeración de unidades
- ejecución de comandos (a través de cmd.exe )
- programar una tarea con el siguiente nombre Windows\Software\OSDebug (que los operadores podrían usar para establecer la persistencia manualmente).
Al igual que en el backdoor en Delphi, hay un conjunto muy limitado de comandos, pero la capacidad de ejecutar comandos arbitrarios a través de cmd.exe amplía posibilidades como la persistencia o la recopilación de información. Otra similitud encontrada es un número de versión de tres dígitos (en el formato xyz); la versión principal actual es 4.yz
Red
El protocolo de red comparte algunas similitudes con la versión Delphi del backdoor. La primera interacción con el servidor C&C recupera una clave AES de 32 bits para cifrar las comunicaciones futuras. La captura de paquetes de esa primera solicitud se ve así:
POST [REDACTED URI] HTTP/1.1
Host: [REDACTED IP]
User-Agent: Go-http-client/1.1
Content-Length: 297
Content‑Type: multipart/form‑data; boundary=b116f1e0a94eff1bb406531e74bb0feba65687cf90ec8a64fc409f230fbd
Accept-Encoding: gzip
--b116f1e0a94eff1bb406531e74bb0feba65687cf90ec8a64fc409f230fbd
Content-Disposition: form-data; name="filename"; filename="[REDACTED]"
Content-Type: application/octet-stream
1
--b116f1e0a94eff1bb406531e74bb0feba65687cf90ec8a64fc409f230fbd--
Aquellos con experiencia en Sednit podrían pensar que Content-Disposition y la palabra clave boundary parecen familiares. Anteriormente fueron utilizados por el backdoor en Delphi en su protocolo de red; también utiliza el algoritmo AES para cifrar el pseudo cuerpo (contenido después del dato Content-Type). Nótese que incluso si Content-Disposition y la segunda instancia de Content-Type son encabezados HTTP reales, aquí se usan dentro del cuerpo del mensaje HTTP. El campo boundary es aleatorio para cada intercambio y el campo filename dentro del pseudo encabezado Content‑Disposition se puede descifrar con el siguiente fragmento de Python:
len_filename = len(filename)
len_key = 14
xor_key = filename[-len_key:].decode('hex')
filename = filename[:len_filename-len_key].decode('hex')
val_filename = ''.join(chr(ord(i)^ord(j)) for i,j in zip(itertools.cycle(xor_key),filename))
random_int = val_filename[-4:]
que da como resultado la siguiente string:
757365722D504318162020190821151055207C.inc
Esa string se puede comprender mejor así:
Username: 757365722D5043
SID*: 181620
Date: 20190821151055
Random: 207C.inc
* 6 bytes provienen de los identificadores de seguridad (SID) del usuario actual S-1-5-21‑xxxxxxxxx‑yyyyyyyyyy‑zzzzzzzzzz‑1000
Otras interacciones con el servidor C&C siguen este patrón, excepto que el pseudo cuerpo, que es 1 en el ejemplo anterior, sea reemplazado por la salida del comando solicitado por el servidor C&C. El cuerpo completo del mensaje también está encriptado, utilizando el mismo algoritmo AES utilizado anteriormente, con la clave provista en el primer intercambio.
Conclusión
Nuevos downloaders, nuevo backdoor: el grupo Sednit ha estado activo y no deja que sus componentes se vuelvan demasiado viejos. ¿Nuevo? Realmente no. Al mirarlo, parece que el grupo Sednit está transfiriendo el código original a otros idiomas o volviéndolo a implementar con la esperanza de evadir la detección. Probablemente sea más fácil de esa manera y significa que no necesitan cambiar sus TTPs por completo. El vector de compromiso inicial permanece sin cambios, pero el uso de un servicio como Dropbox para descargar una plantilla remota es inusual para el grupo.
ESET recomienda estar atento cuando los usuarios abren archivos adjuntos de correos electrónicos sospechosos.
Continuaremos monitoreando nuevas actividades del grupo Sednit y publicaremos información relevante en nuestro blog. Para cualquier consulta, contáctenos a travpes de threatintel@eset.com.
Indicadores de Compromiso (IoCs)
Hashes (SHA-1) | Filenames | ESET detection names |
---|---|---|
c613fcccb380f7e3ce157c4f620efca503c1bad3 | - (eml file) | DOC/TrojanDownloader.Agent.AMY |
6f281b30d8d6a9bc1dbe2fe73995aac382c4a543 | 612243236.docx | DOC/TrojanDownloader.Agent.AMY |
f3f945fb22916f82cb7407cde2a80a68cd83b074 | wordData.dotm | VBA/TrojanDropper.Agent.AIP |
a56af5b44624e8ada60057fd7f39af5b3de10724 | lmss.zip | Win32/TrojanDownloader.Sednit.BK |
b8ac400e1deb6e90fa4e2adb150c511c98bafc6e | lmss.doc | VBA/TrojanDropper.Agent.AIQ |
f0793e02180f3ccf48e41bd67ec1161d93f07e01 | lmss.exe | Win32/TrojanDownloader.Sednit.BK |
04303024ff453f918925d7160abbd199f137a442 | ospsvc.dll | Win32/Sednit.DI |
c96db85ece2b57a9e82ba36b5f31ca9d2051a6f0 | osppsvc.exe | Win32/Sednit.DJ |
Red
https://www.dropbox[.]com/s/foughx315flj51u/wordData.dotm?dl=1
185.221.202[.]35
Técnicas de MITRE ATT&CK
Tactic | ID | Name | Description |
---|---|---|---|
Initial Access | T1193 | Spearphishing Attachment | Zebrocy is using spearphishing emails with an attachment as method of compromise. |
Execution | T1059 | Command-Line Interface | The Golang backdoor uses cmd.exe to execute commands. |
T1117 | Regsvr32 | The Nim downloader uses regsvr32.exe to launch the Golang downloader. | |
T1053 | Scheduled Task | The Golang backdoor can create a pre-defined scheduled task. | |
T1064 | Scripting | The remote template contains VBA used to execute the next stage of the malware. | |
T1204 | User Execution | Zebrocy attempts to get users to click on Microsoft Office attachments containing malicious macro scripts. | |
Persistence | T1053 | Scheduled Task | The Golang backdoor can create a pre-defined scheduled task. |
Privilege Escalation | T1053 | Scheduled Task | The Golang backdoor can create a pre-defined scheduled task. |
Defense Evasion | T1107 | File Deletion | The Golang backdoor can delete files. |
T1117 | Regsvr32 | The Nim downloader uses regsvr32.exe to launch the Golang downloader. | |
T1064 | Scripting | The remote template contains VBA used to execute the next stage of the malware. | |
Discovery | T1083 | File and Directory Discovery | The Golang backdoor can list drives. |
Collection | T1113 | Screen Capture | HTTP is used for C&C communications. |
Command and Control | T1043 | Commonly Used Port | All components are using port 80 to communicate with the C&C server. |
T1024 | Custom Cryptographic Protocol | The Golang backdoor is using an XOR loop for its communications. | |
T1132 | Data Encoding | The Golang backdoor base64- encodes the data before encrypting it. | |
T1071 | Standard Application Layer Protocol | HTTP is used for C&C communications. | |
T1032 | Standard Cryptographic Protocol | The Golang backdoor encrypts communications with the C&C server with AES ECB. | |
Exfiltration | T1022 | Data Encrypted | The Golang backdoor encrypts the data with AES ECB before sending it over the C&C server. |
T1041 | Exfiltration Over Command and Control Channel | The Golang backdoor exfiltrates data to its C&C server. |
Referencias:
[1] https://unit42.paloaltonetworks.com/sofacy-creates-new-go-variant-of-zebrocy-tool/
[2] https://securelist.com/a-zebrocy-go-downloader/89419/
[3] https://www.vkremez.com/2018/12/lets-learn-dissecting-apt28sofacy.html