java安全 fastjson反序列化基础分析

admin 2022年4月6日01:55:47评论39 views字数 3419阅读11分23秒阅读模式
fastjson反序列化基础分析
java安全 fastjson反序列化基础分析

本文主要来讲解fastjson反序列化内容。
依赖包如下:

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.24</version></dependency>

在学习该漏洞之前,先整点前置知识。贴出一个User类。主要来发现fastjson的几个小特性

public class User {
public String name;public User() {
System.out.println("构造函数...");}public String getName() {
System.out.println("调用了get方法");return name;}
public void setName(String name) {System.out.println("调用了set方法");this.name = name;
}@Overridepublic String toString() {return "User{" +"name='" + name + ''' +'}';}}

在进行toJSONString()的时候,可以发现会调用到get方法。(切记 构造函数和set方法是初始化和赋值时调用)
java安全 fastjson反序列化基础分析
Object obj = JSON.parseObject(res,User.class);//返回JSONObject 如果加上User.class则是
User类型

Object obj2 = JSON.parse(res);//返回类 UserSystem.out.println(obj.getClass().getName());System.out.println(obj2.getClass().getName()

);

可以看到在使用parseObject进行反序列化之后,会调用到set方法。而parse没有调用


java安全 fastjson反序列化基础分析

在了解完基础用法之后,我从网上找了一段解释的比较专业的一段话:
为了让开发者更加方便的使用Fastjson的一系列功能,同时也为了方便自省,Fastjson设计了一个叫autoType的功能,也就是网上常⻅的 @type 。
只要JSON字符串中包含 @type ,那么 @type 后的属性,就会被当做是 @type 所指定的类的属性,从而在不传递第二个参数的情况下让Fastjson明确要还原的类。


这是什么意思呢?相信很多小伙伴们复现过fastjson这个漏洞,而下方这条代码,是不是非常像你用到的
“Payload”。用通俗的话来理解,这是一个用来被反序列化的东西,@type后面指定的是类名。
cmd指的是该类的属性,calc为属性的值。

{"@type":"com.example.fastjson.Evil","cmd":"calc"}";


既然有了前面的知识铺垫,接下来准备一个恶意类,该类的set方法会传递参数进去,并通过
Runtime执行

public class Evil {
String cmd;String a;
public Evil(){}
public String getCmd() {
System.out.println("get方法");
return cmd;
}
public void setCmd(String cmd) throws IOException {
System.out.println("set方法");
this.cmd = cmd;Runtime.getRuntime().exec(cmd);}public void setA(String a) throws IOException {Runtime.getRuntime().exec(a);}}


前面知道了parseObject会调用到set方法。那么就给该方法传个值吧

{"@type":"com.example.fastjson.Evil","cmd":"calc"}

在反序列化之后,可以看到成功执行了命令

java安全 fastjson反序列化基础分析

基础的玩法是远远不够的,接下来更深一层的看是如何调用set方法的?
跟进parseObject方法中会调用到parse方法中,在跟进之后会调用到DefaultJSONParser类中

java安全 fastjson反序列化基础分析

在DefaultJSONParser类中发现设置token=12,这个后面会用到,先记住
当再几次F8就会调用到DefaultJSONParser类中的parse方法。
这里的token就是刚才赋值的那个,为12

java安全 fastjson反序列化基础分析

java安全 fastjson反序列化基础分析

java安全 fastjson反序列化基础分析

跟进parseObject方法,前面代码比较多,直接跟到162行的while处
java安全 fastjson反序列化基础分析单步跟进162行,是对一些r n t f 空格等进行不解析
java安全 fastjson反序列化基础分析

继续分析,ch此时为单引号,剧透一下,其实就是"@type" 最前面的这个单引号。
之后会判断是否开启了AllowArbitraryCommas,如果开启了,就会进入到后面的while
而while则是对"逗号,"进行忽略。所以此处是可以对某些waf进行绕过的。
假设某waf只会校验前几个字符,如果为@type就凉拌掉,所以此时将payload写为

{,,,,,,"@type":"com.example.fastjson.Evil","cmd":"calc"}


java安全 fastjson反序列化基础分析

在下方会获取到@type,scanSymbol会将获取目前的字符以及到第二个参数为止的字符中间的内容获取"@type" 也就是@type

java安全 fastjson反序列化基础分析

在274行中,会判断key是否为@type以及DisableSpecialKeyDetect是否开启
java安全 fastjson反序列化基础分析

稍后就会生成一个Class类。ref则是Evil这个恶意类

ref = lexer.scanSymbol(this.symbolTable, '"');Class<?> clazz = TypeUtils.loadClass(ref, this.config.getDefaultClassLoader());

java安全 fastjson反序列化基础分析

最终在318行跟进

ObjectDeserializer deserializer = this.config.getDeserializer(clazz);

跟进后发现,这里进行了一层校验,如果为Thread则会异常

java安全 fastjson反序列化基础分析继续跑到411行,执行了createJavaBeanDeserializer

java安全 fastjson反序列化基础分析

跟进createJavaBeanDeserializer发现了480行的build方法

java安全 fastjson反序列化基础分析

而该方法会获取属性和方法。

java安全 fastjson反序列化基础分析

在继续往后跑,后面会有个重要点,这里贴出一部分
可以看到if处:

  • 方法名长度不能小于4

  • 不能是静态方法

  • 返回的类型必须是void 或者是自己本身

  • 传入参数个数必须为1

  • 方法开头必须是se

for(i = 0; i < var29; ++i) {
method = var30[i];ordinal = 0;int serialzeFeatures = 0;parserFeatures = 0;String methodName = method.getName();if (methodName.length() >= 4 && !Modifier.isStatic(method.getModifiers()) &&(method.getReturnType().equals(Void.TYPE) ||method.getReturnType().equals(method.getDeclaringClass()))) {Class<?>[] types = method.getParameterTypes();if (types.length == 1) {
annotation = (JSONField)method.getAnnotation(JSONField.class);if (annotation == null) {
annotation = TypeUtils.getSuperMethodAnnotation(clazz, method);}if (annotation != null) {
if (!annotation.deserialize()) {continue;}

当执行完成build之后,beanInfo则会存储该类的一些信息。

java安全 fastjson反序列化基础分析

最后跑完这个方法之后,会执行deserializer.deserialze方法。而该类无法断点跟进,前辈们师傅说是ASM机制生成的临时代码,所以跟不了断点

java安全 fastjson反序列化基础分析

直接放行即可,就会自行调用到set处
java安全 fastjson反序列化基础分析

关注公众号

公众号长期更新安全类文章,关注公众号,以便下次轻松查阅


原文始发于微信公众号(moonsec):java安全 fastjson反序列化基础分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月6日01:55:47
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   java安全 fastjson反序列化基础分析https://cn-sec.com/archives/870238.html

发表评论

匿名网友 填写信息