STACK-TWO amd64

Este nivel muestra las variables de entorno y como pueden definir para nuestro beneficio.

En este caso vamos a mirar primero el ensamblador y después contrastaremos lo descubierto con el código fuente.

UTILIZANDO EL DEPURADOR

Como en todos los anteriores, lo primero es utilizar rabin2 para obtener más información del binario:

stack-two. rabin2

Después lo podemos abrir en nuestro depurador, analizar todo y comprobar las funciones para ver qué estamos buscando:

stack-two. afl

Ahora que hemos comprobado que la única función interesante, a primera vista, es main, podemos ver su código ensamblador:

stack-two. pdf main

Vamos a analizar este código:

Con el análisis anterior podemos identificar que el programa:

  1. Comprueba si una variable de entorno existe o no.

  2. Si existe, define una variable con el valor cero.

  3. Más tarde, copia un valor en el stack (previsiblemente el valor de la variable de entorno)

  4. Por último, comprueba que la variable que ha almacenado antes con el valor 0, ha cambiado su valor a 0xd0a090a.

Por lo tanto, y si analizamos la estructura del stack justo antes de comparar el valor de [rbp - 0x10] con 0xd0a090a, veremos que debemos utilizar el contenido de la variable de entorno ExploitEducation para alterar el valor de la variable que se encuentra a su lado almacenada en el stack:

stack-two registers + stack

El rbp es 0x7fffffffe680 que coincide con una dirección de memoria que vemos en el stack. Además, vemos que la variable de entorno (ExploitEducation=prueba) se encuentra almacenada en 0x7fffffffe630. Si hacemos la resta, podemos ver que entre ambas direcciones de memoria hay justamente 0x50 bytes (lo que equivale a 50 bytes en decimal).

Con esto confirmamos que la variable que se almacenaba en [rbp - 0x50] es la variable de entorno.

Si ahora comprobamos el contenido de [rbp - 0x10], veremos que el contenido es 0x00000000. Esto es así por qué se ha definido su valor 0x0 en algún momento de la ejecución del programa.

Por tanto, entre 0x50 y 0x10 hay 0x40 bytes o lo que es lo mismo 64 bytes en decimal. Esto implica que puedo sobreescribir la información almacenada en [rbp - 0x10] para que coincida con 0xd0a090a y asi ganar el reto.

PREPARANDO EL EXPLOIT

Ahora que ya sabemos cómo funciona el binario y creemos saber como explotarlo, vamos a preparar un exploit en python para comprobar que estabamos en lo cierto:

stack-two. exploit.py

Como podemos ver, el exploit se aplica a la variable de entorno y después se ejecuta el binario. Si en este caso volvemos a comprobar el stack en el mismo punto, la estructura habrá cambiado:

stack-two. stack + registers exploit

Como vemos, rbp 0x7fffffffe640 y por tanto en [rbp - 0x10] que equivale a 0x7fffffffe630, podemos encontrar nuestra string "CCCC" o lo que es lo mismo 0x43434343.

Si llevamos la ejecución hasta su final, podemos comprobar que estábamos en lo cierto:

eureka!

EXPLOTANDO LA VULNERABILIDAD

Con todo lo anterior comprobado, podemos modificar nuestro exploit anterior para que modifique changeme por el valor necesario:

stack-two. exploit final

Con el exploit terminado, podemos probar a ver si funciona:

EUREKA MAXIMA!

Ahora si hemos explotado un binario sin ni siquiera conocer su código fuente.

CÓDIGO FUENTE

Después de comprobar que el exploit funciona podemos analizar el código fuente para comprobar qué hacía el binario exactamente.

Última actualización

¿Te fue útil?