HackTheBox : Usage

0liverFlow
11 min readJan 12, 2025

--

Usage is a Linux box that features a website vulnerable to SQL injection, which allows the administrator’s hashed password to be dumped and cracked. This leads to access to the admin panel, where an outdated Laravel module is abused to upload a PHP web shell and obtain remote code execution. On the machine, plaintext credentials stored in a file allow SSH access as another user, who can run a custom binary as root. The tool makes an insecure call to 7zip, which is leveraged to read the root user’s private SSH key and fully compromise the system.

Reconnaissance

Nmap

TCP full scan
UDP scan
Open ports

SSH — TCP/22

Here, we will quickly scan ssh by using ssh-audit :

Auditing SSH

The server seems to be secured.

HTTP — TCP/80

First and foremost, let’s take a quick look at the website :

Usage main page

This is a login page. From here, we can already think of attack vectors such as authentication bypass via SQLi or login brute forcing.

Technology Profiling

Web technologies

We can notice the following information from the output above :

  • The target is running Nginx/1.18.0 on Ubuntu
  • It is also using Laravel which is a PHP framework

Nikto scan

One thing I generally do is to launch nikto on the website while looking for entry points :

Nikto scan

Here is a quick breakdown of the command :

  • -h : specifies the host to target
  • -Tuning 123b : specifies the tests that nikto will run against the target. Here I tell nikto to look for interesting files (1), misconfigurations (2), information disclosure (3), and software identification (b).
  • -F : specifies the output format (html)
  • -o : specifies the output file

Nikto did not return any stunning information except the /login directory which we discovered earlier.

File and directory fuzzing

Let’s first see if there is a robots.txt file before fuzzing the website for files and directories :

Checking for robots.txt file

A robots.txt was found. Here is its content :

robots.txt content

Unfortunately, there is nothing really interesting from this output. Therefore, let’s keep on our enumeration with ffuf :

File/Directory fuzzing

Well, the output showed no interesting information. Let’s move on with virtual host fuzzing.

Vhost fuzzing

Vhost fuzzing

Great ! A virtual host was found : admin.usage.htb

Admin login page

This is the admin login page.

Well, we found out two login pages but no credentials to login.

Nevertheless, there is a website that we did not check out and this is the registration page. Let’s give it a try :

Creating a new account

Here is the page where we land once we log in with our created account :

Well, let’s take a look at the “Reset Password” feature to see what we can find :

As you can see, when we enter an existed email address, we get the following message. However, when the email does not exist we get this error message :

This can be leveraged to enumerate valid email addresses, then perform a dictionary attack. However, the issue here is that the email address has no defined nomenclature that all users should use. Indeed, the only requirement is the format of the email address. Therefore, I will go for SQLi vulnerabilities.

Testing for basic SQLi

In this section, we are going to test basic SQLi payloads on the four webpages identified earlier and see how they respond. If we detect nothing, we will then use sqlmap to perform advanced SQLi.

I tried these payloads : a single quote ' and ' or 'a'='a';-- - for the email address input. I didn’t test the password input because that input will be generally hashed by the web server so there is no need to test injections for that field.

And guess what ? The “Reset Password” page seems to be vulnerable to an SQLi.

Indeed, when I used a single quote as a payload, I got this error message :

Potential SQLi

Well, let’s intercept the request with Burp, then copy it into a file and performs more advanced injection with sqlmap.

sqlmap output

Based on sqlmap output, we can confirm that the email parameter is indeed vulnerable to a boolean based SQLi. Let’s now extract data from the database.

information_schema and performance_schema are MySQL default databases. Therefore, let’s enumerate the tables of the usage_blog database :

Interesting ! Let’s take a look at the columns of the table admin_users as well as the number of entries :

Great ! Let’s retrieve the name, username and password information from this table :

Well, we obtained the administrator’s password hash. Therefore, let’s first perform a rainbow table attack using search-that-hash (sth) :

Unfortunately, we found no credentials related to our hash.

Let’s now try to crack the hash using hashcat. However, let’s first of all identify the type of hash using the hashcat’s --identify option :

Once the hash type identified, let’s crack it using this command :

hashcat -m 3200 -a 0 admin.hash /usr/share/wordlists/rockyou.txt

Hash successfully cracked

Initial Access

Let’s authenticate to the administrator account using the cracked password :

Login successful

Though we got access to the admin page, we have not got yet an initial access to the target machine. Therefore, we need to find a way to get that access.

As you can see, the web server is using PHP 8.1.2 and Laravel 1.8.17.

You can find the version of Laravel at the very bottom of the webpage :

Well, let’s see if these versions have some public known vulnerabilities.

Indeed, there is a vulnerability in larravel-admin that allows attackers to bypass file upload restrictions by uploading files in *. php format for remote code execution. Here is a PoC of this vulnerability :

Great ! Let’s exploit this vulnerability to get a remote code execution :

1/ Go to the “user settings” and try to modify the user’s avatar then save it, and intercept the requested data with Burp :

user.txt

Privilege Escalation

In this section, we will try to escalate our privileges.

To start, let’s enumerate the local files on dash’s home folder :

Password found in .monitrc

Excellent ! We found a password in .monitrc.

Let’s check if this password was reused by other users on the system.

To do that, let’s firstly enumerate the users with a console :

Users with a console

We can then proceed with checking where we can authenticate with the password found above :

Authentication failed for dash
Authentication failed for root
Authentication succeeded for xander

Wonderful ! The authentication succeeded for the user xander.

From that access, we can see that we have the ability to execute a program named usage_management as root without specifying any password :

Let’s try to leverage that to escalate our privileges :

This is a binary file and we have no write permission over it.

Knowing that we have a binary, we can try to extract strings from it using the strings command :

Extracting strings from the binary

Great ! This gives us an idea of what the binary does.

Let’s try to execute it :

Executing the binary

Once executed, the binary gives us the choice to choose between three options: backup the project, backup the MySQL data or reset the admin password. I tried the third and second option but landed nowhere. Finally, I gave a shot to the first option. Indeed this option will create a backup of all the files located at /var/www/html using the 7za command :

/usr/bin/7za a /var/backups/projects.zip -tzip -snl -mnt -- *

When I saw that, I thought of a wildcard injection vulnerability. Nevertheless, after some research I realized that the -- at the end of the command (just before the star) prevented such vulnerability to occur.

Here’s why : the -- is a standard argument in many Linux command-line tools that signals the end of options and ensures that any arguments following it are treated as positional arguments (e.g., file names) rather than options or flags.

That said, let’s try to understand the options being used in the above 7za command :

  • a : Adds files to an archive (here /var/backups/projects.zip)
  • -tzip : Uses zip format for the archive
  • -snl : Tells 7za to store symbolic links as links, rather than copying the files or resolving the links
  • -mnt : Uses multiple CPU threads for faster compression

To escalate our privileges, we will try to access root’s private key by using a symlink :

Creating a symlink to /root/.ssh/id_rsa

When 7za is executed, it will treat root_id_rsa as a file containing the list of files it should compress (that’s what the existence of @root_id_rsa indicates). Therefore when 7za reads root_id_rsa it will read /root/.ssh/id_rsa and see that the content of this file isn't a list of files, it will throw and error showing its content. You can find more information here.

Let’s now try to execute the binary by choosing the first option :

As expected, 7za showed us the content of /root/.ssh/id_rsa .

Let’s copy the ssh private key into a file on our local machine :

Initial content of id_rsa

After that, we will need to clean the file a little bit. I used this vim command to achieve that :

vim -c ':%s/ : No more files//g; x' root_id_rsa
Root ssh private key

Once done, we will need to change the private key permissions to 600, then we should be able to obtain a root shell :

root.txt

Key Techniques Used

Here are the main techniques that we cover in this box :

  • Basic SQL injection on the password reset page : this showed us that how important it is to check if each user input is properly sanitized and validated.
  • File upload vulnerability affecting laravel-admin ≤ 1.8.19
  • Learn how to exploit 7za -snl option to escalate our privileges.

Lessons Learned

1/ To get our initial access, we exploited a basic SQL injection and file upload vulnerability. To fix the SQL injection, we recommend using parameterized queries (aka prepared statements).

To remediate the file upload vulnerability, we recommend updating your Laravel-admin version to the latest one.

Further remediations step include the usage of web application firewall to protect your website.

2/ To escalate our privileges, we exploited the 7za’s -snl option. This was feasible because we had the privileges of executing the usage_management binary as root without specifying any password. To fix that we recommend implementing the principle of the least privilege.

Wrap Up

That’s it guys. Thanks for reading. I hope you enjoyed the writeup.

If so, do not forget to click on the little clap icon below and subscribe to my newsletter to keep up with my latest articles !

--

--

0liverFlow
0liverFlow

Written by 0liverFlow

Pentester | Enjoy breaking and building stuffs

No responses yet