lunes, 5 de enero de 2015

Resolviendo los retos de io.smashthestack.org con radare2 [8]

Level 8


       Vemos el codigo fuente. En la clase "number" hay una función (setAnnotation) que realiza un memcpy, limitado al tamaño de "a". Si miramos
más abajo en el código vemos como esta función es utilizada con el primer argumento que nosotros le pasamos al programa. Por lo tanto
nosotros podemos controlar el tamaño de "a", y en consecuencia podemos hacer que se copie un tamaño de bytes superior al de "annotation",
teniendo como consecuencia un overflow. Siendo C++, y viendo el percal, esto huele a que vamos a tener que trabajar sobre la virtual table. Lo primero, como siempre, es leer un poco ( https://defuse.ca/exploiting-cpp-vtables.htm ).

     Una vez que hemos leído sobre el tema, desempolvamos radare2 y nos ponemos con la faena. Hacemos r2 -d "./level08 AAAA" y empezamos a otear
por el desensamblado de la función main.




      Lo primero que me llamó la atención fue la función "Znwj" (que aparece señalada en la imagen de arriba). Al googlear llegué a este interesante artículo (http://resources.infosecinstitute.com/reverse-engineering-structures/). Esta función se encarga de crear una nueva estructura
en el HEAP, siendo el 108 el tamaño de dicha estructura. Mirando el desensamblado, podemos teorizar que en el HEAP nos vamos a encontrar algo tipo:

[Dirección donde está la vtable][108 bytes][Dirección donde está la vtable][108 bytes]
                     "five"                                                                         "six"

     Por lo tanto, la hipótesis inicial de cómo realizar la explotación sería colocar un shellcode en una variable de entorno, introducir 108 bytes de basura como argumento, y a continuación la dirección donde tenemos los NOPs + shellcode. De esa forma sobreescribiremos "six", haciendo que en vez de apuntar  a la vtable apunte a nuestro código. Así, pues, lo primero que deberemos de hacer es confirmar nuestra primera hipótesis. Buscamos en qué
dirección está la vtable, para ello desensamblamos sym._ZN6NumberC1Ei:


      En la parte resaltada vemos que la dirección es 0x80488c8. Pongamos un breakpoint cuando se llama a la función SetAnnotation (db 0x0804871b) y veamos que se cuece en la pila (dc):



    Miramos el dump de la dirección que hay en el registro ESP y vemos una dirección que huele a HEAP (0x0804a008). Echémosle un ojo:
     ¡Premio! Es exactamente lo que habíamos deducido previamente. Encontramos 0x80488c8 (que es la dirección de la vtable) + 108 byes [ esto corresponde a "five", y otra vez la vtable + 108 bytes [esto correspondería a "six"]. Let's break all the things!



   Un rico sigsegv, y si miramos la dirección que habíamos visto antes (0x0804a008) vemos que efectivamente hemos triunfado:


    Ahora sólo queda hacer un exploit efectivo. Como siempre metemos shellcode en una variable de entorno, sacamos donde está y leña al mono.


 

    Pues no... fiasco. Al parecer en algún punto EIP va a tomar el valor de parte de nuestro shellcode y da un sigsegv (¡se nos ha olvidado la dereferencia!). Si miramos la estructura del HEAP, vemos que ha quedado tal y como queríamos:


      Lo que deberemos de hacer es sustituir los 4 primeros NOPs por la dirección del inicio de los NOPs + 4, de tal forma que en EIP en vez de tomar el valor 0x90909090, tome el de la dirección donde continúan los NOPs. Problema: que como nosotros éramos más chulos que un ocho del revés, lo de usar una variable de entorno se nos jodió (casi puedo oir desde aquí las risas de Zlowram a mi costa). Tiremos de la opción que debiéramos haber elegido desde el principio: colocar el shellcode en "five" (es decir, en el propio argumento que le pasamos).

       En 0x0804a008 + 4 (0x0804a00c) estaría el inicio, por lo que ahí deberíamos de poner la dirección donde van a empezar nuestros NOPs (recordad lo dicho antes), y esa dirección sería 0x0804a008 + 8 (0x0804a010). Por lo tanto, el objetivo final del exploit será que donde antes estaba la dirección de la vtable ahora esté 0x0804a00c.

          Explicado de forma simplificada: pisamos la dirección de la vtable, la ejecución salta hasta 0x0804a00c que contiene la dirección donde empiezan los NOPs (0x0804a010), se hace la dereferencia, y la ejecución salta hacia 0x0804a010, que es donde empiezan los NOPs.




Byt3z!


5 0verl0ad Labs: Resolviendo los retos de io.smashthestack.org con radare2 [8] Level 8        Vemos el codigo fuente. En la clase "number" hay una función (setAnnotation) que realiza un memcpy, limitado a...
< >