soccer
Recon
Start off with a basic nmap
scan:
|
|
|
|
Not much going on in terms of open ports and exposed services. Visiting http://soccer.htb
there is a website dedicated to soccer (no surprise given the box name).
Fuzzing for directories shows http://soccer.htb/tiny/
which may be of interest.
|
|
Visiting that URL, we find a file manager:
If you google “h3k tiny file manager”, one of the top results should be a GitHub repo containing the code for the file manager present on the soccer website: https://github.com/prasathmani/tinyfilemanager. A quick trip through the documentation reveals the default credentials are admin/admin@123
, which work on the soccer website.
In order to get code exec on the box , we are going to upload a webshell, and leverage that into a full reverse shell. Create shell.php
with the following contents:
|
|
Upload shell.php
to tiny/uploads/
in the file manager (as we don’t seem to have permission to upload to the root). Access it, and see that it works by visiting http://soccer.htb/tiny/uploads/shell.php?cmd=id
. You should get the output of the id
command.
Note that there seems to be a script on the box that is clearing the contents of the uploads folder on a periodic basis, so you may have to upload the shell again.
We can generate a reverse shell on https://www.revshells.com/
. Im going to use python3 #2, as I find it to be reliable in these situations, and I verified that python3 is already on the box by running which python3
in the webshell.
My full reverse shell command with the URL included is:
|
|
Escalation to Player
When we get on the box, we can see there is a player
user, who has the user flag in their home directory. However, as www-data
, we don’t have permission to read it.
Since the webserver is nginx, its worth looking at the config to check for sensitive information, or if we missed an vhosts during initial recon. Looking in /etc/nginx/sites-available/
we see there is a config for soc-player.soccer.htb
config. Add that to the host file and lets see what that new site is.
It seems to be very similar to soccer.htb
, but with some added functionality. Lets create an account to see what we might be able to exploit. After creating an account and logging in, we get directed to the /check
endpoint, where we can check if certain ticket numbers exist. If you put in your ticket id, found at the top of the form, you can see you get back the message “Ticket Exists”.
This smells like a boolean based SQLi. However, when looking through requests in Burpsuite and trying to capture the request used to check the ticket, you might be puzzled to find its not there. This is because the submission is being done through a websocket, listening on the port 9091
which we found in our initial nmap
scan. You can find the websocket requests in the “Websockets history” subtab under the “Proxy” tab.
If we were going to try to find a SQLi manually, this would not pose an issue. However, I am lazy, and want to use sqlmap
to automate this for me.
In order to use sqlmap
through a websocket, we will need a intermediary server to convert the regular http
requests from sqlmap
to websocket requests, and vise-versa. I found a brilliant script at https://rayhan0x01.github.io/ctf/2021/04/02/blind-sqli-over-websocket-automation.html. Full credit to the author for writing this, as I only made minor changes to adapt it to my needs.
Here is what I used:
|
|
After starting the above python script, you can run sqlmap
as follows:
|
|
The *
next to the number in the id
parameter indicates to sqlmap
that we want to test that parameter.
If the above command fails and breaks the websocket when checking for a time based SQLi, you can reset the box and leave out those tests by running the following:
|
|
technique=BEUS
leaves out the time based attacks. You can read more about that here.
Dumping the database reveals players password to be PlayerOftheMatch2022
, which can be used with ssh.
Escalation to root
As player, we can run linpeas to try to find any escalation paths.
After running, we see that player
can run dstat
as root using the doas
command.
GTFObins gives us easy to follow, copy paste command to get root: