Natas - [OverTheWire]

Cover Image for Natas - [OverTheWire]
Marmeus
Marmeus

Table of Contents

    Introducción

    El wargame de Natas esta diseñado para aprender sobre vulnerabilidades web, estas vulnerabilidades se irán haciendo más sofisticadas con forme subas de nivel. Además, al igual que en Bandit para poder pasar al siguiente nivel tendrás que resolver los retos para poder obtener la contraseña del siguiente nivel.

    Para comenzar hay que acceder al siguiente enlace, introduciendo como usuario y contraseña natas0.

    natas0.natas.labs.overthewire.org

    Por cada nivel, tendrás que cambiar el número en el sub-sub-subdominio para poder acceder al siguiente reto.

    Level 0

    Solución:

    Si pulsamos Click derecho en la web y apretamos el botón de “Ver código fuente de la página”podremos observar en los comentarios del HTML la clave para el “Level 1”.

    Level 1

    Solución:

    El shortcut para ver el código fuente de la página web en cualquier navegador es Ctrl+U, pulsando esta serie de botones podremos acceder al contenido de la web y por lo tanto a la contraseña para el level 2.

    Level 2

    Solución:

    Viendo el código fuente se puede apreciar que existe una imagén llamada “pixel.png”.

    Si accedemos con el navegador a la dirección donde esta almacenada la web, podemos ver que realmente se trata de un punto blanco en mita de la patanlla.

    Curiosamente, si accedemos a la carpeta “files/” nos encontramos con un archivo llamado “users.txt”

    que tiene las credenciales para el Level 3.

    Level 3

    Antes de empezar con este nivel quiero decir, que si tenéis un antivirus es posible os salga este error impidiendos continuar con los retos. Para solucionarlo, desactivar el antivirus y ya podréis acceder a la web.

    Solución:

    He de decir que el comentario en este caso, es bastante clave para resolver el reto. Esta haciendo referencia al fichero “robots.txt” que tienen todas las webs para evitar que los buscadores como Google lo indexen y no salga en las búsquedas de Google.

    Accediendo al fichero “robots.txt” encontramos una carpeta “s3cr3t”

    la cual contiene el fichero “users.txt” con las credenciales para el Level 4.

    Level 4

    Solución:

    La pista de este reto está en que si provienes de una pestaña nueva, no vienes de ningún sitio, por lo que implica que esta leyendo el campo “Referer” de HTTP. El campo “Referer” es usado por HTTP para indicar la página web que se ha visitado anteriormente.

    Para engañar al servidor y hacerle creer que venimos de natas5, podemos usar la opción del firefox de reenviar una request. Para ello en network, seleccionamos el fichero raíz (“/”) y pulsamos el bontón “Edit and Resend”.

    Editamos este fichero añadiendo el campo “Referer” con la URL que ponía en el enunciado y pulsamos enviar.

    El resultado estará en la pestaña “Response” al lado de la pestaña “Headers” editada anteriormente, con la contraseña para el Level 5.

    Level 5

    Solución:

    Una vez que hemos entrado a la web, si nos vamos a las cookies hay una cookie llamada “loggedin” que podemos intuir que si estas logeado la cookie estará a 1.

    Entonces, si cambiamos la cookie “loggedin” a 1 y recargamos la página web obtendremos la contraseñas para el Level 6.

    Level 6

    Solución:

    En este reto podemos ver en el código fuente que para poder entrar necesitamos enviar un “secret” con la contraseña guardada en el archivo “includes/secret.inc”.

    Si vamos al archivo, a simple vista no veremos nada. Sin embargo, inspeccionando el código fuente podremos ver el contenido de $secret.

    Ahora, introduciendo el valor de “secret” nos permitirá obtener la contraseña para el Level 7.

    Level 7

    Solución:

    Haciendo varias pruebas se puede dar a entender que la ruta de un fichero introducida por el campo “?page” a través del método GET es leído ese fichero y mostrado por pantalla.

    Entonces, si queremos leer la contraseña del natas8, introducimos la ruta comentada en la imagen de arriba y obtendriamos la contraseña para el Level 8.

    Level 8

    Solución:

    Lo que se puede ver en el código fuente, es la clave cifrada en base64, después invierte la cadena con “strrev” y finalmente transforma el hexadecimal en binario.

    Para descifrar la clave tenemos que realizar todo lo anteriormente dicho en orden inverso. Esto se puede hacer mediante la shell de php.

    php -a

    Finalmente, introducimos el código y obtenemos la contraseña para el Level 9.

    Level 9

    Solución:

    Lo que hace esta web ejecutar el comando “grep” de Linux introduciendo como parámetro el valor que escribamos en el formulario.

    Como no tiene ningún tipo de sanetización para evitar escapar el comando y ejecutar cualquier otra cosa. Si introducimos “; cat /etc/natas_webpass/natas10 #” le estamos diciendo a la shell que esta ejecutando grep, que finalice el comando grep sin ningún fichero al que leer, que imprima el contenido de la contraseña10 y finalmente, con el “#” indicamos que todo que exista después del cat no sea interpretado por la shell.

    Level 10

    Solución:

    Como se puede apreciar tanto en el enunciado del reto, como en el código fuente de la web. Se trata de ralizar lo mismo, simplemente que ahora los parametros introducidos por el formulario, estarán filtrados y no se permitirán los caracteres especiales ([];|&).

    No obstante si introducimos “. /etc/natas_webpass/natas10 #” estamos indicándole a grep con el “.” que haga “mach” con cualquier carácter que se encuentre en el fichero de natas10, obteniendo la contraseña del Level 11.

    Level 11

    Solución:

    Como podemos ver, al entrar a la web nos proporciona con una Cookie la cual esta cifrada con XOR como dice el enunciado.

    La desventaja que tiene el cifrado XOR es que si usamos XOR para cifrar un texto con una contraseña, si volvemos aplicar XOR con el criptograma obtenido y el texto plano, obtenemos la contraseña con la que se cifra todo. Y eso es lo que vamos ha hacer. Como sabemos que la cookie es un array cuyos atributos son: “showpassword”, que por defecto esta a “no” y el atributo “bgcolor” que por defecto es “#ffffff”. Tenemos que transformarlo en json y la Cookie con el criptograma decodificarla de base64.

    Después, lo que tenemos que hacer es por cada carácter que tiene tanto el criptograma como el texto plano realizar un XOR, que es lo que hace la función xor_encript().

    Finalmente, ejecutamos dicha función con la Cookie cifrada y el texto plano, devolviendonos la contraseña.

    Como podemos ver, la clave de cifrado no es todo lo larga que es el texto a cifrar, sino que es la misma, pero se va repitiendo varias veces.

    Ahora , usando el mismo script, ejecutamos la misma función pero introduciendo la clave que hemos obtenido anteriormente y el el texto que queremos cifrar. En este caso será el objeto json con el atributo “showpassword” inicializado a “yes”. Después, la salida de la función hay que cambiarla a base64, para ello uso el “base64_encode” que es como originalmente estaba cifrada la cookie.

    El output resultante será la cookie que tenemos que modificar en el navegador.

    Donde al recarga la página web, obtendremos la contraseña para el Level 12.

    Level 12

    Solución:

    Una de las formas para poder superar este reto necesitamos subir un archivo “.php” que lea la contraseña y la muestre por pantalla. Sin embargo, todo lo que subimos lo renombra a una string aleatoria y le cambia la extensión “.jpg”, todo esto se puede ver en el input del formulario “.jpg”

    El archivo que queremos subir es el siguiente. Simplemente, lee la contraseña para natas14 y lo muestra por pantalla.

    Antes de subir el archivo, en mi caso he usado Burp Suit, para interceptar la petición al servidor y poder modificar todo lo necesario.

    Como se puede ver en la request, el nombre del archivo ha cambiado y la extensión también. Entonces, simplemente con modificar la extensión a .php y enviar la request.

    El archivo resultante se habrá subido correctamente.

    Finalmente, accediendo a la ruta donde se ha subido el fichero podemos encontrarnos con la contraseña del Level 13.

    Level 13

    Solución:

    Seguimos con la misma historia de subir un archivo .php para poder obtener la clave. Sin embargo, en este caso hay una función llamada “exif_imagetype” que comprueba los primeros bytes del fichero para saber si es o no una imagen.

    Para hacer creer a la función de que se trata de una imagen, bastaría con añadir al principio del fichero los siguientes caracteres “FF D8 FF E0”. En mi caso he usado Ghex, que permite insertar valores hexadecimales de forma sencilla y sin mucha complicación.

    Solo queda subir el fichero, cambiarle la extensión para que se pueda ejecutar y acceder a el para obtener la contraseña para el Level 14.

    Level 14

    Solución:

    Como se puede apreciar en el siguiente trozo de código, todo lo introducido en en los campos del formulario “Username” y “Password” son usados en la query contra la base de datos. Debido la falta de sanetización y uso de filtros podenmos llegar a la conclusión que para obtener la contraseña para el siguiente nivel, es necesario realizar un ataque de SQL injection.

    Para que la autenticación sea exitosa necesitamos que la ejecución de la query proporcione alguna fila. Para ello, le decimos que devuelva todo que concuerde con nombre de usuario vacío (“”) o algo que sea siempre cierto, este es el caso del (or ‘1’ = ‘1’) y para que no compruebe la contraseña escribimos # comentando todo lo que haya después.

    Level 15

    Solución:

    Seguimos con los retos de SQL injection, pero ahora estamos ante un reto de blind SQLi.

    Para obtener la contraseña y pasar el Level 16, necesitamos crear un script que vaya letra por letra comprobando cuales son cada una de las letras que componen la contraseña almacenada en la base de datos.

    Level 16

    Solución:

    Este reto es más complicado que en el Level 11. Esto es debido a que no podemos escapar de ninguna de las formas del parámetro necesario para grep -i.

    Sin embargo, porque se permite el uso del símbolo del dollar y los paréntesis, podemos ejecutar comandos de bash cuyo resultado servirá para el filtrado de grep.

    Entonces, lo que podemos hacer es como en blind sqli, ir obteniendo uno a uno todos los caracteres que componen la contraseña para el Level 17. Para ello, vamos a comprobar que la contraseña no empieza por la letra “c” y así hacer las sentencias con la palabra “hola”.

    Si enviamos “$(grep -E ^c.* /etc/natas_webpass/natas17)hola” y no aparece nada por output, significaría que empieza por c. Esto funciona, porque lo que grep esta haciendo es buscar en el fichero natas17, cualquier palabra o en este caso línea que comience por la letra “c”.

    Si fuese el caso, pasaría la contraseña entera al grep de la web, por lo que el filtrado del grep de la web sería el siguiente. Busca en el fichero “dictionary.txt” todas las palabras que contengan <LaContraseñaEntera>+hola, como la contraseña es de 32 caracteres es imposible que exista una palabra con dicha longitud y por tanto no saldría nada como output.

    Finalmente, creamos un script que vaya comprobando por fuerza bruta todos los posibles caracteres alfanuméricos y comprobando si la contraseña empieza por uno de ellos.

    Level 17

    Solución:

    Hemos vuelto al SQLi. Sin embargo, esta vez no se nos ofrece ningún tipo de output, tras haber realizado la query. No obstante, existe la Time based SQLi, que consiste en realizar queries que duren un determinado periodo de tiempo y dependiendo del tiempo que se tarde en finalizar la ejecución de la query podremos afirmar que la respuesta es true o false.

    Básicamente como se puede apreciar en el script realizado en la siguiente imagen, estamos realizando el mismo tipo de query que antes con el ligero cambio de que si los caracteres que componen la contraseña, la base de datos esperará dos segundos, sino no esperará ningún intervalo de tiempo.

    El problema con este script es que necesita muy buena conexión a Internet, si se produce un retardo debido la lentitud de la conexión, el script lo tomará como correcto y la contraseña se irá a la porra.

    Level 18

    Solución:

    Analizando el código vemos una variable global llamada “maxid” que se supone que será el número máximo de ids que puede tener la página.

    Y cuando te logeas por primera vez, en la línea “session_id(createID….”

    se te asigna una ID generada aleatoriamente.

    Para afirmarlo, basta con entrar con un usuario y contraseña que nos inventemos y en el apartado de cookies de nuestro navegador podremos apreciar como se nos ha asignado una cookie.

    Básicamente para resolver el reto necesitamos de logearnos un montón de veces con diferente número de sesión, hasta llegar con uno el cual sea el correspondiente del administrador. Para ello, me he creado el siguiente script, que al ejecutarlo realizará todos esos intentos y mostrará por pantalla el número de sesión para poder acceder como administrador.

    Ejecutamos el código y una vez terminado, simplemente cambiamos la cookie de sesión

    y recargando la página obtendremos la contraseña para el Level 19.

    Level 19

    Solución:

    Una vez que hemos accedido a la web, obtenemos una cookie que debido a los caracteres que lo componen quizás puede ser hexadecimal.

    Buscando en Internet un decodificador de hexadecimal a ASCII

    vamos que la contraseña es una combinación de un número aleatorio de 0 a 640 y el nombre. Para pasarnos este reto, hay que modificar el script anterior que adjunte nuestro nombre y después lo cifre en hexadecimal.

    Finalmente, ejecutamos el script que nos dará la cookie necesaria para obtener la contraseña del Level 20.

    Level 20

    Solución:

    Este reto requiere mucho de mirar profundamente en el código para saber que introducir y más importante como introducirlo en el formulario para obtener la clave del siguiente nivel.

    Básicamente el método write guarda en un archivo cuyo nombre es “mysess_” más nuestro identificador de sesión. En el se guardará una línea que contendrá “name “ más lo que nosotros le pasemos a través del formulario o al menos eso parece que es lo único que se puede hacer.

    La función “myread” añade al array las líneas que ha leído en el fichero. Tomando la primera palabra como nombre de la variable y la segunda parte de la string como valor de la variable.

    La función “print_credentials” comprueba que existe una variable de sesión llamada “admin” y que su valor es 1.

    El truco para pasarnos este reto es enviale un salto de línea de tal forma que la segunda línea sea

    “admin 1”. Para ello enviamos “natas20.natas.labs.overthewire.org/?debu&name=admin%0Aadmin+1” así a la hora de almacenar los datos en el fichero, tomará “admin\nAdmin 1” como valor de la variable “name” y a la hora de leerlo se leerán como dos lineas diferentes y por tanto dos variables de sesión diferentes.

    Level 21

    Para obtener las credenciales para el siguiente nivel necesitamos poner en nuestras variables de sesión una variable “admin” cuyo valor sea 1.

    En este caso la única forma que tenemos de hacerlo es a través de este formulario que utiliza las variables de sesión para cambiar el estilo del div.

    Al abrir el “sourcecode” encontramos la debilidad en el primer if de todos. La debilidad consiste en que todas las variables que se envíen durante el REQUEST serán almacenadas como variables de sesión, junto con sus correspondientes valores.

    Para poder realizarlo podemos editar el HTML de la web, añadiendo un nuevo input en el formulario y enviarlo contra el servidor.

    Una vez enviado el formulario, copiamos la sessionID almacenada en nuestro navegador y

    y la copiamos en la pestaña de la página principal de este reto y recargamos la página obteniendo la contraseña para el Level 22.

    Level 22

    El primer fragmento de código indica que si enviamos por GET la variable “revelio”, pero la variable de sesión “admin” no esta inicializada a 1 nos redirige a la pantalla principal.

    Sin embargo, la siguiente porción de código si nosotros enviamos la variable “revelio” se nos mostrarán las credenciales para el siguiente nivel.

    Para poder ver las credenciales, antes de que se produzca el “redirect” podemos usar Burp Suit y capturar la respuesta. Para ello capturamos la request y la enviamos al apartado repeater, donde finalmente enviaremos la request y obtendremos las credenciales para el Level 23.

    Level 23

    Strstr, encuentra la primera aparición de un string en una cadena de caracteres, en este caso busca ‘iloveyou’ y devuelve todo lo que había antes de esa cadena.

    Antes de nada, quiero decir que este reto me salio un poco a la chiripa, porque sigo sin entender lo siguiente.

    En este caso, si enviamos una cadena que contiene un número mayor que 10 concatenado a la cadena “iloveyou” nos da la contraseña para el level 24. Esto debe ser porque se asigna el resultado de strstr a la variable “passwd”, en este caso sería nuestro 11, que será evaluado en la siguiente parte del if, resultando en un true y mostrando las credenciales.

    He intentado buscar respuestas ejecutando el código por mi cuenta para ver si la variable se modifica durante la ejecución, pero parece ser que no. :/

    Level 24

    Como se puede ver en el código, para poder obtener la contraseña del siguiente nivel es necesario enviar la propia contraseña del Level 25 algo que para nosotros es imposible de obtener.

    Lamentablemente, el if esta trufado, porque si nosotros pasamos un vector como argumento de la comparación, la función “strcmp” devolverá un error y “false”, el cual se convertirá a true por el signo de exclamación; obteniendo las credenciales para el Level 25.

    Level 25

    Este reto esta formado por varias debilidades, la primera de ellas consiste en el “path traversal” que se obtiene del uso de la variable “lang” enviada durante el cambio de idioma. Sin embargo, no podemos obtener directamente la clave almacenada en el la ruta “/etc/natas_webpass/natas26” debido a que el programa comprueba si existe la cadena “natas_webpass” en nuestra string.

    No obstante, podemos modificar el campo “User-Agent” de nuestra petición para que introduzca en el ficheros de logs la contraseña del siguiente nivel.

    Para hacer todo esto nuestra request tendría que ser algo tal que así:

    Primero de todo, como los documentos están en la carpeta “language” tenemos que poner “….//” para así cuando se realice el remplazo se quede la siguiente dirección “../logs/natas_neton.log”. Además, como la PHPSESSID es usada para crear el archivo, la podemos cambiar creando el archivo que queramos. Y finalmente, en el “User-Agent” le decimos que incluya todo el contenido del fichero natas26.

    De esta forma, enviando la solicitud obtendremos en la web todo lo que se ha guardado en el archivo .log y con ello la contraseña para el level 26.

    Level 26

    En este reto nos encontramos ante una web que dibuja lineas a partir de los valores que introducimos en el formulario.

    Como podemos ver en la función anterior, todas las rectas son almacenadas en nuestro navegador en una variable de sesión.

    Si decodificamos lo que hay en la variable “drawing” nos sale un array de arrays.

    En las siguiente función se puede observar como se llama a la función “unserialize”

    que si hacemos una búsqueda en el manual de PHP se puede observar que esta trufado, por lo que podemos aprovechar de esa debilidad y obtener la contraseña para el siguiente nivel.

    Para ello nos crearemos una clase Logger donde añadiremos el código malicioso a ejecutar.

    Como se puede ver, se trata del método constructor que hay en el código fuente de la página web, al cual le hemos inicializado las variables de “initMsg” Y “exitMsg”, para que sus valores sean impresos en un fichero “$file.php”, y una vez accedamos a la url donde se encuentra el fichero, se ejecuten los “include”s, mostrándonos la contraseña.

    Ejecutamos el fichero: $ php natas.php y añadimos el output en la variable de sesión “drawing” del navegador.

    Volvemos a acceder a la página web y después a la url del fichero, obteniendo así la contraseña para el level 27.

    Level 27

    En este reto volvemos otra vez a saltarnos las credenciales para obtener la contraseña para el siguiente nivel. Sin embargo, no podemos hacer ataques de SQLi como hemos hecho antes debido al uso de la función “mysql_real_escape” evitando que hagamos tipo cualquier escapada en la query.

    Por suerte, una vez que se ha comprobado las credenciales la contraseña ya no vale de nada, porque se piensa que no habrá ningún usuario con el nombre repetido.

    Como se puede ver en la función “dump_data” muestra las credenciales de todos los usuarios con el nombre introducido. Además, esta función no machea los usuarios estrictamente, lo que quiero decir es que si existe un usuario “pepito” y otro usuario llamado “pepito ” a la hora de hacer la comparación de nombres para la base de datos el nombre será el mismo.

    Entonces, lo que tenemos que hacer es crear un usuario, que de alguna forma, el nombre del usuario sea diferente a la base de datos y consigamos tener dos usuarios “iguales”.

    Una curiosidad que tiene que tiene mysql es el overflow de strings, que consiste en introducir una cadena de caracteres con una longitud mayor, que la definida en la columna de la tabla de la base de datos. Si pasa esto, mysql cogerá todos los caracteres hasta el máximo definido eliminando todos los restantes. Para nosotros esto es oro en paño, porque si creo un usuario con usuario suficientemente largo quizás lo tome como algo diferente.

    Para hacer pruebas y comprobar que es cierto, me he creado mi propia base de datos de mysql parecida a la que hay en OverTheWire pero con la longitud de las columnas más cortas.

    Por si quieres intentarlo en vuestro ordenador escribid esta serie de comandos para crear la base de datos a a través de mysql.

    sudo mysql -u root

    CREATE DATABASE pruebas;
    USE pruebas;
    create table users( user varchar(4), passwd varchar(4));

    Una vez creada la base de datos, vamos a poner la teoría en práctica.

    Como se puede ver en la anterior imagen, al sobrepasar el número máximo de caracteres permitidos en la columna (En este caso son cuatro) he conseguido crear un nuevo usuario. Y lo mejor es que si listamos el usuario ‘us’ saldrá más de uno.

    Finalmente, si realizamos esto a escala, conseguiremos las credenciales para el siguiente nivel. Ahora bien, como son 64 caracteres los definidos en la columna “username” vamos a ser un poco bestias y voy a poner unos 100 espacios y sobrepasar el limite impuesto en la definición de la tabla.

    python -c ‘print “natas28”+“%20”*100’

    Nota: Como los espacios se tienen que enviar por HTTP, el espacio en HTTP es %20.

    El resultado lo copiamos y lo sustituimos en Burp Suite a la hora de enviar la request con las credenciales.

    Finalmente, volvemos otra vez a la web e introducimos “natas28” obteniendo las credenciales para el level 28.

    Level 28

    Aquí tenemos una maravilloso reto el cual es muy difícil, pero al principio te ríes y eso es debido a que estamos ante un ataque de SQLi contra una base de datos que almacena chistes sobre informáticos. Aquí tenéis unos cuantos para que os divirtáis.

    Para evitar alargar mucho este reto, básicamente no se pueden escapar caracteres ya que como en niveles anteriores hay métodos que nos lo impiden. También, he de decir que cuando realizas una consulta a la base de datos a través del formulario se nos reenviá una página intermedia, supuestamente la que se encarga de sanetizar la string, la cual será usada contra la base de datos y finalmente se nos devuelve a la página principal con una URL muy larga. Es curioso porque si modificas la URL salé el siguiente error.

    Esto implica que estamos ante un cifrado de bloques, lo que no sabemos es de que tipo se trata. Es lo que tenemos que averiguar ;D

    Primero me he creado un script para poder averiguar el tamaño del bloque. Lo que hace es enviar requests a la base de datos enviando cada vez un número mayor de caracteres y luego comprobar el tamaño de la respuesta. He de decir que la longitud de la respuesta es apartir de .../search.php/?query=.

    La conclusión que se puede sacar a partir de las siguientes imágenes, es que el tamaño del bloque es de 16 bytes.

    <Más resultados>

    Una vez sabemos el tamaño del bloque falta como varía la cadena de caracteres para saber con que tipo de cifrado en bloque estamos tratando. Si uno se fija bien en la siguiente imagen se dará cuenta de que los dos primeros bloques de cada una de las queries contiene siempre los mismos datos.

    Eso quiere decir que cada uno de los bloques es cifrado independientemente del otro, por lo que estamos ante un ECB (Electronic CodeBook). Como ECB encripta siempre el texto plano de la misma forma, no oculta bien el patrón de los datos. ¿Qué quiero decir con esto? Pues que si estoy cifrando un texto y un atacante tiene acceso a la “máquina de cifrado” el atacante cifrará sus propios textos planos e irá comparando su criptograma con el de la victima. De esta forma, irá viendo que el texto introducido va coincidiendo con el texto cifrado de la victima, obteniendo finalmente el texto plano de la victima.

    Además, la otra pista obvia, es como los dos primeros bloques siempre son los mismos; significa que hay algo antes de lo que nosotros introducimos por el formulario, en este caso podría ser el principio de la query que se ejecutará contra la base de datos.

    También, en la siguiente imagen nos damos cuenta que una vez hemos llegado a la longitud 10 de la query el bloque tres deja de cambiar, por lo que hemos sobrepasado el tamaño del bloque.

    Sabiendo esto, podemos descifrar el contenido que hay después de lo que nosotros introducimos por pantalla, ya que cuando la longitud de la query es nueve, en el último byte del bloque se encuentra el primer carácter que va después de lo que nosotros introducimos en el formulario. Por lo que haciendo fuerza bruta sobre ese carácter podemos saber de que carácter se trata.

    Para ello es necesario un nuevo script que vaya probando todas los caracteres posibles hasta encontrar con el carácter cifrado.

    El resultado del programa es el siguiente:

    Lo que quiere decir que la query alomejor es algo como: “select * from chistes where text like ‘%%’ ”. De esta forma se obtendrá todo lo que contenga lo que introduzcamos en el formulario.

    Ahora bien, una forma de resolver este reto sería cifrar el segmento de query que añada la contraseña de natas28 al resultado cuando se ejecute la query. El fragmento tendría que ser como el siguiente: “ ‘ UNION SELECT password from users; #”. Para cifrarlo necesitamos saber cuantos bloques va a ocupar nuestro fragmento, para después saber hasta que punto tenemos que copiar del criptograma cifrado.

    Necesitaremos un total de 3 bloques. Ahora toca, obtener el segmento cifrado, combinarlo con una query buena y finalmente enviarlo a la web para que nos devuelva la contraseña para el level 29.

    Una vez tenemos el script y obtenemos la contraseña.

    Level 29

    Para este reto tenemos que enfrentarnos al lenguaje perl, al menos eso parace al ver la portada “Hey kid, do you rememeber perl right?, do you want to go all down? Read up!”

    Por lo que podemos ver al seleccionar algo del menú desplegable, son documentos sobre cosas de perl.

    Tampoco hay nada más interesantate. Pero lo que si que es interesante es como pasa el nombre de los ficheros.

    Parece ser que es el nombre del fichero entero, como se puede ver en la URL de la web.

    Seguramente, exista alguna forma de escapar el nombre del fichero a introducir de epara ejecutar algún RCE.

    Buscando mil formas de escapar resulta que si introducimos “|”, el comando a ejecutar y “%00” nos ejecuta el comando que queramos. (“%00” en muchos lenguajes se interpreta como final de cadena”).

    Curiosamente, si queremos añadir en el echo código html, es “neutralizado” y no nos muestra el resultado.

    Historias aparte, estaría saber que hay dentro del contenido de “index.pl”. Para ello, con un simple cat podemos obtener su contenido.

    Como se puede ver, el resultado no es muy bonito a la vista, pero obtenemos información importante. A la hora de detectar “natas” en el input nos devolverá un “meeeeeeep!”, por lo que tenemos que transformar la query de alguna forma para que pase el if y luego se sanetice con la función “escapeHTML()” que elimina todo el contenido HTML.

    Escribiendo: http://natas29.natas.labs.overthewire.org/index.pl?file=|cat%20/etc/nat%22as_webpass/nat%22as30%00

    Donde %22 son comillas dobles y %20 podemos saltarnos el if y obtener la contraseña para el level 30.

    Level 30

    Seguimos con los clásicos, saltarnos el formulario de credenciales para obtener la contraseña. Sin embargo, ahora toca pelearse con perl. Yujuuu! y yo pensando que nor servía para nada :P

    Como se puede ver arriba el programa recibe los parámetros del formulario y escapa los caracteres para evitar ataques de SQLi. No obstante, buscando en Internet hay dos posts de stackOverflow y stackExchange que detallada la debilidad que tiene este método.

    Básicamente, si el método “quote()” recibe como parámetro un listado de objetos, usará el segundo objeto como un identificador del primer objeto. Por ejemplo, si nosotros le pasamos una string y le indicamos como segundo objeto que el primer parámetro no es una string, quote devolverá el primer parámetro sin añadirle comillas.

    Enviamos la modificación de la request y obtendremos la contraseña para el Level 31.

    Level 31

    Como se pueden ver en las imágenes anteriores estamos ante una página web que te crea una bonita tabla partir del archivo CSV que le envíes. Como podéis en la siguiente imagen, el código es bastante sencillo, abre el fichero y la primera línea la toma como header de la tabla y las demás, como datos que para rellenar la tabla.

    Como se puede ver en este documento de la black2016 los métodos upload(), param() están trufados y nos podemos aprovechar para obtener las credenciales del siguiente nivel. Todo esta explicado en el documento, pero bueno, lo explico de dotas formas. Lo que pasa es lo siguiente:

    En la segunda línea, el método “upload()” comprueba que al menos uno de de los valores de “file” es un atributo. Si nosotros subimos un archivo y un escalar con el mismo parámetro funcionará igualmente. Además, en la tercera linea el método “param()” devuelve una lista con todos los valores cuyo nombre de atributo sea ‘file’. Sin embargo, si asignamos un escalar primero, se guardará en $file, en vez del fichero. Finalmente, en el bucle “while” si hemos introducido en “$file” la string “ARGV” el bucle while iterará sobre cada uno de los argumentos enviados en la request, ejecutando la llamada “open()” a cada uno de los parámetros, por lo que abrirá el archivo que le pasamos. Finalmente, la request tiene que quedar de la siguiente forma:

    Que al enviarla obtendremos las credenciales para el level 32.

    Level 32

    Si en efecto, no te has vuelto loco. El nivel 32 es el mismo que el nivel 31. Es más, vamos a comprobar el código fuente de la web, para ver si hay algo distinto.

    No hace falta que gastes tiempo mirándolo, ya lo he gastado yo y efecto, son idénticos. Y ahora mismo puede que tu mente este pensando “Pues ya estaría, ejecutamos el mismo exploit que antes y a seguir” y no irías mal encaminado. No obstante, el mismo exploit no va, así que tenemos que buscar alguna variación del exploit anterior para obtener las credenciales para el siguiente nivel.

    Vale, después de morirme un rato, puedes introducir código en la URL de la web, que será ejecutado por el sistema, de la misma forma que introdujimos el archivo a imprimir en el nivel anterior.

    Básicamente estoy haciendo “ls .” mostrando todos los archivos de la carpeta, como podéis ver en la siguiente imagen.

    Como se puede ver hay un archivo llamado “getpassword”, si se procede a ejecutarlo obtendremos la contraseña para el Level 33.

    Level 33

    ¡¡¡Por fin!!! Ya estamos en el último reto. Vale, ahora bien, como se puede ver en el código de la siguiente imagen.

    Todo lo que subamos se guardará en la carpeta “natas33/upload”, una vez el archivo se ha subido, se comprobará si el hash coincide con el que hay en la variable $signature se ejecutará el fichero con todo lo que había dentro.

    Un problema que tiene este reto y es como no se tiene que resolver es el uso de path traversal. Esto es debido a que existe una carpeta llamada “/natas33-new” donde natas33 tienes permisos de escritura, entonces podríamos subir un archivo a dicha carpeta y después acceder a él para obtener la contraseña. Para ello, primero deberíamos de subir un fichero que contenga la siguiente línea de código “”. Cuando lo subamos tenemos que interceptar la request y modificar el path donde se almacenará el fichero.

    Finalmente, accedemos a la siguiente URL:

    http://natas33-new.natas.labs.overthewire.org/index.php?c=cat%20/etc/natas_webpass/natas34

    Así le estamos indicando que use cat y lea el archivo donde se encuentra la contraseña del level 34. Finalmente, obteniendo la última credencial de los retos de Natas (al menos por ahora) y acabando con este wargame.

    Finalmente, me gustaría decir que estos retos han empezado siendo sencillitos pero que se han convertido en una autentica tortura donde he aprendido mucho y he disfrutado mucho resolviendo mucho, cada uno de ellos. :D

    Contraseñas

    0)  natas0  
    1)  gtVrDuiDfck831PqWsLEZy5gyDz1clto  
    2)  ZluruAthQk7Q2MqmDeTiUij2ZvWy2mBi  
    3)  sJIJNW6ucpu6HPZ1ZAchaDtwd7oGrD14  
    4)  Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ  
    5)  iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq  
    6)  aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1  
    7)  7z3hEENjQtflzgnT29q7wAvMNfZdh0i9  
    8)  DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe  
    9)  W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl  
    10)  nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu  
    11)  U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK  
    12)  EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3  
    13)  jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY  
    14)  Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1  
    15)  AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J  
    16)  WaIHEacj63wnNIBROHeqi3p9t0m5nhmh  
    17)  8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw  
    18)  xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP  
    19)  4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs  
    20)  eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF  
    21)  IFekPyrQXftziDEsUr3x21sYuahypdgJ  
    22)  chG9fbe1Tq2eWVMgjYYD1MsfIvN461kJ  
    23)  D0vlad33nQF0Hz2EP255TP5wSW9ZsRSE  
    24)  OsRmXFguozKpTZZ5X14zNO43379LZveg  
    25)  GHF6X7YwACaYYssHVY05cFq83hRktl4c  
    26)  oGgWAJ7zcGT28vYazGo4rkhOPDhBu34T  
    27)  55TBjpPZUUJgVP5b3BnbG6ON9uDPVzCJ  
    28)  JWwR438wkgTsNKBbcJoowyysdM82YjeF  
    29)  airooCaiseiyee8he8xongien9euhe8b  
    30)  wie9iexae0Daihohv8vuu3cei9wahf0e  
    31)  hay7aecuungiuKaezuathuk9biin0pu1  
    32)  no1vohsheCaiv3ieH4em1ahchisainge  
    33)  shoogeiGa2yee3de6Aex8uaXeech5eey  
    34)  shu5ouSu6eicielahhae0mohd4ui5uig