0

I'm trying to access the deserialize static method within the hsqldb (2.5.1) InOutUtil class. When I run it, java -cp hsqldb.jar:. testcode

I get:

java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: org.hsqldb.lib.InOutUtil.deserialize
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.JDBCStatement.execute(Unknown Source)
    at testcode.main(testcode.java:58)
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: org.hsqldb.lib.InOutUtil.deserialize
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.result.Result.getException(Unknown Source)
    ... 4 more

Code:

...

connection = DriverManager.getConnection(dburl, "sa", "");
statement = connection.createStatement();
statement.execute("call \"java.lang.System.setProperty\"('org.apache.commons.collections.enableUnsafeSerialization','true')");
statement.execute("call \"org.hsqldb.lib.InOutUtil.deserialize\"('" + my_object +"');");
    
...

This is the offending line that throws the exception:

statement.execute("call \"org.hsqldb.lib.InOutUtil.deserialize\"('" + my_object +"');");

What I'm trying to do is reproduce this exploit, https://github.com/Critical-Start/Team-Ares/tree/master/CVE-2020-5902, on a local instance of hsqldb.

Not sure what I'm doing wrong. Thanks!

Matt
  • 1,053
  • 4
  • 14
  • 29
  • The first method is not allowed for security. The second method is for internal use and it's not possible to call it directly. Can you add to your question and explain what you want to achieve. – fredt Jul 09 '20 at 17:50

2 Answers2

0

The exploit you linked to refers to HSQLDB version 1.8.0 which has been obsolete since the release of version 2.0 in 2010. However, aspects of the the security framework remain the same up to the latest version of HyperSQL.

  1. A database user with even the DBA credentials cannot execute any arbitrary static method that happens to be in the classpath of the database server. A sysadmin who starts the database server can issue an allow-list of the specific static methods that are allowed to run as callable procedures, using the hsqldb.method_class_names Java System property with the list. See: http://hsqldb.org/doc/2.0/guide/sqlroutines-chapt.html#src_jrt_access_control

  2. The listed safe static methods can then be turned into SQL callable procedures only by DBA credentials. EXECUTE privileges on the procedures are granted by the DBA.

  3. Versions 2.x of HyperSQL generally improve upon the older security framework, for example allows secure password hash algorithms, password check and retention policies, including external authentication via LDAP and other frameworks.

fredt
  • 24,044
  • 3
  • 40
  • 61
0

You may succeed if you "try harder" and find the way HSQLDB expects parameter type definitions.

With HSQLDB 2.7.1 the maintainer's answer is enforced by either the absence or the presence of the server's system property (in addition to the connecting user's privilege needed to execute procedures). The server requires an explicit permission in its own Java properties such as -Dhsqldb.method_class_names="org.hsqldb.lib.StringConverter.*". (Using just the class name did not enable its static methods for me).

$ java -jar ~/hsqldb-svn-trunk/lib/sqltool.jar --inlineRc="url=jdbc:hsqldb:hsql://localhost/test,user=sa,password=" --sql="CALL \"org.hsqldb.lib.StringConverter.getUTFSize\"('java.class.path');"
 15

With older HSQLDBs (or with a dangerously wide class name permission in 2.7.1), the only hurdle is to correctly declare the Java method's parameter types. I already figured that byte corresponds to TINYINT. I just need to learn the array mapping.

$ nl=$'\n'; java -cp ~/hsqldb-svn-trunk/lib/sqltool.jar org.hsqldb.cmdline.SqlTool --inlineRc="url=jdbc:hsqldb:hsql://localhost/test,user=sa,password=" --sql="CREATE FUNCTION TEST (BINARY) RETURNS BINARY NO SQL LANGUAGE JAVA EXTERNAL NAME 'CLASSPATH:org.hsqldb.lib.InOutUtil.deserialize';${nl}.;"
Feb 14, 2023 2:29:58 PM org.hsqldb.cmdline.SqlTool objectMain
SEVERE: SQL Error at '--sql' line 2:
"CREATE FUNCTION TEST (BINARY) RETURNS BINARY NO SQL LANGUAGE JAVA EXTERNAL NAME 'CLASSPATH:org.hsqldb.lib.InOutUtil.deserialize';"
user lacks privilege or object not found: org.hsqldb.lib.InOutUtil
org.hsqldb.cmdline.SqlTool$SqlToolException
eel ghEEz
  • 1,186
  • 11
  • 24
  • Thanks to your reference to CVE-2020-5902 and Internet Archive, I could dig [Mikhail Klyuchnikov's exploit](http://web.archive.org/web/20220620155351/https://swarm.ptsecurity.com/rce-in-f5-big-ip/) that took advantage of the permission to call arbitrary static methods. He demonstrated planting a reverse shell in a security appliance. – eel ghEEz Feb 15 '23 at 17:16