
[CVE-2022-41828] Amazon AWS Redshift JDBC Driver Remotecodeausführung (RCE)
Der Amazon JDBC-Treiber für Redshift ist ein Type 4 JDBC-Treiber, der Datenbankkonnektivität über die standardmäßigen JDBC-Anwendungsprogrammierschnittstellen (APIs) bereitstellt, die in der Java Platform, Enterprise Edition verfügbar sind. Der Treiber ermöglicht den Zugriff auf Redshift von jeder Java-Anwendung, jedem Anwendungsserver oder Java-fähigen Applet aus.
Ein potenzielles Problem der Remote-Befehlsausführung besteht in redshift-jdbc42 Version 2.1.0.7 und darunter. Wenn Plugins mit dem Treiber verwendet werden, instanziiert er Plugin-Instanzen basierend auf Java-Klassennamen, die über die Verbindungseigenschaften sslhostnameverifier, socketFactory, sslfactory und sslpasswordcallback bereitgestellt werden. In betroffenen Versionen überprüft der Treiber nicht, ob eine Plugin-Klasse vor der Instanziierung die erwartete Schnittstelle implementiert. Dies kann zum Laden beliebiger Java-Klassen führen, die ein kenntnisreicher Angreifer mit Kontrolle über die JDBC-URL nutzen kann, um Remote Code Execution zu erreichen.
Dieses Problem ist in redshift-jdbc-42 Version 2.1.0.8 und höher behoben.
AWS empfiehlt Kunden, die Plugins verwenden, ein Upgrade auf redshift-jdbc42 Version 2.1.0.8 oder höher durchzuführen. Es sind keine bekannten Workarounds für dieses Problem bekannt.
Um dieses Problem zu beheben, wurden in 4 verschiedenen Java-Klassen im Commit aws/amazon-redshift-jdbc-driver@9999659 Änderungen vorgenommen. Diese Klassen sind wie folgt.
@@ -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) {

Um CVE-2022-41828 zu reproduzieren, wird eine angreifbare Java-Anwendung mit Spring Framework entwickelt, die den verwundbaren Treiber redshift-jdbc42 in Version 2.1.0.7 als externe Bibliothek verwendet.