RASP | FastJson反序列化漏洞回顾
2022-5-29 15:22:58 Author: mp.weixin.qq.com(查看原文) 阅读量:10 收藏

    与原生的Java反序列化的区别在于,FastJson反序列化并未使用

ObjectInputStream.readObject()方法,而是由FastJson自定一套反序列化的过程。通过在反序列化的过程中自动调用类属性的setter/getter方法,将JSON字符串还原成对象,当这些自动调用的方法中存在可利用的潜在危险代码时,漏洞便产生了。

  1. FastJson反序列化漏洞的演变历程

  • 自从2017年爆出FastJson1.2.24版本反序列化漏洞后,近几年安全人员在不断寻找新的利用方式。

  • 自FastJson1.2.25版本开始,FastJson关闭了默认开启的AutoType,并且内置了一个黑名单,用于防止存在风险的类进行序列化。

  • 由于FastJson 1.2.41版本和1.2.42版本对类名处理不当,导致黑名单机制被绕过,在修复该漏洞的同时还将黑名单进行加密,增加了研究成本。

  • 在FastJson1.2.45版本中,研究人员发现新的可利用的类,且不在黑名单中。

  • 在FastJson1.2.47版本中,研究人员发现通过缓存机制,能够绕过AutoType的限制和黑名单机制。

  • 在2020年,FastJson1.2.68版本又被发现新的绕过AutoType的方式,也是通过缓存的方式绕过,但具体成因的代码逻辑有些差异,利用难度也较先前版本更大。

  • 在2022年5月,FastJson1.2.80版本又被发现新的绕过AutoType的方式。

    从上述FastJson反序列化漏洞可以看出漏洞利用主要集中在如下的2个方面。

  • 寻找新的利用链,绕过黑名单;

  • 寻找绕过AutoType的方式;

2.  FastJson反序列化漏洞的基础

FastJson将JSON还原成对象的方法有以下3种。

parse(String text);parseObject(String text);parseObject(String input, Class clazz);

    当通过这3种方法将JSON还原成对象时,FastJson自动调用类中的setter方法和无参构造函数,以及满足条件的getter方法。当类中定义的属性和方法满足下列要求时,FastJson会自动调用getter方法。

  1. 只存在getter方法,无setter方法;

  2. 方法名称长度大于等于4;

  3. 非静态方法;

  4. 方法名以get开头,且第四个字符为大写字母,例如getAge;

  5. 方法无须人参;

  6. 方法返回值继承自Collection、Map、AtomicBoolean、AtomicInteger和

AtomicLong的其中一个;

FastJson 1.2.24 下的PoC 如下:

import com.alibaba.fastjson.JSON;
import java.util.Properties;
public class User { public String name; private int age; private Boolean sex; private Properties properties; public User() { System.out.println("无参构造函数调用"); } public int getAge() { System.out.println("age的getter方法调用"); return age; } public void setAge(int age) { System.out.println("age的setter方法调用"); this.age = age; } public Properties getProperties() { System.out.println("properties的getter方法调用"); return properties; } public void setName(String name) { System.out.println("name的setter方法调用"); this.name = name; } public String getName() { System.out.println("name的getter方法调用"); return name; } public void setSex(Boolean sex) { System.out.println("sex的setter方法调用"); this.sex = sex; } public Boolean getSex() { System.out.println("sex的getter方法调用"); return sex; } public static void main(String[] args) { String jsonstr = "{\"@type\":\"User\",\"sex\":true,\"name\":\"Yu\",\"age\":18,\"properties\":{}}"; Object obj = JSON.parse(jsonstr); }}

PoC执行结果:

    parseObject(String text)方法将SON申还原成对象后,后会调用一次getter方法,类中所有的getter方法都会被执行一次,如下图所示:

3. checkAutoType 安全机制

    FastJson1.2.25版本中引人了checkAutotype,其中增加了黑白名单的校,验,缓解反序列化需洞的产生,后续版本将内置的黑白名单进行加密,增加了绕过黑白名的研究成本。

    com.alibaba.fastjson.parser.ParserConfig 加入了CheckAutoType方法,在其中有个 autotypeSupport 属性,如果为 false,那么就会检测json中@type的值 开头是否与黑名单中的值一样,若一样就直接返回一个异常,然后加载白名单中的类。

黑名单长这样:

CheckAutoType() 部分代码

若autotypesupport开启,则会先白名单加载,后黑名单检测

    后面的许多更新都是对 checkAutotype 以及本身某些逻辑缺陷导致的漏洞进行修复,以及黑名单的不断增加。

4. RASP 防御

1.2.47 版本的漏洞利用与RASP 防御

复现参考:https://mp.weixin.qq.com/s/A0X3nCq9w4BAlGPCN-jH5Q

受到漏洞影响的服务注册到管理端:

发起攻击后查看日志:

攻击详情:

调用栈:

业务层面影响:请求被阻断

    说明:1.2.80版本的绕过问题,rasp 理论上都可以检测到,由于绕过poc构造难度大,并且没有公开的资料,这里没有复现。

官网:http://www.jrasp.com

github:https://github.com/jvm-rasp/jrasp-agent

加入技术交流群请添加微信:sear2022


文章来源: https://mp.weixin.qq.com/s?__biz=Mzg5MjQ1OTkwMg==&mid=2247484289&idx=1&sn=930cc2e69426762372824dadfc66ea02&chksm=c03c8d90f74b0486e4b3d2f838407d3c437d7bc999a4c8617adc7aab4b37fedc8125abafa4b3&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh