HacktheBox: Soccer Writeup
Hey everyone, I wanted to share my experience doing the HackTheBox machine “Soccer”, which is rated as an “easy” machine. During my exploration, I discovered some new techniques and approaches, and I thought it would be helpful to share a walkthrough with you all. I’m very grateful to Kiran Ghimire for providing such a challenging and engaging environment to learn.
By the time of this writeup, the machine should have been retired. Still you can find it below:
Initial Recon
Let’s start with a basic Nmap scan. This allows us to see what ports are open and what services are running on those ports:
After running the Nmap scan, we can find that three ports are open: 22, 80, and 9091.
Let’s start with the port 80, where we can see it’s redirecting us to soccer.htb
.In order to resolve the host, we need to add it to our /etc/hosts
file:
When we visit the host using our web browser, we see a single page with the Nginx web server running. There doesn’t seem to be anything interesting on the page.
Let’s fuzz for some interesting stuffs with FFUF:
While fuzzing, we can find a directory called /tiny
that contains a web application called Tiny File Manager.
To try to gain access to the Tiny File Manager application, we can try for default credentials of tiny File Manager. After a bit of google, we can find that admin:admin@123
works. This gives us access to the application’s dashboard, which we can use to upload and manage files on the server.
So, We’re in!!
/
isn’t writeable but /tiny/uploads
is.
So, we can upload our php reverse shell to get a shell.
After successfully uploading our PHP reverse shell to the /tiny/uploads
directory, we are able to establish a remote shell on the server. However, we can see that the shell was running as the www-data
user, which had limited privileges. To be able to access the flag, we needed to escalate our privileges to gain greater control over the machine.
Let’s make the shell stable and do some enumeration. We knew that there are two users who can login with ssh (root&player) user.txt is on player’s home directory which we can’t read yet.
Privilege Escalation I (user)
As we had observed during our initial reconnaissance, the web server on the target machine was running Nginx. To see if we could find any additional information, we can start to explore some of the Nginx configuration files on the server.
Through this process, we can find that there is another subdomain running on the machine at “localhost:3000”. To access this subdomain, we have to add the hostname “soc-player.soccer.htb” to our “/etc/hosts” file (same as before)
Let’s try FUZZing this subdomain too.
Cool, this host seems to have more functionality than previous one.
After registering and logging in, we can notice a feature on endpoint /check
which basically checks if the ticket exists.
Which looks to be vulnerable to SQL injection. This simple payload made the server sleep for 5 seconds.
The server was using Websocket which we knew from initial nmap scan too:
It took me few minutes to find following blog with good explanation and script to exploit this blind SQLi:
Let’s make our exploit ready and make the sqlmap do our job:
It takes some time to dump the database but at last we can get our credentials on accounts table of soccer_db with email and password on it.
Let’s try to ssh on the server with the credentials we got:
Here, we got our user flag.
Privilege Escalation II (root)
After few more enumeration, we got the unusual binary doas
with special permission:
doas (“dedicated openbsd application subexecutor”) is a program to execute commands as another user.
Digging more, we can know that whenever the user player
executes the command /usr/bin/dstat
, the command can be executed with root privileges without requiring a password.
dstat is a tool that is used to retrieve information or statistics form components of the system such as network connections, IO devices, or CPU, etc.
dstat — list gives us the available operations within dstat:
Unfortunately the directory at /usr/share/dstat
is unwritable but we can know the file formats from it (dstat_operation.py):
Since, we can write on /usr/local/share/dstat
, it’s also included on dstat’s operations:
Now, since we know that, we can execute command as root. we can create a simple python file to execute the code as root user and run it:
The SUID bit was set! Now we just need to run /bin/bash -p
to allow us to keep the elevated permissions as root from the SUID.
Pwned!!
Analyzing Vulnerable Code snippet:
So this was the code responsible for Blind SQL injection via Web socket:
var id = JSON.parse(data).id
is parsing the incoming message from a websocket client and extracting the id
field from the JSON object.
The vulnerability lies in the fact that the id
value is being concatenated directly into the SQL query string without any proper sanitization or validation. This means that an attacker can potentially inject malicious SQL code as the id
value, causing the query to execute unintended commands on the database.
In the vulnerable code, the SQL query is constructed using string concatenation with the id
value as follows:
const query = `Select id,username,password FROM accounts where id = ${id}`;
An attacker can craft a payload to manipulate the id
value to execute unintended SQL commands.
To prevent these types of vulnerabilities, it’s recommended to use parameterized queries or prepared statements, which separate the query logic from the data input, and validate/sanitize the input to ensure it’s safe to use in the query.
Thanks for making it till the end, that’s all folks.
You can connect with me on Twitter if you wish to.