HTB
HTB Usage writeup [20 pts]
Usage is a linux easy machine which start with a SQL injection in a forgot password functionality. With this SQL injection, I will extract a hash for admin that gives me access to the administration panel. From there, I will abuse a profile picture upload to upload a php reverse shell that gives me access as dash user. Then, in dash’s home directory, I will find a .monitrc that gives me credentials for xander, which has a sudo privilege that allows to backup the web directory and introduce our symlinks there. I will abuse this to retrieve root’s id_rsa.
Enumeration
Port scanning
I will start with a basic TCP port scanning with nmap to see which ports are open and see which services are running:
- -sVC: Identifies service and version.
- -p-: scans all the range of ports (1-65535).
- –open: shows only open ports and not filtered or closed.
- -sS: TCP SYN scan that improves velocity because it doesn’t establish the connection.
- –min-rate 5000: Sends 5000 packets per second to improve velocity (don’t do this in a real environment).
- -n: Disables DNS resolution protocol.
- -v: Enables verbose to see which ports are opened while it’s scanning
- -Pn: Disables host discovery protocol (ping).
- -oN targeted: Exports the evidence to a file named “tcpTargeted”.
There are ports 22 and 80. I don’t have valid credentials for ssh so I will go forward to the web.
Web enumeration
Taking a look with curl, I can see it consists of a nginx ubuntu server and that it redirects to usage.htb:
So I will add this line to the /etc/hosts
for the system to know where to follow this domain. If I don’t do this, my linux system wouldn’t now where is that domain:
Now, using curl with this domain, I can see one new thing. It sets two cookies, one for csrf protection (XSRF-TOKEN) and another for the session (laravel_session). Now I know that its using laravel and in consequence, php:
Looking in the browser, I can see it shows a login page. There are also some links like “Register”, “Admin” and “Reset password”:
“Admin” is a link to admin.usage.htb:
After adding it to the /etc/hosts, I can see with curl that its also using laravel but its a different page with title Admin | Login
:
In the browser, looks completely different from the other page:
Testing for basic credentials doesn’t work, so I will look another things. Registering an account and logging in, just shows a blog page talking about “the importance of server side pentesting” and the “laravel php framework”:
My used creds doesn’t work for the admin panel:
I don’t see nothing interesting logged in, so I will log out and see other functionalities. The reset password functionality returns the message “We have e-mailed your password reset link to gabri@gabri.com” when the email exists and when it doesn’t exists it says “Email address does not match in our records!”:
Also, ' or 1=1-- -
returns a successfull message:
To make sure this is not a created account, I will put any random number and it works:
My technique to dump the data will be using a boolean sql injection using substring. I will intercept with burpsuite to craft the request to dump data. First, I will change burpsuite repeater settings to always follow redirects as it shows the message after the redirect:
Also, I will search for the string “We have e-mailed your password” and check the checkbox “Auto-scroll to match when text changes” in the response settings to instantly see if the query is correct:
With this, I have confirmed it works because when I say that the first character of the current database is ‘u’, it works:
Now I have a way to extract data from the database, so I will create a python script to bruteforce some queries. I will start with database(). This python scripts does a lot of things. First, it gets the length from a query specified to do only the necessary requests for the position. Then, it goes for each number between 1 and the length and for each character to extract the data from the database char by char. For every iteration in the loop, it takes the token from the forget-password page because if not it will throw a 419 page expired
status code. With that token, it makes the SQLi request and if the string “We have e-mailed your password” is in the response, it shows the character in console. This is the result:
Executing this script, successfully prints the length and retrieves that the name of the current database in use is “usage_blog”:
I will change the query to "select group_concat(schema_name) from information_schema.schemata"
to retrieve all the databases separated by commas. There is no other interesting database here:
Now, to dump the tables of ‘usage_blog’ database, I will change the query to select group_concat(table_name) from information_schema.tables where table_schema='usage_blog'
. After a while I can see the results:
The most interesting tables are admin_users and users, so I will dump their columns by changing the query to select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='users'
and then to select group_concat(column_name) from information_schema.columns where table_schema='usage_blog' and table_name='admin_users'
:
The users
table most interesting columns are email
and password
. However, I saw that there were a lot of users that were HackTheBox players and only two belonged to the machine, so I will hide them here and show only the interesting ones:
Note: the use of BINARY is because if I don’t use it, it will be case insensitive and I don’t want that.
Trying to crack the hashes success:
The password for raj it’s xander. However, it doesn’t work in ssh and neither in the admin portal:
I can login in usage.htb with username raj@raj.com
and password xander
but there is nothing new:
So I will go forward the admin_users table and dump its columns:
Columns “username” and “password” results interesting to me so I will dump them:
I have the hash of admin, which its also crackable:
Now I can login into the admin panel:
Access as dash
In the dashboard, I can see the dependencies and also its versions. Searching for vulnerabilities, I saw this one that shows the same admin interface and that the ‘user settings’ page has a upload feature that I can abuse with a bypass for RCE:
I will replicate it by creating a image.png file with the following contents:
Now intercept the request with burpsuite and change image.png
to image.png.php
:
When forwarded, I can see the file in the profile:
And successfully get RCE by copying the link:
Now, I will start a nc listener on port 443 and send myself a reverse shell:
And I receive a shell as dash!:
But now to have a completely interactive tty shell, I will execute the following commands:
-
script /dev/null -c bash
: Spawns a tty. -
ctrl+z
: puts the shell in background for later doing a treatment. -
stty raw -echo;fg
: gives the shell back again. -
reset xterm
: resets the terminal to give the bash console. -
export TERM=xterm
: let do ctrl+l to clean the terminal. -
export SHELL=bash
: specifies the system that it’s using a bash console. -
stty rows <YOUR ROWS> cols <YOUR COLUMNS>
: sets the size of the current full terminal window. It is possible to view the right size for your window runningstty size
in a entire new window on your terminal.
And I can see user.txt:
Access as xander
Looking at dash’s home directory I can see some interesting hidden files:
The .monit* files are for monit, which is a utility for managing and monitoring processes, programs, files, directories, etc:
And the .monitrc has another password:
Looking for system users with shell, I have dash, xander and root:
And the password is correct for xander!:
Access as root
This user (xander) has sudoers privileges:
I can execute /usr/bin/usage_management as any user I want without password. This executable consists in a binary:
Before doing reverseing, I would like to see what the executable does. Executing it, it asks for an option of which there is “Project Backup”, “Backup MySQL data” and “Reset admin password”:
The “reset admin password” choice seems to do the described thing:
The “Backup MySQL data” option doesn’t give any output:
And the option “Project backup” seems to do a backup of some folder using 7z:
I will transfer the binary to my machine to analyze it with ghidra:
Attacker machine:
Victim machine:
Now I will select “File” > “New Project”, select the folder for the project and click “Finish”:
Then import the binary selecting “File” > “Import file”:
And finally, drag the binary to the dragon to have this interface where the C code is decompiled (because the binary its written in C):
Going to “Functions” > main, I can see the main program code:
Where I can see what actually happens, it prints those things and depending on the option, it executes one function or another. I will focus on the backupWebContent() to see what it actually does by double clicking on it:
There is an important vulnerability here. I can’t insert my input but it’s using a wildcard to zip all the contents of /var/www/html so I can put a symlink there to /root/.ssh/id_rsa for example and see its contents. I will do that:
And I see root’s id_rsa in the output, so I will write it into a file and ssh as root:
And I have access as root! Now I can see the final root.txt: