
[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 وsslpasswordcallback. في الإصدارات المتأثرة، لا يتحقق البرنامج مما إذا كانت فئة الإضافة تنفذ الواجهة المتوقعة قبل الإنشاء. قد يؤدي ذلك إلى تحميل فئات Java عشوائية، يمكن لمهاجم مطلع يتحكم في عنوان JDBC URL استخدامها لتحقيق تنفيذ التعليمات البرمجية عن بعد.
تم إصلاح هذه المشكلة في الإصدار 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>