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 / ComandoPara que sirve
XOR con clave repetidaCifrado simetrico basico (y quebrantable)
Known-plaintext attackRecuperar clave cuando conoces plaintext + ciphertext
base64_decode / base64_encodeSerializar/deserializar la cookie en transito
DevTools → Application → CookiesInspeccionar y editar cookies desde el navegador
python3 -c / script PHP inlineCalcular 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 ApplicationCookies. 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

ErrorCausaSolucion
Clave recuperada parece aleatoria / sin patronCiphertext o plaintext con longitud incorrectaVerifica que el JSON usado es exactamente el que muestra el codigo del servidor, sin espacios extra
base64.b64decode lanza error de paddingCookie con URL-encoding (%3D en lugar de =)Decodifica URL primero: urllib.parse.unquote(cookie) antes de b64decode
Nueva cookie devuelve el mismo estado noLa longitud del ciclo de la clave calculada es incorrectaPrueba incrementando len_key de 1 en adelante hasta que el patron se repita exactamente
Error de autenticacion HTTP 401Credenciales de natas11 incorrectas o mal formateadas en curlRecuerda 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)

Conexiones