Arkham — Hackthebox Writeup
Arkham is a Medium-difficulty box that I picked up in order to get familiar with deserialisation vulnerabilities for the OSWE exam.
Nmap shows that IIS 10.0 is running and SMB is open. I check out port 80 and see the default IIS page.
Gobuster doesn’t find any directories at first, so I assume that there’s a virtual host to find and check out SMB.
Anonymous access appears to be enabled for the “BatShare” share. I find and download a file called “appserver.zip”.
Inside the archive I find a note and a LUKS encrypted image file.
I don’t find any more information about a virtual host or what the LUKS password could be, so I use a tool called “bruteforce-luks” to try and crack the password.
Hackthebox creators usually don’t make password cracking that bad since it isn’t very fun, so I guess that the password is in rockyou.txt and grep out a wordlist containing the words “batman”, “joker”, “robin” to start with.
I haven’t taken the time to learn how to give my Kali VM access to the GPU so trying to crack LUKS encryption is very slow. Luckily the password is in the first hundred lines of the list.
I mount the image and decrypt it, and find some images, the script of “Batman Begins”, and a directory called “tomcat-stuff” which contains what I assume to be the web server’s configuration files.
In “server.xml” I find out about port 8080. I don’t know why my first scan didn’t find it since 8080 is in nmap’s default set of ports, but make a mental note about not being lazy with nmap in the future and move on.
In “web.xml.bak” I find the algorithm that the server uses and the HMAC signing key. I also see that the viewstate is saved on the server. I’ve done a few JWT challenges in CTFs before so I think I know what’s going to happen, but I’m still waiting to encounter the deserialisation issue.
I check port 8080 next and find the website for a company named “Mask”.
There isn’t much on the website to interact with except the “Subscription” button which takes me to “http://arkham.htb:8080/userSubscribe.faces”.
I enter “batman@arkham.htb” into the “Sign Up” box and see a confirmation page. I spend a while looking for a reflected XSS vulnerability but am not successful. Viewstates are involved anyway so it’s not like I can send an “admin” an XSS link, either.
I notice that the “Subscribe to us” page contains parameters which my browser sent to the server as POST data.
The base64 stands out, so I decode it but find that the base64 decoded data is non-printable. I assume that this means the data is serialised and encrypted with the key we found earlier.
I spend some time looking for code/SQL injection vulnerabilities in the other parameters, but I already knew Arkham was about deserialisation so I give up on that.
From the archive I found earlier, I can assume that the Tomcat is the webserver which runs on Java. So I install ysoserial which I’ll use to serialise my payloads.
I spend a couple of hours trying to decrypt the value of the “javax.faces.ViewState” parameter, but am unsuccessful. I do some more reading about HMAC and find that it is as similar to JWT as I suspected. I also find a page that tells me everything I need to know to get RCE on the server.
After the attacker has sent his modified form back to the server the JSF implementation tries to deserialize the provided ViewState. Now even before the deserialization of the ViewState has ended the command is executed and the calculator is started on the server.
I see that ysoserial supports 7 “CommonsCollections” payloads, so I use number 7 to generate a serialised object for the code that I want the server to run.
I save it in a file and begin writing a Python script which will:
- Generate a serialised object for the command I want the webserver to run
- Encrypt the payload with the key we found, and generate an HMAC hash
- Add the two pieces together and send the POST request to hopefully get RCE
Unfortunately I wasted 2 hours trying to capture stdout for the ysoserial subprocess, and give up and just do that part manually beforehand. The heavy usage of the “print” function shows how much tinkering was required to get it to work.
I always do a simple pingback to confirm RCE first, because I often run into character escaping issues with more complicated payloads and don’t know if I don’t have RCE, or just messed up my command. I set tcpdump to listen for ICMP packets and run my script.
It feels great to see those packets! I set up a netcat listener on port 1337 of course, and then exploit the vulnerability twice more to send nc.exe over and use it to send myself a reverse shell. I call it abc.exe just in case somebody else is working on the same machine.
I land on the box as ARKHAM\Alfred and find the user flag.
I don’t get any privesc leads from WinPEAS.exe, but in Alfred’s Downloads folder I find a folder containing a zip file. I send that back to my machine and find an Outlook mailbox file inside.
There’s a tool called “readpst” that comes with the “libpst4” library. I use it to convert the mailbox to Thunderbird’s format, and have trouble importing it into Thunderbird.
I try letting my OS open it however it wants, and find that mbox files are human readable. In LibreOffice I see an email with a base64 encoded attachment called “image001.png” at the bottom of the file.
Just as the email said, it’s a PNG file.
The image contains Batman’s password and a share that I can try to access.
I try to follow the image but am not able to. I’m much more comfortable with a shell than runas shenanigans so I get one with Powershell.
I’m really glad that I decided to send nc.exe over.
Batman doesn’t have any interesting folders in his home directory, but he is in the “Administrators” group. I’m not able to access the “Administrator” home folder where I believe the root flag will be though.
As an Administrator, Batman can probably get SYSTEM privileges by manipulating service paths/binaries, but I try to find the “gotham” share from image001.png earlier.
There’s no such share with that name, but then I remember the other share that Administrators can use. I change to the mounted drive and get the root flag.
Privesc was very CTF-like, but the foothold for this box was fantastic and I enjoyed my first experience with a deserialisation vulnerability.
I need to move on to cover more OSWE content, but if I had more time I’d find out why I was unable to deserialise the objects provided by the application.
Putting a blue team hat on, the following problems should be addressed:
- Anonymous share access enabled. (I’ve never seen this in a pentest so it mustn’t be a default setting)
- Web server configuration accessible via SMB, even if it did require authentication. (I’ve actually encountered this multiple times, except the files were even easier to obtain)
- The encryption key needs to be changed now, as it was previously exposed.
- The plaintext password in an image was pretty dumb, but I’ve probably seen credentials laying around on more pentests than not.
- I have no idea how the ACLs work where that was possible. Maybe accessing c$ gives you SYSTEM privilege or similar?
From a normal shell:
PS C:\Users> icacls Administrator\
icacls : Administrator\: The handle is invalid.
At line:1 char:1
+ icacls Administrator\
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Administrator\: The handle is invalid.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Successfully processed 0 files; Failed processing 1 files
From the mounted drive through c$:
S:\Users>icacls Administrator
icacls Administrator
Administrator NT AUTHORITY\SYSTEM:(OI)(CI)(F)
BUILTIN\Administrators:(OI)(CI)(F)
ARKHAM\Administrator:(OI)(CI)(F)