长亭百川云 - 文章详情

RASP | FastJson反序列化漏洞回顾

RASP安全技术

50

2024-07-13

    与原生的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

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2