As usual, we begin with an nmap scan to identify listening services.
- 22: OpenSSH 7.6p1 Ubuntu
- 80: Apache httpd 2.4.29
- 443: Apache httpd (SSL-only mode)
Enumeration – HTTP (80)
The HTTP service home page responds with HTTP 403 – Forbidden… After running a Gobuster scan with the dirb/common.txt wordlist, we didn’t get any further results. So let’s move on to HTTPS enumeration
Enumeration – HTTPS (443)
Naturally, when navigating to this page, we get a warning from our browser that the certificate is self-signed and cannot be trusted. Anyways, lets take a closer look at the certificate before we accept the warning. We get some interesting information here. The issuer/issued common name (CN) is
staging-order.mango.htb, so that is a subdomain. We also see in the details tab that the issuer email is
email@example.com. Let’s note these down and move on.
Once accepting the risk, we land on a Mango page, which looks similar to Google. However, it seems that when search requests are sent, we just get redirected back to the Mango page. On the top right, we see an
analytics.php page. Within this page, there a bunch of statisics on the average of startup density for different states in USA. Hmm, not really able to find any injection point here. Let’s take a look at the subdomain.
This page points to a login page, and we see some mangos.
We already have a potential username from the SSL certificate (
firstname.lastname@example.org), but we don’t know the password yet. I was stuck on this part for a while and eventually loaded the request into Burp repeater. Failed logins get a HTTP 200 response and we re-load the login page. I suppose that we need to perform some sort of injection to get in. However, none of the normal SQL injection payloads were successful e.g.
' or 1=1; -- -. But, the name Mango alludes to a different type of DMBS => mongo.
This is where I turned to PayloadAllTheThings’s repository which had a page on MongoDB injection payloads. I just went through these one by one and eventually got a different response where we can know that there was some injection.
# Normal HTTP request parameters username=admin&password=admin&login=login => HTTP 200 response, failed login # With MongoDB injection username[$ne]=toto&password[$ne]=toto&login=login => HTTP 302 response, successful login
The reason that
username[$ne]=toto as a parameter worked is because the
$ne flag means not equal. So we have some potential blind injection here. We can move forward and guesstimate some usernames
# Try to find usernames username[$regex]=admin&password[$ne]=toto&login=login => HTTP 302 response, admin is a valid username username[$regex]=mango&password[$ne]=toto&login=login => HTTP 302 response, mango is a valid username
We can use the valid usernames to perform some blind injection to pull out the password. Lets create a python script, it works like this
- Send a login request with these parameters
- Enumerate through dictionary characters and use them as the password. The
[$regex]field means that a successful portion of the password will match. For example if the password would be
password[$regex]=frwould be true and give a HTTP 302 response.
- For each successful login, append the next character to a list, and try again for the next letter.
- If we loop through all letters then we have some certainty that we have found the end of the password.
The python script which I made for it can be found on my GitHub page here. The output can be seen in the screenshot below. These are the credentials which we grabbed.
So, now that we have some credentials, we can log in right? Well yes, but no… The website is under plantation.
Getting the initial shell
Lets step back to our host enumeration, and remember that we still have the SSH port. We can try logging in with the credentials which we have pulled from the Mango application. And we are able to login as
mango, however there is no user.txt flag. Let’s go into
/home to see what other users are on the host – and of course we see
admin as well. Lets hope that their password is the same as the Mango web application too. And it is! Now we can read the user.txt flag.
Lets perform some host enumeration and run
linpeas.sh. Under the “Interesting Files” and “SGID” headings, there is a highlight which according to Linpeas would be a 99% privilege escalation route. The reason that this is interesting for us is because as an SGID binary, the users within the group can run this binary under root context, without a password. This is why it was important for us to switch to the
admin user, which of course is part of the admin group.
JJS is also an interesting binary, and there is some good information which might help us on the GTFOBins page for JJS. For completeness, I wanted to get a root shell. I was not however able to get the reverse shell to work from the GTFOBins page. However, the GTFOBins page also shows how we can write to files. So I added my SSH public key to the
authorized_keys file in the root folder of Mango, and we were able to login with our private key.
$ echo 'var FileWriter = Java.type("java.io.FileWriter"); var fw=new FileWriter("./file_to_write"); fw.write("ssh-rsa AAAAB[...]"); fw.close();' | jjs
This was a really cool box to learn some MongoDB injection. I have never done that before and this box allowed me to not only learn something new, but also to write a python script. I’m sure there are better tools available, however this was still a cool challenge.