// 01
Resumen
Injection es una máquina de dificultad fácil de DockerLabs diseñada para practicar la vulnerabilidad de inyección SQL y la posterior escalada de privilegios en Linux. La máquina corre sobre Ubuntu y expone dos servicios: SSH en el puerto 22 y un servidor web Apache en el puerto 80.
El vector de entrada es un formulario de login PHP vulnerable a
SQL Injection clásica. Al inyectar
1' or 1=1-- - en el campo de usuario,
la consulta SQL siempre evalúa como verdadera, autenticando sin credenciales
válidas y revelando la contraseña en texto claro del usuario
dylan. Estas credenciales permiten acceso por SSH.
Una vez dentro, la escalada de privilegios se logra a través del binario
/usr/bin/env con el bit SUID
activado. Consultando GTFObins, el comando
env /bin/sh -p spawnea una shell
como root aprovechando que los privilegios efectivos
no son descartados.
| Fase | Técnica / Herramienta | Resultado |
|---|---|---|
| Despliegue | auto_deploy.sh injection.tar | Contenedor activo en 172.17.0.2 |
| Reconocimiento | ping + nmap -p- -sSCV + xsltproc | 22 SSH (OpenSSH 8.9p1) · 80 HTTP (Apache 2.4.52) |
| Enumeración Web | Navegador → :80 | Login PHP con PHPSESSID — vulnerable a SQLi |
| Explotación | SQL Injection: 1' or 1=1-- - | Bypass auth + password dylan en claro |
| Acceso inicial | ssh dylan@172.17.0.2 | Shell como usuario dylan |
| PrivEsc | find SUID + GTFObins env /bin/sh -p | Shell como root |
// 02
Despliegue del Laboratorio
DockerLabs usa un script de despliegue automático que levanta el contenedor
Docker con la máquina vulnerable y nos asigna su IP. Al ejecutar
auto_deploy.sh con el archivo
injection.tar, el sistema
despliega el laboratorio y nos indica la dirección IP asignada:
172.17.0.2. El proceso queda en primer plano
y se detiene con Ctrl+C cuando terminemos.
// 03
Reconocimiento
Verificamos que el contenedor esté activo y accesible. El TTL de respuesta es 64, confirmando que es una máquina Linux (TTL inicial 64, sin hops que lo reduzcan al ser una red Docker local). La latencia de 0.3ms confirma que el contenedor está corriendo en la misma máquina host.
El escaneo revela dos puertos abiertos: el puerto 22 con
OpenSSH 8.9p1 (Ubuntu) y el puerto 80 con
Apache httpd 2.4.52. El script NSE http-title
detecta "Iniciar Sesión" como título de la página, revelando un formulario
de login. El header http-cookie-flags muestra que la cookie
PHPSESSID tiene el flag
httponly not set, lo que indicaría
también vulnerabilidad a XSS, aunque no será necesario para esta máquina.
// 04
SQL Injection — Bypass de Autenticación
Navegamos a http://172.17.0.2 y
encontramos un formulario de login con dos campos: User
y Password. El título "Iniciar Sesión" y la cookie
PHPSESSID ya nos indicaron que
el backend está desarrollado en PHP, lo que sugiere
una consulta SQL del tipo:
SELECT * FROM users WHERE user='$input' AND password='$pass'
Esta construcción clásica es vulnerable a SQL Injection si los parámetros no están sanitizados ni parametrizados con prepared statements.
Introducimos el payload clásico de bypass en el campo User y cualquier valor en el campo Password. El payload funciona alterando la lógica de la consulta SQL:
La consulta original sería:
SELECT * FROM users WHERE user='1' or 1=1-- -' AND password='...'
El -- (comentario SQL) elimina
el resto de la consulta incluyendo la verificación de contraseña.
La condición 1=1 siempre es
verdadera, por lo que la consulta devuelve el primer registro de la tabla,
logrando el bypass y revelando la contraseña del usuario
dylan en texto claro.
// SQL INJECTION — ANÁLISIS DEL PAYLOAD
1' → El número 1 cierra la comilla de apertura del parámetro user. El apóstrofe rompe la sintaxis SQL y empieza la inyección.
or 1=1 → Condición adicional siempre verdadera. Hace que la cláusula WHERE devuelva todos los registros.
-- - → Comentario SQL en MySQL/MariaDB. Todo lo que viene después (incluyendo AND password='...') queda comentado y no se evalúa. El espacio después de -- es necesario en algunas versiones de MySQL.
Query resultante: SELECT * FROM users WHERE user='1' or 1=1-- -'
Resultado: Devuelve el primer usuario de la tabla (dylan) con su contraseña en claro.
// 05
Acceso SSH como Dylan
Con las credenciales obtenidas de la inyección SQL, nos conectamos por SSH al servidor. El servidor acepta las credenciales y obtenemos una shell interactiva como el usuario dylan en un sistema Ubuntu 22.04.4 LTS. Desde aquí debemos escalar privilegios hasta root.
// 06
Escalada de Privilegios — SUID env
El bit SUID (Set User ID) en un binario hace que al ejecutarlo, el proceso corra con los permisos del propietario del archivo (generalmente root) en lugar de los del usuario que lo ejecuta. Buscamos todos los binarios con este bit activado en el sistema.
Entre los resultados destaca /usr/bin/env: una herramienta estándar de Unix que normalmente se usa para ejecutar programas en un entorno modificado. Con el bit SUID activado, se convierte en un vector de escalada de privilegios documentado en GTFObins.
// DESGLOSE DEL COMANDO FIND
find / → Busca recursivamente desde la raíz del sistema de archivos.
-perm -4000 → Filtra archivos cuyo modo incluya el bit SUID (octal 4000). El guion (-) indica "al menos estos bits activos", sin importar los demás.
2>/dev/null → Redirige los errores (stderr, fd 2) a /dev/null, descartando los mensajes "Permission denied" que aparecerían al intentar leer directorios sin acceso. Limpia el output y muestra solo los resultados válidos.
GTFObins es una base de datos curada de binarios Unix que pueden
usarse para escalar privilegios, escapar de shells restringidas o transferir archivos
cuando tienen configuraciones inseguras. Buscamos env
bajo la categoría SUID y obtenemos el comando exacto:
env /bin/sh -p
El flag -p es clave: le indica a
/bin/sh que no descarte los privilegios efectivos.
Sin este flag, muchas shells modernas detectan que el UID real (dylan) difiere
del efectivo (root) y degradan los privilegios como medida de seguridad.
El comando nos da una shell # inmediatamente.
Verificamos con whoami que somos
root y navegamos al directorio
/root para listar su contenido.
// ¿POR QUÉ .MYSQL_HISTORY EN /ROOT?
La presencia de .mysql_history en el directorio root revela que
el usuario root ha estado ejecutando comandos MySQL directamente desde la línea
de comandos. Este archivo registra todas las queries ejecutadas en sesiones
interactivas de MySQL. En un entorno real, esto podría contener queries con
credenciales, nombres de tablas sensibles o datos de configuración de la base
de datos. Siempre revisar este archivo en post-explotación:
cat /root/.mysql_history
// 07
Referencia de Comandos
- sudo bash → Necesita root para gestionar Docker y redes.
- Ctrl+C → Detiene y elimina el contenedor al finalizar.
- 172.17.0.0/16 → Subred Docker por defecto en la mayoría de sistemas.
- -sC → Scripts NSE: http-title, http-cookie-flags, ssh-hostkey.
- -sV → Versiones: Apache 2.4.52, OpenSSH 8.9p1.
- -oX → XML para xsltproc → HTML.
- 1' → Cierra la comilla del parámetro e inicia la inyección.
- or 1=1 → Condición siempre verdadera.
- -- - → Comentario MySQL, descarta el resto de la query.
- -perm -4000 → Bit SUID (octal 4000) activo.
- 2>/dev/null → Descarta errores de permisos.
- -type f → (opcional) Solo archivos regulares, no directorios.
- env → Ejecuta un programa en un entorno modificado.
- /bin/sh → Shell POSIX a spawnar.
- -p → No descarta los privilegios efectivos del SUID.
- -p <PORT> → Puerto alternativo (por defecto 22).
- -i <KEY> → Autenticación con clave privada en lugar de contraseña.
- -v → Verbose: muestra el handshake para depuración.
// 08
Glosario
xp_cmdshell en SQL Server). La prevención correcta usa prepared statements (consultas parametrizadas) donde los datos del usuario son siempre tratados como datos, nunca como código SQL. En PHP: $stmt = $pdo->prepare("SELECT * FROM users WHERE user=?"); $stmt->execute([$input]);. OWASP clasifica SQLi como A03:2021 en el Top 10.passwd (necesita escribir en /etc/shadow) o sudo. El peligro surge cuando binarios que permiten ejecutar código arbitrario (como env, find, vim, python) tienen este bit activado incorrectamente. Identificación: ls -la muestra -rwsr-xr-x (la 's' en lugar de 'x' en el grupo de permisos del propietario).env aparece bajo la categoría SUID con el técnica Shell: env /bin/sh -p. Recurso: https://gtfobins.github.ioauto_deploy.sh y la eliminación también: solo Ctrl+C. Las IPs son siempre del rango 172.17.0.0/16 (red bridge de Docker). Ideal para practicar sin límites de tiempo ni de instancias concurrentes.Server: Apache/2.4.52 (Ubuntu), el título de la página y las flags de las cookies. El flag httponly not set en PHPSESSID indica que la cookie de sesión es accesible desde JavaScript, lo que haría posible el robo de sesión mediante XSS además de la SQLi.? o :nombre) al servidor de base de datos, que la compila; luego se envían los datos del usuario por separado. El servidor de BD trata los datos siempre como valores literales, nunca como código SQL, imposibilitando la inyección. En PHP con PDO: $stmt = $pdo->prepare("SELECT * FROM users WHERE user=? AND pass=?"); $stmt->execute([$user, $pass]);. En MySQL nativo: PREPARE stmt FROM 'SELECT * FROM users WHERE user=?'; EXECUTE stmt USING @user;