Natas Nivel 18 a 19
Nivel oficial: http://natas18.natas.labs.overthewire.org
Este nivel introduce una vulnerabilidad clasica de gestion de sesiones: el servidor genera identificadores de sesion (PHPSESSID) como enteros dentro de un rango muy pequeno (1-640). Un atacante puede iterar ese espacio de forma automatizada hasta encontrar la sesion activa del administrador.
Este nivel forma parte del wargame Natas de OverTheWire, un entorno de laboratorio legal y autorizado para practicar seguridad web.
Objetivo
Obtener la contrasena del nivel 19 (<pass_natas19>) accediendo con los privilegios de administrador sin conocer su contrasena, solo adivinando su PHPSESSID.
Que aprendes
| Concepto / Comando | Para que sirve |
|---|---|
curl -b "PHPSESSID=<n>" | Enviar una cookie de sesion arbitraria en una peticion HTTP |
| Fuerza bruta de espacio pequeño | Iterar un rango finito de valores hasta encontrar el valido |
| Deteccion por contenido de respuesta | Identificar la sesion correcta comparando la respuesta HTML |
grep sobre salida de curl | Filtrar respuestas que contengan texto indicativo de exito |
Secuencia bash for / seq | Generar rangos numericos para automatizar peticiones |
Concepto clave
Identificadores de sesion predecibles (OWASP A07: Identification and Authentication Failures).
Un PHPSESSID seguro debe ser un token criptograficamente aleatorio de entropia alta (128 bits o mas). Cuando en su lugar se usa un entero secuencial o de rango acotado, el espacio de busqueda se vuelve trivialmente iterable. El atacante no rompe cifrado: simplemente prueba cada entero posible como si fuera ese usuario.
Patron general:
- El servidor asigna
PHPSESSID = entero entre 1 y N(aqui N = 640). - La sesion del admin existe en el servidor con alguno de esos valores.
- Enviar cada valor como cookie y comparar la respuesta revela cual pertenece al admin.
Este ataque no requiere interaccion con el formulario de login; explota directamente el mecanismo de reconocimiento de sesion del servidor.
Paso a paso
1. Reconocimiento inicial
Accede al nivel con las credenciales anteriores y observa el formulario de login. Mirando el codigo fuente (o la descripcion del nivel) se confirma que el rango de PHPSESSID es 1-640.
2. Script de fuerza bruta en bash
for i in $(seq 1 640); do
resultado=$(curl -s \
--cookie "PHPSESSID=$i" \
-u natas18:<pass_natas18> \
http://natas18.natas.labs.overthewire.org/)
if echo "$resultado" | grep -q "You are an admin"; then
echo "[+] PHPSESSID admin encontrado: $i"
echo "$resultado" | grep "Password"
break
fi
doneLa cadena que indica exito ("You are an admin") puede variar ligeramente; inspecciona el HTML de la pagina para confirmar el texto exacto antes de lanzar el script.
3. Alternativa en Python (mas rapida por conexiones paralelas)
import requests
url = "http://natas18.natas.labs.overthewire.org/"
auth = ("natas18", "<pass_natas18>")
for i in range(1, 641):
r = requests.get(url, auth=auth, cookies={"PHPSESSID": str(i)})
if "You are an admin" in r.text:
print(f"[+] PHPSESSID: {i}")
print(r.text)
breakAviso: el texto exacto de la condicion de exito puede requerir ajuste fino contra el reto en vivo. Inspecciona la respuesta de una sesion normal vs una de admin para calibrar el filtro.
4. Leer la contrasena
Una vez identificado el PHPSESSID correcto, la respuesta contendra la contrasena de natas19:
Password: <pass_natas19>
Por que funciona
El servidor PHP crea sesiones con session_start() y almacena en memoria o disco que el usuario con PHPSESSID=X es admin. Al recibir una cookie, PHP simplemente busca ese ID en su almacen de sesiones y devuelve el estado asociado, sin verificar que la IP o el navegador coincidan con quien creo la sesion originalmente.
Cuando el espacio de IDs es 1-640, hay exactamente 640 peticiones a probar. Incluso con latencia de red, el ataque termina en segundos. Si el ID fuera un UUID4 o un token de 128 bits, el mismo enfoque seria computacionalmente inviable.
Errores comunes
| Error | Causa | Solucion |
|---|---|---|
| El script no encuentra nada en rango 1-640 | El texto de deteccion no coincide con el HTML real | Hacer una peticion manual con curl -v y leer el cuerpo de respuesta para encontrar la cadena correcta |
curl devuelve 401 siempre | Falta la autenticacion HTTP basica del wargame (-u natas18:<pass>) | Añadir -u natas18:<pass_natas18> a cada peticion |
| El script es muy lento | Curl secuencial con latencia alta | Usar Python con requests.Session() o paralelizar con xargs -P |
| La sesion de admin no existe en el momento de la prueba | El servidor reinicia sesiones periodicamente | Relanzar el script; la sesion del admin se regenera automaticamente en estos wargames |
Pasar al siguiente nivel
Usa la contrasena obtenida (<pass_natas19>) para acceder a:
http://natas19.natas.labs.overthewire.org/
con usuario natas19 y la contrasena encontrada.