Jarvis
Last updated
Last updated
This write-up details the steps taken to solve the Jarvis machine from Hack The Box. The approach includes reconnaissance, enumeration, exploitation, and privilege escalation to gain root access.
To begin the process, an nmap
scan was conducted to identify open ports and services running on the target machine:
The scan revealed three open ports:
22/tcp
open
ssh
OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp
open
http
Apache httpd 2.4.25 ((Debian))
64999/tcp
open
http
Apache httpd 2.4.25 ((Debian))
Port 22 (SSH): Running OpenSSH 7.4p1, a common entry point for secure remote access.
Port 80 (HTTP): Hosted a web server identified as Apache 2.4.25.
http-title
: Stark Hotel — likely the website name.
http-cookie-flags
: PHPSESSID did not have the httponly
flag set, a minor security misconfiguration that may indicate weak session handling.
Port 64999 (HTTP): Another Apache 2.4.25 service was running, but it lacked a title or additional identifying information.
The next step involves further enumerating the web servers on ports 80 and 64999 to uncover potential vulnerabilities or entry points.
Port 80: Stark Hotel Website
Visiting the website on port 80 revealed a hotel-themed interface:
HTTP Title: "Stark Hotel"
A standard hotel website layout with a navigation bar, links to rooms, and potential forms.
Room Page with Controllable cod
Parameter
Navigating to the Room page, the URL used the following structure:
The cod
parameter was identified as controllable, meaning user input directly influenced the page’s content. This behavior hints at potential vulnerabilities like Local File Inclusion (LFI), Remote File Inclusion (RFI), or SQL Injection (SQLi).
cod
ParameterSince the cod
parameter appeared controllable, it was tested for SQL Injection vulnerabilities. A common technique is to use payloads to determine the number of columns returned by a query.
The following payloads were used:
Basic injection test:
This caused a result:
Then if we try with a false condition the result is not displayed confirming that the input is unsanitized.
Using the ORDER BY
method to determine the column count:
Repeating this with increasing numbers (ORDER BY 2--
, ORDER BY 3--
, etc.) until an error occurred helped identify the total number of columns.
Using the ORDER BY
technique, it was determined that the number of columns in the query is 7. The following payloads confirmed this:
This returned a valid response, while using ORDER BY 8--
resulted in an error, confirming that there are 7 columns.
Identifying Injectable Columns
While testing column reflection using a valid cod
parameter (e.g., 2
), no output was displayed. However, using an invalid value such as -1
allowed the injection results to be visible. This indicates that error-based or blind SQL injection techniques may be limited, but injecting into non-existent records provides direct feedback.
The following payload confirmed this behavior:
The payload revealed which columns are reflected on the page. The specific columns displaying content can be used for further injection to extract sensitive data from the database.
Identifying the Database in Use
After confirming injectable columns, the next step was to identify the database in use. The following payload was used to extract the database schema:
This query revealed that the database in use is hotel.
Listing the Tables in the hotel
Database
With the database identified, the next step was to enumerate the tables within the hotel
database using the following payload:
This revealed the room table as the only table in the hotel
database.
Enumerating Columns in the room
Table
To list the columns in the room
table, the following payload was used:
However, since the results were limited, we had to experiment with the LIMIT
clause to enumerate all columns effectively. Once all columns were visible, we found no interesting columns such as user
or password
. As a result, the focus shifted to file reading and further exploitation techniques.
File Reading via SQLi
Attempting to read system files through SQL injection was the next logical step. The following payload was used to read the /etc/passwd
file, revealing system user information:
The contents of the file were displayed as expected:
Writing Files via SQLi
Next, the ability to write files to the server was tested. A file was uploaded using the following payload:
This successfully created a file named test.txt in the /var/www/html
directory.
Remote Code Execution via File Upload
Given that the web page was running PHP, an attempt to upload a PHP reverse shell script was made using the following payload:
This created a PHP shell at /var/www/html/shell.php.
Getting a Reverse Shell
Finally, a reverse shell was obtained by accessing the PHP shell and passing the cmd
parameter with a bash command to initiate a reverse shell:
This successfully connected to the attacker's listener, providing a reverse shell with access to the target machine as www-data.
In the /var/www/Admins-Utilities
directory, a Python script was found that could be executed as the pepper user without requiring its password. This script was identified as a potential privilege escalation vector.
The script itself is a python3
script used to manage and provide statistics on the webserver:
The script provides three command-line options:
Display statistics about recent attacks
List the attacker IPs
Ping an IP address
I’m particularly interested in the ping option because I suspect the script might not handle the ping operation purely in Python, and instead, it likely relies on a system or subprocess call. Upon inspection, I confirm this:
The exec_ping
function is executed directly from the main block when the -p
option is provided:
The vulnerability lies in the way user input is handled in the exec_ping
function, where the input is directly used in the os.system
call:
This approach is vulnerable to command injection. While the script filters out certain forbidden characters such as &
, ;
, -
, `
, ||
, and |
, the author overlooked another key bash syntax: $()
. This allows me to inject arbitrary commands and bypass the forbidden characters filter.
Now, I can test this vulnerability by using the $()
syntax to execute additional commands along with the ping
command.
None of the reverse shells I’m aware of can run without using at least one of those characters, but I can work around this by writing the commands I want to execute into a file and then running that file instead.
Finally execute the python script using sudo as pepper user:
I found that the /bin/systemctl
binary had the SUID permission set, which allowed any user to execute it with root privileges. The SUID bit lets a program run with the permissions of its owner, in this case, root.
Since systemctl
manages system services, this could be exploited for privilege escalation. By executing systemctl
as a regular user, I could manipulate services or run arbitrary commands with root access.
The presence of this SUID permission on such an important binary posed a significant security risk, which could be leveraged for further escalation.
/bin/systemctl
To escalate privileges using the SUID-enabled /bin/systemctl
, I followed these steps:
Create a malicious root.service
file: I created a systemd service file named root.service
with the following content:
This service starts a reverse shell to my attacker's machine on IP 10.10.14.22
and port 9999
.
Execute the payload: I used the following command to enable the service, which would make it start automatically:
Start the listener and get the shell as root: I started the service with the following command:
This triggered the reverse shell, and I successfully gained a root shell.