// 01
Resumen
Cap es una máquina Linux de dificultad fácil
que corre un servidor HTTP con funciones administrativas, entre ellas la captura de
tráfico de red. La aplicación web expone un panel de monitoreo con la ruta
/data/<ID>
donde el ID es un número entero secuencial. La ausencia de controles de acceso
adecuados da lugar a una vulnerabilidad de tipo
IDOR (Insecure Direct Object Reference): al manipular
el ID a /data/0
se accede a la captura de otro usuario, que contiene tráfico
FTP en texto plano con credenciales válidas.
Con esas credenciales se accede vía SSH al sistema como
el usuario nathan y se obtiene la flag de usuario. Para la escalada
de privilegios, el binario
/usr/bin/python3.8
tiene asignada la capability CAP_SETUID, lo que permite
ejecutar código Python que cambia el UID del proceso a 0 (root) y lanza una shell,
obteniendo acceso total al sistema.
| Fase | Técnica / Herramienta | Resultado |
|---|---|---|
| VPN | sudo openvpn Dedicated_Lab_Masker10.ovpn | Túnel HTB establecido |
| Reconocimiento | ping 10.129.2.33 -c 3 | Host activo, TTL 63 → Linux |
| Escaneo | sudo nmap -p- -sV 10.129.2.33 --min-rate 50000 | Puertos 21 (FTP), 22 (SSH), 80 (HTTP) |
| Enum. Web | http://10.129.2.33 → dashboard como Nathan | Aplicación de captura de red |
| IDOR | http://10.129.2.33/data/0 | Pcap ajeno con 72 paquetes |
| Análisis pcap | Wireshark → filtro ftp → TCP Stream | USER nathan / PASS Buck3tH4TF0RM3! |
| Foothold | ssh nathan@10.129.2.33 | Shell como nathan, user.txt |
| Enumeración | getcap -r / 2>/dev/null | /usr/bin/python3.8 = cap_setuid+eip |
| Privesc | python3.8 -c 'import os; os.setuid(0); os.execl("/bin/sh","sh")' | Shell como root, root.txt |
// 02
Conexión OpenVPN
Antes de interactuar con cualquier máquina de HackTheBox, es necesario establecer un túnel VPN hacia la red de laboratorio. Sin esta conexión, la IP de la máquina objetivo (10.129.x.x) no es alcanzable desde Internet, ya que pertenece a un segmento de red privado de HTB.
Descargamos el archivo .ovpn
desde el portal de HTB (sección Connect) y lo ubicamos en
~/Downloads/.
El comando sudo openvpn lanza el cliente OpenVPN con
privilegios de root (necesarios para crear la interfaz de red virtual tun0).
El parámetro del archivo Dedicated_Lab_Masker10.ovpn
contiene la configuración completa del servidor VPN: dirección IP del servidor
HTB, certificados de autenticación, protocolo (TCP/443 en este caso), rutas a
inyectar en la tabla de enrutamiento local y parámetros de cifrado
(AES-256-CBC). Una vez establecida la conexión, el sistema añade automáticamente
las rutas necesarias para que el tráfico hacia 10.10.x.x y
10.129.x.x pase por el túnel.
// SEÑAL DE CONEXIÓN EXITOSA
La línea Peer Connection Initiated confirma que el túnel TLS está establecido. A partir de este momento, las IPs del rango 10.129.x.x son alcanzables desde nuestra máquina Kali. Este proceso debe mantenerse corriendo en una terminal aparte durante todo el ejercicio.
// 03
Reconocimiento
Antes de lanzar cualquier herramienta de escaneo, verificamos que la máquina
objetivo responde en la red. Usamos ping con el
flag -c 3 para enviar exactamente
3 paquetes ICMP Echo Request y detenerse automáticamente
(sin este flag, ping continuaría indefinidamente). Si la máquina está activa,
responderá con paquetes ICMP Echo Reply. El campo
ttl=63
en la respuesta es un indicador del sistema operativo: Linux suele partir de
TTL 64 y lo decrementamos en 1 por cada salto de red, mientras que Windows
parte de 128. Un TTL cercano a 64 apunta a un sistema Linux,
lo cual es coherente con la descripción de la máquina.
Con la máquina confirmada como activa, realizamos un escaneo de puertos completo con nmap. Cada flag tiene un propósito específico:
-p- escanea todos los 65535 puertos TCP,
no solo los 1000 más comunes que nmap usa por defecto. Es fundamental para no
pasar por alto servicios en puertos no estándar.
-sV activa la detección de versiones:
nmap envía sondas específicas a cada puerto abierto para identificar el software
exacto y su versión (ej. vsftpd 3.0.3, OpenSSH 8.2p1).
--min-rate 50000 fuerza a nmap a enviar al menos
50,000 paquetes por segundo, reduciendo el tiempo total del
escaneo de minutos a segundos. Esta agresividad es aceptable en un entorno
de laboratorio controlado. Finalmente, la IP
10.129.2.33
es el objetivo del escaneo.
// ANÁLISIS DE RESULTADOS
Se detectan 3 puertos abiertos: 21 (FTP) con vsftpd 3.0.3 — servidor FTP, potencial vector si hay credenciales. 22 (SSH) con OpenSSH 8.2p1 — acceso remoto seguro, útil una vez tengamos credenciales. 80 (HTTP) con Gunicorn — servidor Python WSGI, indica una aplicación web desarrollada en Python (probablemente Flask o Django). El siguiente paso es explorar la aplicación web.
// 04
Acceso Web · Puerto 80
Accedemos a http://10.129.2.33
en el navegador. La aplicación presenta un dashboard de administración de red
que muestra estadísticas de tráfico capturado: número de paquetes IP, TCP y UDP.
En la esquina superior derecha se aprecia el nombre del usuario autenticado:
Nathan.
El menú lateral incluye la opción Security Snapshot (5 Second PCAP + Analysis),
que al ejecutarse genera una captura de tráfico de 5 segundos y la almacena bajo
la ruta /data/<ID>.
El ID es un número entero que se incrementa con cada captura que realiza el usuario
actual. Al observar la URL tras generar una nueva captura, nos encontramos en
/data/2 o similar.
// VULNERABILIDAD DETECTADA — IDOR
La aplicación usa un identificador numérico secuencial y predecible para referenciar capturas de red. No existe ningún control de autorización que verifique que el usuario autenticado sea el propietario de la captura solicitada. Cualquier usuario puede acceder a las capturas de cualquier otro usuario simplemente cambiando el número en la URL. Esto es una vulnerabilidad IDOR (Insecure Direct Object Reference).
// 05
IDOR · Acceso a /data/0
Sabiendo que el servidor asigna IDs secuenciales a cada captura, probamos el
ID más bajo posible: 0. Al navegar a
http://10.129.2.33/data/0
el servidor nos devuelve la captura número 0, que pertenece a otro usuario
(no a Nathan). Esta captura muestra 72 paquetes en total
(69 TCP, 69 IP), una cantidad significativamente mayor que la captura vacía
de 1 paquete que tendríamos en nuestra propia sesión. Esto indica actividad
de red real, potencialmente interesante.
El botón Download permite descargar el archivo
.pcap
de esa captura para analizarla localmente con Wireshark.
// ¿POR QUÉ /data/0?
El ID 0 es el primero asignado cuando el sistema inicia. Al pertenecer a la configuración inicial o a otro usuario, su captura puede contener tráfico generado durante la puesta en marcha del servicio. En muchos CTFs y entornos reales, los datos más antiguos (ID más bajos) son los más ricos en información sensible, ya que corresponden a actividad administrativa temprana.
// 06
Análisis PCAP · Wireshark
Abrimos el archivo .pcap
descargado en Wireshark. Para encontrar credenciales
rápidamente, aplicamos el filtro ftp
en la barra de filtros de Wireshark. Este filtro muestra únicamente los paquetes del
protocolo FTP, descartando todo el tráfico irrelevante.
FTP (File Transfer Protocol) transmite todos sus datos,
incluidas las credenciales, en texto plano sin cifrado.
Cualquier persona que capture el tráfico de red puede leer directamente el usuario
y la contraseña. En la vista filtrada de Wireshark identificamos los paquetes clave:
el paquete con Request: USER nathan
y el paquete con
Request: PASS Buck3tH4TF0RM3!,
seguidos del response 230 Login successful.
Para ver la conversación FTP completa en orden cronológico, hacemos clic derecho sobre cualquier paquete FTP → Follow → TCP Stream. Esta función de Wireshark reconstruye el flujo TCP completo mostrando la sesión en su totalidad: el intercambio de comandos entre el cliente FTP y el servidor vsftpd. Los datos en rojo corresponden a lo enviado por el cliente (credenciales) y en azul las respuestas del servidor.
// RIESGO — CREDENCIALES EN TEXTO PLANO
FTP transmite credenciales sin cifrado alguno. En un entorno real, esto constituye una vulnerabilidad crítica: cualquier dispositivo en la misma red (switch, router, otro host comprometido) puede interceptar estas credenciales con herramientas como Wireshark, tcpdump o ettercap. La solución es migrar a SFTP o FTPS, que cifran la sesión completa.
// 07
Acceso SSH · Foothold
Con las credenciales extraídas del tráfico FTP, intentamos acceder vía
SSH al puerto 22. Usamos el comando
ssh nathan@10.129.2.33:
el formato es usuario@IP.
Esto funciona gracias a la técnica de reutilización de contraseña
(password reuse): el usuario nathan usó la misma contraseña tanto para FTP como para SSH,
un error de seguridad muy común en entornos reales.
Una vez dentro del sistema como nathan, listamos el contenido del
directorio home con ls
y encontramos el archivo user.txt.
Lo leemos con cat user.txt
para obtener la flag de usuario.
// 08
Escalada de Privilegios · CAP_SETUID
Para escalar privilegios buscamos Linux Capabilities mal configuradas.
Las capabilities son una forma granular de otorgar privilegios específicos a binarios
sin necesidad de darles el bit SUID completo. Usamos el comando
getcap -r / 2>/dev/null
para enumerarlas en todo el sistema.
getcap es la herramienta que lee las capabilities
asignadas a archivos ejecutables (almacenadas como atributos extendidos en el
sistema de archivos). El flag -r (recursive) indica
que debe buscar de forma recursiva desde el directorio raíz
/, revisando
todos los subdirectorios y archivos del sistema. El redireccionamiento
2>/dev/null descarta el stderr
(descriptor de fichero 2), es decir, todos los mensajes de error que genera
getcap al intentar acceder a directorios sin permiso (como
/proc,
/sys, etc.),
manteniendo la salida limpia con solo los resultados relevantes.
// VECTOR DE ESCALADA IDENTIFICADO
El binario /usr/bin/python3.8 tiene asignada la capability cap_setuid+eip. Esto significa que cualquier proceso ejecutado con este Python puede llamar a setuid() para cambiar su UID al de cualquier usuario, incluyendo root (UID 0), sin necesitar la contraseña de root ni el bit SUID tradicional.
Consultamos GTFOBins (gtfobins.github.io), un repositorio
de técnicas para abusar de binarios Unix en escenarios de escalada de privilegios.
En la entrada de Python con la pestaña Capabilities, encontramos
el comando exacto que necesitamos:
python -c 'import os; os.setuid(0); os.execl("/bin/sh", "sh")'.
Lo adaptamos a la versión python3.8
ya que es la que tiene la capability asignada.
Ejecutamos el siguiente comando que explota la capability CAP_SETUID de Python 3.8. Cada parte del comando tiene un rol específico:
python3.8
invoca el intérprete Python 3.8, que es el binario con la capability asignada.
El flag -c permite pasar código Python directamente
como argumento de línea de comandos, sin necesidad de crear un archivo
.py.
Dentro del código: import os carga el módulo
estándar de Python para interacción con el sistema operativo.
os.setuid(0) llama a la syscall
setuid
con argumento 0
(UID de root), cambiando el UID real y efectivo del proceso Python a root —
esto solo es posible porque el binario tiene CAP_SETUID.
Por último, os.execl("/bin/sh", "sh") reemplaza
el proceso Python actual por una shell /bin/sh
mediante la syscall execl.
Como el proceso ya tiene UID 0, la shell resultante corre como root.
// EXPLICACIÓN DE os.execl()
os.execl(path, arg0, arg1, ...) es la versión Python de la syscall
Unix execve(). Reemplaza la imagen del proceso actual por un nuevo
programa (/bin/sh) sin crear un proceso hijo. El primer argumento es
la ruta del ejecutable, y el segundo es el nombre del proceso tal como aparecerá
en ps (convencionalmente el mismo nombre del binario). Al heredar el
UID root del proceso Python, la shell resultante opera con privilegios completos.
// 09
Flags
Como root, navegamos al directorio
/root
y leemos el archivo root.txt
para completar la máquina.
// 10
Referencia de Comandos
- archivo.ovpn — configuración descargada del portal HTB
- -c 3 — envía exactamente 3 paquetes ICMP
- ttl=63 — indica sistema Linux (base 64 - 1 salto)
- -p- — todos los 65535 puertos TCP
- -sV — detección de versión de servicio
- --min-rate 50000 — velocidad mínima de 50k paquetes/s
- filtro ftp — muestra solo paquetes del protocolo FTP
- TCP Stream — reconstruye la sesión completa en orden
- usuario — nombre de cuenta en el sistema remoto
- @IP — dirección del host objetivo
- -r — búsqueda recursiva desde la raíz /
- 2>/dev/null — descarta errores de permisos
- -c — ejecuta código Python inline
- os.setuid(0) — cambia UID a root (requiere CAP_SETUID)
- os.execl() — reemplaza proceso actual por /bin/sh
- /data/0 — captura #0, pertenece a otro usuario
- sin autenticación extra — el servidor no verifica propiedad
// 11
Glosario Técnico
.ovpn personalizado que contiene certificados
únicos de cliente y la configuración del servidor VPN de HTB. Al ejecutar
sudo openvpn archivo.ovpn, el sistema crea una interfaz de red virtual
(tun0) y añade rutas estáticas para que el tráfico hacia las IPs
10.129.x.x y 10.10.x.x pase por el túnel cifrado hacia la
infraestructura de HTB. Sin esta conexión, las máquinas objetivo son inalcanzables.
/data/<ID> usa un
entero secuencial como referencia al archivo .pcap. Al cambiar el ID de
/data/2 a /data/0, el servidor retorna la captura de otro
usuario sin validar la propiedad. La corrección consiste en vincular cada registro de
base de datos al usuario propietario y verificar esa relación en cada petición.
USER y PASS se envían como texto ASCII legible
en la red. Cualquier herramienta de captura de tráfico como Wireshark, tcpdump o
ettercap puede interceptarlos. En Wireshark, el filtro ftp muestra
directamente estos paquetes. La alternativa segura es SFTP (FTP sobre
SSH, puerto 22) o FTPS (FTP sobre TLS, puertos 990/989), que cifran
toda la sesión incluyendo la autenticación.
.pcap (packet capture) y permite inspeccionar cada paquete
capturado con decodificación automática de cientos de protocolos. Los filtros de
visualización como ftp, http o tcp.port==21
permiten aislar el tráfico relevante. La función Follow TCP Stream
(clic derecho → Follow → TCP Stream) reconstruye el flujo bidireccional completo de
una sesión TCP, presentando los datos en orden cronológico y diferenciando por color
los datos del cliente (rojo) y del servidor (azul). Es esencial para analizar
sesiones FTP, HTTP y otros protocolos en texto plano.
Buck3tH4TF0RM3! tanto para FTP como para SSH. Una vez comprometido
uno de los servicios (FTP, que transmite en texto plano), el atacante puede
probar esas mismas credenciales en todos los demás servicios del sistema. En
entornos reales, este vector es una de las causas más frecuentes de compromiso
en cadena. La mitigación incluye usar contraseñas únicas por servicio, gestores
de contraseñas y autenticación de dos factores.
CAP_NET_BIND_SERVICE, CAP_SETUID, etc.) y puede
asignarse a binarios individuales como atributo extendido del sistema de archivos.
Los conjuntos +eip definen en qué contextos la capability es
efectiva (e), inheritable (i) y permitida (p). La herramienta
getcap lee estos atributos y setcap los configura.
Una capability mal asignada puede ser tan peligrosa como el bit SUID si permite
a un proceso sin privilegios realizar operaciones de root.
setuid(), setgid() y funciones
relacionadas para cambiar su identidad de usuario sin ser root. Normalmente,
solo root puede cambiar el UID a otro valor arbitrario; con CAP_SETUID, cualquier
proceso que la posea puede hacer setuid(0) para convertirse en root.
Cuando se asigna esta capability a un intérprete de lenguaje de propósito general
como Python, el impacto es crítico: el atacante puede escribir código arbitrario
que primero llame a os.setuid(0) y luego ejecute cualquier comando
con privilegios de root. El comando os.execl("/bin/sh", "sh")
reemplaza el proceso Python por una shell root interactiva mediante la syscall
execve().
cap_setuid: importar el módulo
os, llamar a os.setuid(0) y ejecutar una shell. Es
la referencia estándar en CTFs y pentesting para identificar rápidamente si un
binario con privilegios especiales puede usarse para escalar.
Gunicorn en el puerto 80) es una
pista que la aplicación web está desarrollada en Python. Esto es relevante para el
pentesting porque: (1) sugiere vulnerabilidades comunes de frameworks Python,
(2) es coherente con que el sistema tenga Python instalado con capabilities
especiales, y (3) puede revelar rutas de depuración o endpoints típicos de
aplicaciones Flask/Django.
.pcap contienen una secuencia
de paquetes de red con sus metadatos (timestamp, longitud, datos raw) capturados
en una interfaz de red. Herramientas como tcpdump, tshark
y Wireshark pueden crear y leer este formato. En el contexto de Cap,
la aplicación web usa la librería scapy o similar para capturar
5 segundos de tráfico y guardarlo como .pcap. El análisis posterior
de este archivo en Wireshark revela toda la actividad de red del período de
captura, incluyendo sesiones FTP con credenciales en texto plano.