Seguridad

Sandworm y UAC-0099: el ataque que destruyó datos en una empresa de Ucrania

El titular suena a noticia de esta semana, pero no lo es. El ataque contra la empresa de logística de granos en Ucrania ocurrió entre julio y septiembre de 2025; lo que se publicó el 22 de octubre de 2026 es el análisis forense de ESET Research sobre lo que quedaba dentro. Esa diferencia de más de un año cambia por completo la respuesta que sirve: aquí no hay un parche que aplicar hoy, hay un patrón de intrusión que todavía puede estar activo en empresas de logística, energía y transporte de la región.

El hallazgo central es un backdoor en Go al que llamaron MythicRatatoskr, que esconde su servidor de comando y control dentro de Yggdrasil, una red mesh pública. No es un dominio que se pueda bloquear en el firewall: es una dirección IPv6 dentro de la malla, y solo se alcanza si el host se une a la red. Hay un segundo detalle más incómodo todavía, y es el que más se deforma en la cobertura de prensa: Yggdrasil no fue diseñado para dar anonimato, sino para que la red sea difícil de tumbar. Quien lo recomendaba como capa de invisibilidad se equivocó de objetivo.

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30 a 45 minutos de lectura y dos sesiones de terminal para dejar reglas de detección y una lista blanca de egreso listos.
  • Requisitos: un servidor Linux con auditd, iptables o nftables, y acceso de lectura a los registros de SSH. No hace falta un laboratorio aislado.
  • Resultado: un método concreto para reconocer movimiento lateral por SFTP, conexiones TLS salientes hacia la malla Yggdrasil y artefactos ocultos con punto inicial.
  • Troubleshooting: si el bloque de reglas del firewall no surte efecto, revisa que estén en la cadena OUTPUT y que no exista una política previa que descarte todo antes de evaluarlas.

Qué pasó realmente: la cadena UAC-0099 y Sandworm

La secuencia tiene dos actores y no conviene mezclarlos. UAC-0099 es un grupo de ciberespionaje que ESET describe con confianza media como alineado con intereses rusos: apunta a organismos gubernamentales, instituciones financieras y medios, todos en Ucrania. El grupo opera desde al menos 2022 y fue reportado por primera vez por CERT-UA en junio de 2023. Sandworm es el grupo destructivo por excelencia, atribuido a la Unidad 74455 de la GRU.

El resultado del trabajo de ESET es que estos dos actores cooperaron. UAC-0099 entró, abrió el camino con su propio kit y después le pasó el acceso a Sandworm, que ejecutó el borrado. Ese traspaso se evalúa con alta confianza por los TTPs observados. ESET también señala el precedente: en 2025 ya había documentado una colaboración similar entre Gamaredon y Turla.

El punto que más importa para un sysadmin no es quién inició la cadena, sino el intervalo: el acceso inicial fue el 16 de julio de 2025 y el borrado de datos el 17 de septiembre de 2025. Más de dos meses de permanencia silenciosa entre ambas fechas.

Momento Evento Actor Artefacto
16-jul-2025, 06:59 Tarea programada pdfopentask ejecuta un payload de PowerShell desde %temp%/temporarydoc.txt UAC-0099 Adjunto malicioso de spearphishing
Un minuto después Se despliega MATCHBOIL, descargador que instala el backdoor MATCHWOK UAC-0099 C&C uztickets[.]com, descarga desde egyptanimals[.]com/animals/photoalbum
17-jul-2025, 09:28 Se entrega el binario MythicRatatoskr Indeterminado Backdoor en Go con C&C dentro de Yggdrasil
17-jul-2025, en adelante Más muestras se despliegan en otras máquinas usando un servidor SFTP de OpenSSH Indeterminado Movimiento lateral por SSH
Agosto 2025 Se detecta un servidor SOCKS5 en algunas máquinas Indeterminado Herramienta en Go llamada bindProxy
17-sep-2025 Borrado de datos con la utilidad SDelete desplegada por Group Policy de Active Directory Sandworm Táctica clásica de Sandworm

Dos precisiones que evitan exagerar el caso: no hubo ransomware, hubo borrado destructivo con SDelete, y el actor primario fue UAC-0099, no Sandworm. Sandworm llegó después, por el traspaso. ESET también es explícito en un punto que la prensa suele estirar: no ha visto el backdoor usado en ningún otro sitio, así que no hay indicios de explotación masiva.

Un apunte sobre nomenclatura que vale la pena tener claro: algunos medios de seguridad en inglés identifican a UAC-0099 con el alias Earth Sirrush. El informe de ESET no lo usa y describe al grupo como alineado con intereses rusos con confianza media, por sus objetivos. Si necesitas citar la atribución, cita a ESET y no a la prensa.

Qué es MythicRatatoskr por dentro

El nombre viene de la mitología nórdica: en el árbol Yggdrasil vive una ardilla llamada Ratatoskr que lleva mensajes entre la copa y las raíces. El equipo de ESET, Anton Cherepanov y Peter Strýček, bautizó así al malware por su función análoga: transportar datos por la malla.

Técnicamente es un backdoor con capacidades estándar: ejecución de comandos, navegación del sistema de archivos, transferencia de archivos, captura de pantalla y proxy. Los comandos que quedaron en el binario son chtime, expose, upload, download, nodeinfo, screenshot, cd, ls, pwd, churl, proxy y shell. Dos llaman la atención: expose reenvía conexiones TCP desde la malla hacia un puerto local, y proxy levanta un SOCKS5 inverso contra una dirección fija en el mismo servidor de C&C, en el puerto 8080.

La persistencia en Windows corre de dos formas. MATCHBOIL escribe el valor de registro UpdateMonitor en HKCU\Software\Microsoft\Windows\CurrentVersion\Run, y MythicRatatoskr se registra como servicio de Windows con el nombre ieupdate.

La configuración se guarda como JSON cifrado con AES-256-CFB, usando una clave fija embebida en el binario, y los primeros 16 bytes del archivo son el vector de inicialización. Si el archivo de configuración no existe, el malware no falla: trae una configuración por defecto embebida, la cifra y la escribe durante la inicialización. Eso permite desplegarlo sin preparar nada del lado del atacante y actualizar la configuración más tarde por comando.

Un detalle de ingeniería vale la pena: el código está basado en yggstack, una implementación del stack de red de Yggdrasil en espacio de usuario. No necesita crear una interfaz de tunnel, así que el mismo binario funciona tanto en un host con privilegios como en uno sin ellos, y eso facilita la portabilidad a otros sistemas Unix. En los binarios hay señales de que el desarrollo empezó entre diciembre de 2024 y febrero de 2025.

Los artefactos en disco quedaron en rutas que conviene reconocer. ESET documenta como rutas de instalación C:/Windows/system32/updater.exe, C:/Windows/system32/krbtman.exe y C:/Windows/system32/windowsdefendersvc.exe, entre otras. Hay una colisión de nombres que puede confundir un análisis: krbtman.exe es MythicRatatoskr en unas máquinas y el servidor SOCKS5 en otras.

Por qué Yggdrasil y no un dominio

Yggdrasil es una red mesh descentralizada en estado alpha. Cada nodo genera su propio par de claves Ed25519 y deriva su dirección IPv6 de la clave pública, dentro del rango 200::/7, un bloque que la IETF deprecó en 2004. El tráfico entre nodos pares va protegido de extremo a extremo y el enrutamiento es experimental. No hay un servidor central: la red es resistente y difícil de interrumpir.

El backdoor incluye una lista embebida de 32 nodos pares públicos, codificada en base64, y elige tres al azar para unirse a la malla pública. Esa es exactamente la cantidad que recomienda el propio proyecto para aumentar la resiliencia de las conexiones. Una vez dentro, la comunicación con el C&C ocurre por HTTPS en el puerto 443, con mensajes JSON en POST que llevan un uuid, un tipo de mensaje y datos opcionales. Los cuatro tipos son checkin, tasking, result y getfile. Los datos van codificados en base64 y no hay preparación previa: la exfiltración de archivos y capturas de pantalla ocurre directamente por el canal, sin etapa intermedia.

Aquí está la corrección importante sobre el relato mediático. Yggdrasil no está diseñado para dar anonimato, y ESET lo dice de forma textual: el anonimato no está entre los objetivos del proyecto. Lo que el atacante busca es resiliencia. No hay un dominio ni una IP central que un analista pueda reportar y que un proveedor pueda tumbar.

Conviene distinguir dos direcciones que la prensa mezcla. La del C&C es fija: vive en la configuración embebida del malware y ESET la publica como indicador de compromiso, la primera vez vista el 17 de julio de 2025. La que sí cambia en cada ejecución es la del host infectado, porque el backdoor genera una clave Ed25519 nueva al arrancar y de ahí deriva su dirección en la malla. Es un detalle con consecuencia práctica: la dirección del C&C es un valor estable que se puede bloquear o reportar, y lo que rota es la identidad de cada víctima.

La contramedida que sí propone ESET es bloquear las direcciones de los nodos pares públicos, ya que el nombre del host del C&C no existe. No es perfecta: la lista mezcla IPs, dominios y puertos no estándar, y los dominios son la parte que rota. ESET señala además que la mayoría de los nodos de su lista siguen operativos, así que el valor real está en combinarla con una lista blanca de egreso.

Detecta el movimiento lateral por SFTP en tu servidor Linux

Este es el ángulo útil. La segunda ronda de despliegue de MythicRatatoskr usó un servidor SFTP de OpenSSH para llevar el backdoor a otras máquinas de la organización. En un servidor Linux esa técnica deja señales bastante específicas, y ninguna requiere desplegar un EDR comercial.

Lo primero es identificar archivos authorized_keys con fecha de modificación reciente. En un servidor que lleva meses sin cambios, cualquier authorized_keys tocado en los últimos días es material de investigación, no un dato decorativo.

find /home /root -maxdepth 3 -name authorized_keys -exec stat -c '%y %n' {} + 2>/dev/null | sort

El segundo control es revisar la configuración de SSH: quien agrega una clave también suele tocar AllowUsers, AllowGroups o las directivas de autenticación para asegurar su propio acceso y cerrar el de los demás.

grep -RniE 'AllowUsers|AllowGroups|PermitRootLogin|PasswordAuthentication' /etc/ssh/ 2>/dev/null

El tercero es reconstruir la línea de tiempo de sesiones SFTP. Una transferencia de archivos fuera del horario de trabajo del operador de turno es un dato que se consulta contra el calendario del equipo, no contra una regla automática. El nombre de la unidad cambia según la distribución, así que conviene pasar las dos: en Debian y Ubuntu es ssh.service y en RHEL, Rocky y Fedora es sshd.service.

journalctl -u ssh -u sshd --since '-7 days' --no-pager | grep -iE 'sftp|session opened|session closed' | tail -n 100

Y el cuarto es dejar el registro de auditoría sobre los archivos que importan, para que la próxima vez la evidencia exista aunque alguien ajuste las marcas de tiempo. Nótese que authorized_keys vive dentro del home de cada usuario, así que la regla se define sobre esa ruta y no sobre el archivo de configuración de SSH.

auditctl -w /etc/ssh/sshd_config -p wa -k sshd_conf
auditctl -w /home -p wa -k home_changes
ausearch -k home_changes -i | tail -n 50

Estas reglas volaron con auditctl son efímeras: se pierden al reiniciar. Para que sobrevivan, van en un archivo dentro de /etc/audit/rules.d/ y se cargan con augenrules --load.

Caza los artefactos y el tráfico de la malla en Linux

El backdoor es de Windows, pero ESET encontró indicios de una posible variante Unix, y hay una pista técnica precisa. La configuración de MythicRatatoskr se guardaba en rutas como C:/Windows/Temp/.updatecache y C:/Windows/system32/.updatecache, y en una de las muestras apareció %LocalAppData%/Temp/.crond con barras inclinadas hacia adelante. ESET lo anota como un error tipográfico de los atacantes, y ese error es justamente la pista: un archivo llamado .crond con separadores Unix pertenece a un mundo Unix.

El segundo indicio es más sencillo. Todos los archivos de configuración empiezan con punto, y en sistemas tipo Unix las herramientas de listado los ocultan por defecto. En Windows no. Que el malware ocultara archivos en Windows es irrelevante, pero el mismo comportamiento en Unix sí sirve: el nombre del archivo fue elegido para esconderse.

Una búsqueda dirigida de esos artefactos en un servidor Linux es directa:

find /tmp /var/tmp /home /opt -maxdepth 5 -type f -name '.updatecache' -o -type f -name '.crond' -o -type f -name '.test_config' 2>/dev/null

Para el tráfico hay un matiz que cambia la estrategia de detección, y conviene entenderlo antes de escribir una regla. El backdoor está basado en yggstack, que implementa la pila de red de Yggdrasil en el espacio de usuario del proceso, sin crear una interfaz de tipo tunnel en el kernel. La consecuencia práctica es que la dirección IPv6 del C&C no aparece en la tabla de sockets del sistema: no hay un socket IPv6 del kernel con esa dirección. Lo que sí se ve son las conexiones TCP y UDP del propio proceso hacia las direcciones IP reales de los nodos pares públicos, en los puertos que indica la lista embebida.

Por eso la detección real no hunt una dirección IPv6 exótica, sino tráfico hacia un conjunto pequeño y conocido de IPs, en puertos poco comunes. La lista completa de los 32 nodos pares está publicada por ESET al final de su informe, y viene en formato URI, con el punto ofuscado como [.] y con el puerto incluido. Este comando extrae de ahí las IPv4, que son las que se pueden bloquear en un firewall tradicional:

tr -d '[]' < ygg_peers.txt | grep -oE '([0-9]{1,3}[.]){3}[0-9]{1,3}' | sort -u > peers_ipv4.txt
wc -l < peers_ipv4.txt

Con la lista ya en plano, buscar conexiones hacia esos nodos es directo. En la lista completa hay 10 direcciones IPv4, 21 nombres de dominio y una dirección IPv6, así que el resultado de este filtro es el subconjunto numérico y el resto queda como advertencia aparte.

ss -tnp | grep -F -f peers_ipv4.txt
ss -unp | grep -F -f peers_ipv4.txt

La primera línea cubre las conexiones TCP y la segunda las UDP, que son las que usa el transporte QUIC de la lista de nodos. Y para ver el proceso que origina el tráfico, la vista por proceso ordena mejor el ruido.

lsof -nP -iTCP -sTCP:ESTABLISHED | grep -vE '127[.]0[.]0[.]1|::1' | awk '{print $1, $2, $9}'

Finalmente, el servidor SOCKS5 que se desplegó en esta campaña es una herramienta propia, distinta del backdoor, y escucha en un puerto concreto de loopback: el 33690. El comando expose del backdoor no deja un listener local: abre un extremo dentro de la malla y el backdoor se conecta hacia el puerto local. En el host, ese comando se ve como una conexión saliente hacia ese puerto, no como un proceso escuchando.

ss -ltnp | grep ':33690'
ss -ltnp | grep -E ':(1080|1081|3128|9050)'

Bloquea la salida hacia la malla y aplica una lista blanca de egreso

Con los nodos pares ya extraídos en un archivo de texto, el bloqueo es directo. La lista publicada por ESET viene en formato URI y mezcla IP, dominios y puertos, así que conviene trabajar sobre el archivo ya normalizado del apartado anterior en lugar de pasar la lista cruda al firewall.

while read -r ip; do iptables -I OUTPUT -d "$ip" -j REJECT; done < peers_ipv4.txt
iptables -S OUTPUT | grep -c REJECT

Dos salvedades sobre esa lista que conviene tener presentes. Veintiuno de los 32 nodos son nombres de dominio, y esos son los que rotan: bloquearlos exige resolverlos por DNS en el momento de aplicar la regla, o convertirlos a IP en un proceso programado que se refresque. Y hay una dirección IPv6 en la lista, que iptables no cubre y que corresponde bloquear con ip6tables.

En nftables el mismo control se expresa como un conjunto de direcciones, que es más cómodo de auditar y de actualizar cuando la lista cambia:

nft add set inet ygg_peers '{ type ipv4_addr; }'
nft add element inet ygg_peers '{ 37.205.14.171, 109.176.250.101 }'
nft add rule inet filter output ip daddr @ygg_peers reject
nft add rule inet filter output ip6 daddr 200::/7 reject

La cuarta línea merece un comentario, porque es el patrón más limpio de todos: la dirección del C&C vive dentro del rango 200::/7, y bloquear ese rango entero cubre el C&C y cualquier otra dirección de la malla, sin depender de mantener una lista de Indicadores de compromiso actualizada. Ese rango está deprecado por la IETF desde 2004 y casi ningún servidor legítimo lo usa.

El paso que más valor tiene a largo plazo no es la lista de IPs, sino el modelo: lista blanca de egreso, lo que en inglés se llama allowlist. Si el servidor solo puede hablar con lo que necesita, un C&C dentro de una malla deja de ser un problema de detección y pasa a ser un problema de permiso denegado.

nft add set inet allowed_egress '{ type ipv4_addr; }'
nft add element inet allowed_egress '{ 10.0.0.10, 10.0.0.11 }'
nft add rule inet filter output ip daddr @allowed_egress accept
nft add rule inet filter output ip daddr 0.0.0.0/0 reject

El orden de las reglas importa en nftables: la regla de aceptación debe ir antes que la de rechazo genérico, y conviene verificar el resultado antes de activar el conjunto en la cadena de producción.

nft list chain inet filter output
nft list ruleset | grep -E 'ygg_peers|allowed_egress'

Endurece el host sin cambiar la arquitectura

El vector de entrada en este caso fue un adjunto de spearphishing. En un servidor Linux el equivalente operativo no es un antivirus, sino una política: lo que llega desde correo no se ejecuta, y los directorios temporales no admiten ejecución ni elevación de privilegios.

mount | grep -E ' on /(tmp|var/tmp) '
findmnt -no OPTIONS /tmp
findmnt -no OPTIONS /var/tmp

Si el resultado no incluye noexec ni nosuid, el montaje se puede endurecer sin tocar la aplicación, con una entrada propia en el fstab. El mismo criterio aplica a los archivos ocultos con punto inicial: si el estándar de la organización es que /tmp no se use para persistir nada, la opción nodev,nosuid,noexec reduce la superficie completa.

Y queda el punto más básico de todos, el que un operador con prisa salta: este ataque no usó ninguna vulnerabilidad. Fue phishing, herramientas legítimas de Windows usadas para el mal y una ventana de dos meses. Ninguna de esas piezas se arregla con un parche.

Lo que este caso no significa

Conviene cerrar con los límites, porque la cobertura de prensa tiende a estirarlos. Yggdrasil no es una red anónima y MythicRatatoskr no es una amenaza masiva: ESET no ha visto el backdoor en ningún otro entorno. No hubo ransomware, hubo borrado con SDelete. El actor primario fue UAC-0099. Y el indicio de una variante Linux existe, pero ESET dice que encontró indicios, no una confirmación: nadie ha descrito públicamente un despliegue sobre un host Linux de MythicRatatoskr.

Lo que sí queda es un patrón reproducible. Un grupo de espionaje obtiene acceso con phishing, deja su kit, traspasa la intrusión a un actor destructivo, y entre ambos pasos pasan dos meses. Los controles que marcan la diferencia no son exóticos: registro de auditoría sobre authorized_keys y sshd_config, visibilidad del tráfico saliente por proceso, lista blanca de egreso, bloqueo del rango 200::/7 y montajes temporales sin ejecución. Todo eso se puede aplicar esta tarde en un servidor que ya está en producción.

ESET presentó los hallazgos en LABScon el 18 de septiembre de 2026 y en Virus Bulletin el 16 de octubre de 2026. El informe técnico completo, con la lista de nodos pares y el análisis de la configuración cifrada, está en el blog de WeLiveSecurity.

Preguntas frecuentes

¿Yggdrasil sirve para ocultar el tráfico del atacante?

No. ESET lo dice de forma explícita: el anonimato no está entre los objetivos del proyecto. Lo que Yggdrasil aporta es resiliencia, porque no existe un servidor central que pueda tumbarse. Eso sí tiene una consecuencia práctica: la dirección del C&C está embebida en el malware y ESET la publica como indicador de compromiso, de modo que se puede bloquear aunque no se pueda reportar por hostname. Lo que rota en cada ejecución es la dirección del host infectado, porque genera una clave nueva al arrancar.

¿Hay evidencia de que MythicRatatoskr se usó en servidores Linux?

No hay confirmación, solo indicios. ESET encontró dos pistas: la ruta de configuración %LocalAppData%/Temp/.crond escrita con barras inclinadas hacia adelante, que es un error de los atacantes y un path de Unix, y el hecho de que todos los archivos de configuración empiecen con punto, algo que en Unix oculta archivos y en Windows no. El código basado en yggstack, que no necesita crear interfaz de tunnel, refuerza la hipótesis de portabilidad. Ninguna de esas señales equivale a un despliegue confirmado.

¿Cómo se distingue un movimiento lateral por SFTP de una transferencia legítima?

Por contexto, no por la conexión en sí. Un servidor SFTP de OpenSSH es una herramienta normal, así que la señal aparece al correlacionar tres datos: el horario de la sesión frente al turno del operador, el origen de la conexión y el estado del authorized_keys de la cuenta destino. Si las tres cosas no cuadran, conviene revisar si la clave se agregó desde un origen esperado. En un incidente real la evidencia decisiva suele ser el authorized_keys con fecha de modificación posterior al inicio de la intrusión.

¿Bloquear las IPs de los nodos pares basta para proteger un servidor?

Es una medida útil, no completa. La lista de ESET tiene 32 entradas, de las cuales 10 son IPv4, 21 son nombres de dominio y una es IPv6, y varias usan puertos no estándar: un bloqueo estático sobre el subconjunto IPv4 no cubre el resto. El control que se sostiene es la lista blanca de egreso, reforzada con el rango 200::/7 bloqueado por completo. Si el servidor solo puede hablar con destinos conocidos, un C&C dentro de una malla falla por permiso denegado en lugar de pasar desapercibido.

¿El borrado de datos hubiera sido evitable con parches o firewall?

No directamente, porque este ataque no explotó ninguna vulnerabilidad. El punto de entrada fue un correo de spearphishing con adjunto malicioso, y el borrado se ejecutó dos meses después con herramientas legítimas de Windows desplegadas por Group Policy de Active Directory. Lo que reduce el impacto es la detección temprana y la limitación de privilegios: auditoría sobre archivos de configuración de SSH, visibilidad del tráfico saliente, montajes temporales sin ejecución y una separación real entre el equipo que entra y el equipo que borra.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *