CTF OverTheWire: Natas7

Continuamos con la serie de tutoriales del CTF Natas, ahora toca el turno de natas7.

Natas Level 6 → Level 7
Username: natas7
URL:      http://natas7.natas.labs.overthewire.org

Utilizamos la bandera obtenida en el reto anterior y accedemos a la URL indicada en las instrucciones del reto, veremos una pantalla como la siguiente.

Inspeccionamos el código fuente de la pagina y observamos un par de cosas interesantes:

Vemos dos hypervinculos (index.php?page=home y index.php?page=about) y un comentario que dice:

<!-- hint: password for webuser natas8 is in /etc/natas_webpass/natas8 -->

Dependiendo el valor del parámetro page el contenido de la pagina cambia, todo apunta a que estamos ante una vulnerabilidad de tipo Local File Inclusion, escribimos texto aleatorio solo para verificar la vulnerabilidad.

Efectivamente podemos ver la ruta del archivo php en el servidor (path disclosure), debido a esta vulnerabilidad podemos leer cualquier archivo al que el usuario que ejecuta el servidor web tenga acceso, por ahora solo nos centraremos en obtener la bandera del reto con http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8

La bandera para acceder a natas8 es DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe

En este reto aprovechamos un fallo de seguridad llamado Local File Inclusion, con el que es posible leer otros archivos que no son accesibles directamente en el servidor.

Happy hacking 🙂

Si te gusto comparte ...Share on Facebook
Facebook
Share on Google+
Google+
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin

#DailyCodingProblem: El producto de todos los elementos en el arreglo menos el elemento actual

https://www.dailycodingproblem.com/

Good morning! Here’s your coding interview problem for today.

This problem was asked by Uber.

Given an array of integers, return a new array such that each element at index i of the new array is the product of all the numbers in the original array except the one at i.

For example, if our input was [1, 2, 3, 4, 5], the expected output would be [120, 60, 40, 30, 24]. If our input was [3, 2, 1], the expected output would be [2, 3, 6].

Follow-up: what if you can’t use division?

Si ignoramos la restricción este problema es muy sencillo de resolver.

  • Iteramos el arreglo y calculamos el producto total de todos los elementos: 1 x 2 x 3 x 4 x 5 = 120
  • Iteramos nuevamente dividiendo el total entre cada uno de los elementos y guardamos esos resultados en nuevo arreglo: 120/1, 120/2, 120/3, 120/4, 120/5

La complejidad de esta solución seria O(2n) o simplemente O(n), pero debido a que el problema dice que no podemos usar la división las cosas se complican un poco mas.

Solución cuadrática

Sin usar la división la solución mas obvia es una solución cuadrática, iteramos el arreglo y por cada elemento vamos a ir acumulando el producto de esos valores menos el elemento i actual.

    int[] calculateProduct(int[] numbers) {
        int[] result = new int[numbers.length];
        // ...
        // ... logica para inicializar todos los valores de result en 1
        // ...
        for (int i = 0; i < numbers.length; i += 1) {
            for (int j = 0; j < numbers.length; j += 1) {
                if (i != j) {
                    result[j] *= numbers[i];
                }
            }
        }
        return result;
    }

Esta solución es muy fácil de entender pero no es para nada eficiente, O(n2), en la publicación anterior ya analizábamos otra solución cuadrática y veíamos que era un problema con inputs de datos muy grandes, por ejemplo un arreglo de 1000 elementos (1 millón de operaciones).

Solución en tiempo lineal con programación dinámica

Después de pensar un rato en este problema, haciendo algunas anotaciones y viendo la relación entre los indices y el producto parcial de cada uno de ellos llegue a la siguiente solución.

La primera fila son los valores del arreglo, después como si estuviéramos iterando, el valor actual es marcado en color amarillo, si pudiéramos obtener el producto acumulado de izquierda y derecha de cada uno de los elementos entonces podríamos resolver el problema multiplicándolos entre si 🙂

Ejemplo: para el obtener el resultado del 3 tendríamos que multiplicar sus valores de la izquierda que son 2 y sus valores de la derecha que son 20 dando como resultado 40.

Vamos a recorrer el arreglo por la izquierda y por la derecha guardando el producto de sus elementos, para eso necesitaremos 2 arreglos mas, left y right, podemos hacer esos recorridos en una sola iteración, después iteramos nuevamente multiplicando los valores de izquierdo y derecho de result[i].

    public static int[] calculateProduct(int[] numbers) {
        int[] result = new int[numbers.length];
        int[] left = new int[numbers.length];
        int[] right = new int[numbers.length];
        int totalLeft = 1;
        int totalRight = 1;
        int size = numbers.length - 1;
        for (int i = 0; i <= size; i += 1) {
            totalLeft *= numbers[i];
            totalRight *= numbers[size - i];
            left[i] = totalLeft;
            right[size - i] = totalRight;

        }
        for (int i = 0; i < numbers.length; i += 1) {
            if (i == 0) {
                result[i] = right[i + 1];
            } else if (i == numbers.length - 1) {
                result[i] = left[i - 1];
            } else {
                result[i] = left[i - 1] * right[i + 1];
            }
        }
        return result;
    }

La complejidad en tiempo de esta solución es O(2n) o O(n).
La complejidad en espacio de esta solución es O(3n) o O(n), (tomando en cuenta solamente los 3 nuevos arreglos que necesitamos, todas las demás variables son espacio constante).

Happy hacking 🙂

Si te gusto comparte ...Share on Facebook
Facebook
Share on Google+
Google+
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin

#DailyCodingProblem: Encontrar si dos números dentro de un arreglo suman K

https://www.dailycodingproblem.com/

Good morning! Here’s your coding interview problem for today.

This problem was recently asked by Google.

Given a list of numbers and a number k, return whether any two numbers from the list add up to k.

For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.

Bonus: Can you do this in one pass?

Como el problema lo indica, debemos crear una función que reciba 2 parámetros, un arreglo de números y un numero entero k, debemos buscar dentro de ese arreglo si dos elementos sumados entre si son iguales al numero k.

La solución naive para este problema seria iterar sobre los elementos del arreglo y por cada uno de ellos iterar nuevamente para ver si la suma de numbers[i] + numbers[j] da como resultado el numero k

   for (int i = 0; i < numbers.length; i += 1) {
        for (int j = 0; j < numbers.length; j += 1) {
            // evitamos la comparación de un elemento consigo mismo
            if (i != j && (numbers[i] + numbers[j]) == k) {
                return true;
            }
        }
    }

Esta solución no es muy buena ya que por cada elemento en el arreglo vamos a iterar nuevamente los datos, resultando en una complejidad O(n2) donde n es el tamaño del arreglo, imagina un arreglo de 1000 elementos, tendríamos que realizar 1 millón de operaciones.

Solución lineal para encontrar si dos números suman K

Vamos a iterar el arreglo, pero esta vez vamos a usar un HashSet para guardar información, por cada elemento:

  • Calculamos el numero que falta para completar el total k
  • Revisamos si el numero que nos falta existe en el HashSet, si es así devolvemos true (buscar elementos en un HashSet se hace en tiempo constante)
  • Si el numero que buscamos no existe entonces registramos el numero actual como “observado” en el HashSet

Si terminamos de recorrer el arreglo significa que no hay números que sumados nos den como resultado k y por lo tanto devolvemos false.

    public static boolean findSum(int[] numbers, int k) {
        HashSet<Integer> seenNumbers = new HashSet<>();
        for (int i = 0; i < numbers.length; i += 1) {
            int missing = k - numbers[i];
            if (seenNumbers.contains(missing)) {
                return true;
            }
            seenNumbers.add(numbers[i]);
        }
        return false;
    }

La complejidad en tiempo de esta solución es O(n), ya que el numero de operaciones a realizar depende directamente del tamaño del arreglo n.

La complejidad en espacio de esta solución también es O(n), el espacio o la memoria a utilizar depende directamente de lo que reciba la función, en este caso un arreglo de n elementos, utilizamos un HashSet para almacenar máximo el mismo numero de elementos y no realizamos otras operaciones que sean significativas con la memoria.

Happy hacking 🙂

Si te gusto comparte ...Share on Facebook
Facebook
Share on Google+
Google+
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin

CTF OverTheWire: Natas6

Continuamos con la serie de tutoriales del CTF Natas, ahora toca el turno de natas6.

Natas Level 5 → Level 6
Username: natas6
URL:      http://natas6.natas.labs.overthewire.org

Utilizamos la bandera obtenida en el reto anterior y accedemos a la URL indicada en las instrucciones del reto, veremos una pantalla como la siguiente.

Es solo un formulario donde nos piden ingresar una contraseña o secreto, al introducir cualquier cosa obtenemos un mensaje de error.

En la misma pagina hay un enlace que dice view sourcecode (ver código fuente), damos clic y veremos lo siguiente.

La parte importa es:

<?

include "includes/secret.inc";

    if(array_key_exists("submit", $_POST)) {
        if($secret == $_POST['secret']) {
        print "Access granted. The password for natas7 is <censored>";
    } else {
        print "Wrong secret";
    }
    }
?>

Es un código php muy sencillo, podemos ver que obtiene un parámetro via POST (el que enviamos mediante el formulario) y lo compara con la variable $secret, ademas hace include de un archivo interesante includes/secret.inc

Accedemos a ese archivo usando el navegador.

Y utilizamos el secret que acabamos de descubrir en el formulario inicial.

La bandera para acceder a natas7 es 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9

En este reto aprovechamos un fallo de seguridad llamado Source code disclosure, en donde tenemos acceso a código que solo debería ser consumido del lado del servidor.

Happy hacking 🙂

Si te gusto comparte ...Share on Facebook
Facebook
Share on Google+
Google+
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin

Security Fest #CTF – Zion write up

Para este reto nos daban un archivo comprimido zion.tar.gz, procedemos a descomprimirlo y obtenemos otro archivo llamado YouKnow.

El archivo no tiene extension pero utilizamos el comando file para ver que tipo de archivo es.

Parece un archivo de Microsoft Word Office y sabemos que los archivos docx en realidad son archivos en formato zip.

Procedemos a descomprimir YouKnow

Obtenemos varios archivos y carpetas, comenzamos a analizarlos de uno por uno, sin embargo no encontramos nada que haga referencia a la bandera del reto. (analice la imagen del conejo con un par de herramientas de esteganografía pero no había nada)

Damos un paso atrás y abrimos el archivo YouKnow en un editor hexadecimal de su elección, you utilice Sublime

Observamos la cabecera estándar PK del formato ZIP

Al ir analizando el archivo, hacia el final, algo salta inmediatamente a la vista.

Parece que hay otro archivo Zip concatenado al primero pero los bytes están en orden inverso (observen como el archivo termina en KP, y vemos algunos strings como lmx que seria xml).

Podemos utilizar python para invertir los bytes del archivo fácilmente.

open('YouKnow_reversed','wb').write(open('YouKnow','rb').read()[::-1])

Obtenemos el archivo con los bytes invertidos y procedemos a descomprimirlo.

Obtenemos nuevamente varios archivos y carpetas.

Y en donde estaba la imagen anterior del conejo rojo ahora encontramos otra imagen, esta vez de un conejo azul que nos muestra la bandera del reto 🙂

La bandera del reto es sctf{m41nfr4m3_4cc3ss_c0d3_1337_4lw4s}

Bonus

Programe una pequeña herramienta en python llamada reverse bytes para invertir los bytes de un archivo utilizando una cli mas amigable.

usage: rbytes.py [-h] [-o OUTFILE] infile

A simple python script for reverse the bytes of a file.

Author: Lenin Alevski Huerta Arias
Year: 2018

positional arguments:
  infile                Input file

optional arguments:
  -h, --help            show this help message and exit
  -o OUTFILE, --outfile OUTFILE
                        Output file

Happy hacking 🙂

Si te gusto comparte ...Share on Facebook
Facebook
Share on Google+
Google+
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin