Natas Nivel 11 a 12
Nivel oficial: http://natas11.natas.labs.overthewire.org
Este nivel introduce criptografia simetrica mal aplicada: la aplicacion cifra una cookie JSON con XOR de clave repetida, pero expone suficiente informacion para romper el cifrado sin conocer la clave. Es un ejemplo clasico de ataque de texto plano conocido (known-plaintext attack).
Este wargame es un laboratorio legal y autorizado por OverTheWire. Toda practica aqui descrita tiene fines educativos y eticos.
Objetivo
Modificar la cookie data para que el servidor interprete "showpassword":"yes" y revele la contrasena de natas12.
Que aprendes
| Concepto / Comando | Para que sirve |
|---|---|
| XOR con clave repetida | Cifrado simetrico basico (y quebrantable) |
| Known-plaintext attack | Recuperar clave cuando conoces plaintext + ciphertext |
base64_decode / base64_encode | Serializar/deserializar la cookie en transito |
| DevTools → Application → Cookies | Inspeccionar y editar cookies desde el navegador |
python3 -c / script PHP inline | Calcular rapidamente XOR byte a byte |
Concepto clave
XOR con clave reutilizada y plaintext conocido es trivialmente roto.
La operacion XOR tiene la propiedad: A XOR B = C implica C XOR A = B y C XOR B = A.
Si el servidor calcula ciphertext = plaintext XOR key y tu conoces tanto ciphertext (la cookie) como plaintext (el JSON por defecto), entonces:
key = ciphertext XOR plaintext
Con la clave recuperada puedes cifrar cualquier plaintext nuevo, incluyendo uno con "showpassword":"yes".
Paso a paso
1. Obtener la cookie actual
Inicia sesion en natas11 con las credenciales natas11:<pass_natas11> y abre las herramientas de desarrollador del navegador (F12) → pestaña Application → Cookies. Copia el valor de la cookie data. Sera algo como:
ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw%3D
Decodifica URL-encoding si es necesario (reemplaza %3D por =, etc.).
2. Identificar el plaintext conocido
El codigo fuente de la pagina (accesible via “view-source” o el botton de natas) revela que el JSON por defecto es exactamente:
{"showpassword":"no","bgcolor":"#ffffff"}Este es tu plaintext conocido.
3. Recuperar la clave XOR (Python)
import base64
cookie_b64 = "ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=" # ajusta al valor real
ciphertext = base64.b64decode(cookie_b64)
plaintext = b'{"showpassword":"no","bgcolor":"#ffffff"}'
# XOR byte a byte: key = ciphertext XOR plaintext
# La clave se repite, por eso hacemos modulo sobre su longitud estimada
raw_key = bytes(c ^ p for c, p in zip(ciphertext, plaintext))
# La clave se repite; para verla completa tomamos el ciclo minimo
# (inspecciona raw_key y busca el patron que se repite)
print("Clave recuperada (raw):", raw_key)Observa el patron en raw_key: la clave se repite ciclicamente. Identifica el bloque minimo repetido (suele ser 4-8 bytes). Llamemosla key.
4. Cifrar el JSON modificado
import base64
key = raw_key[:len_key] # sustituye len_key por la longitud del ciclo
new_plain = b'{"showpassword":"yes","bgcolor":"#ffffff"}'
# XOR ciclico
new_cipher = bytes(p ^ key[i % len(key)] for i, p in enumerate(new_plain))
new_cookie = base64.b64encode(new_cipher).decode()
print("Nueva cookie:", new_cookie)Alternativa en PHP (si prefieres ejecutarlo en un entorno con PHP):
<?php
function xorEncrypt($data, $key) {
$result = '';
for ($i = 0; $i < strlen($data); $i++) {
$result .= $data[$i] ^ $key[$i % strlen($key)];
}
return $result;
}
$cookie_b64 = "ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=";
$ciphertext = base64_decode($cookie_b64);
$plaintext = '{"showpassword":"no","bgcolor":"#ffffff"}';
// Recuperar clave
$key = xorEncrypt($ciphertext, $plaintext);
echo "Clave: " . $key . PHP_EOL;
// Cifrar nuevo JSON
$new_plain = '{"showpassword":"yes","bgcolor":"#ffffff"}';
$new_cipher = xorEncrypt($new_plain, $key);
$new_cookie = base64_encode($new_cipher);
echo "Nueva cookie: " . $new_cookie . PHP_EOL;
?>5. Inyectar la cookie y leer la respuesta
Con curl directamente:
curl -u natas11:<pass_natas11> \
-b "data=<nueva_cookie_calculada>" \
http://natas11.natas.labs.overthewire.org/O bien edita la cookie en DevTools (doble clic sobre el valor → pega el nuevo valor → recarga la pagina). La pagina mostrara la contrasena de natas12.
Por que funciona
El servidor usa XOR con clave fija y repetida como unico mecanismo de “cifrado” de la cookie, sin MAC ni firma. Dado que el formato del JSON de estado inicial es predecible y fijo, un atacante con acceso a la cookie tiene todo lo necesario para resolver el sistema: key = ciphertext XOR plaintext. No hay secreto alguno que proteja el esquema cuando el plaintext es conocido.
Este es exactamente el escenario que rompio el cifrado RC4 en WEP (Wi-Fi) y que motiva el uso de esquemas autenticados como AES-GCM en lugar de XOR crudo.
Errores comunes
| Error | Causa | Solucion |
|---|---|---|
| Clave recuperada parece aleatoria / sin patron | Ciphertext o plaintext con longitud incorrecta | Verifica que el JSON usado es exactamente el que muestra el codigo del servidor, sin espacios extra |
base64.b64decode lanza error de padding | Cookie con URL-encoding (%3D en lugar de =) | Decodifica URL primero: urllib.parse.unquote(cookie) antes de b64decode |
Nueva cookie devuelve el mismo estado no | La longitud del ciclo de la clave calculada es incorrecta | Prueba incrementando len_key de 1 en adelante hasta que el patron se repita exactamente |
| Error de autenticacion HTTP 401 | Credenciales de natas11 incorrectas o mal formateadas en curl | Recuerda que curl -u espera usuario:contrasena sin espacios |
Pasar al siguiente nivel
La contrasena obtenida te da acceso a:
- URL:
http://natas12.natas.labs.overthewire.org - Usuario:
natas12 - Contrasena:
<pass_natas12>(la que obtuviste al inyectar la cookie)