MySQL JDBC Attack

0x01 JDBC Deserial

JDBC(Java DataBase Connectivity)是SUN公司发布的一个java程序与数据库之间通信的接口(规范),各大数据库厂商去实现JDBC规范,并将实现类打包成jar包

image-20230123013436497

进行数据库连接时指定了数据库的URL及连接配置

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root", "root");

若JDBC连接的URL被攻击者控制,就可以让其指向恶意的MySQL服务器

JDBC连接MySQL服务端时,会有几个内置的SQL查询语句会执行,查询的结果集会在MySQL客户端被处理时会调用ObjectInputStream#readObject进行反序列化。

攻击者可以搭建恶意MySQL服务器,返回精心构造的查询结果集,进行客户端反序列化攻击。

可被利用的两条查询语句:

  • SHOW SESSION STATUS

  • SHOW COLLATION

恶意MySQL服务器搭建:

  • https://github.com/fnmsd/MySQL_Fake_Server 📌

  • https://github.com/rmb122/rogue_mysql_server

DriverManager#getConnection

👇

connectOneTryOnly=>this.session.setQueryInterceptors(this.queryInterceptors);

设置对应的查询拦截器(即我们指定的ServerStatusDiffInterceptor

执行查询语句会调用拦截器的preProcesspostProcess

判断拦截器是否为空,非空则调用invokeQueryInterceptorsPre

image-20230328204414675

invokeQueryInterceptorsPre调用了拦截器的preProcess

image-20230328204534640

看到执行了SHOW SESSION STATUS,并将结果(com.mysql.cj.jdbc.result.ResultSetImpl)传入ResultSetUtil#resultSetToMap进行反序列化处理

image-20230328204912985

getObject判断MySQL类型为BLOB后,从MySQL服务端获取对应的字节码数据

从MySQL服务端获取到字节码数据后,判断autoDeserialize是否为true(连接URL中设置了autoDeserialize=true)、字节码数据是否为序列化对象(前两个字节为-84-19标识序列化对象)等,最后调用readObject触发反序列化漏洞

image-20230328215913350
image-20230328215340798

0x02 Payload Collections

ServerStatusDiffInterceptor触发

8.x<=8.0.20

6.x

queryInterceptors改名statementInterceptors

>=5.1.11

包名不含cj

5.x<=5.1.10

同上,需要连接后执行查询

detectCustomCollations触发

5.1.29~5.1.40

5.1.19~5.1.28

0x03 Reference

Last updated

Was this helpful?