viernes, 18 de octubre de 2013

Buffer Overflow : The lazy way

¡Saludos!

    Hace mil que no dedico un poco de tiempo para el blog, pero es que me han estado liado en un par de cosas (como el pasado Navajas Negras... del cual saqué la conclusión de que en realidad las mejores charlas empezaban a partir de las 3 de la madrugada ... animo a todos a que vayais el año que viene, es una experiencia cojonuda), que próximamente comentaremos por aquí.

   La cuestión es que estos últimos días me estoy pasando por el canal de IRC de los chicos de Highsec, y allí @ShellShockLabs me lió para ir haciendo algunos "Exploit me" entre todos. Lo cual agradezco mucho, porque nunca me había puesto "manos a la obra" con el tema de las vulnerabilidades en binarios, más allá de la teoría (lo mío es la seguridad a nivel web). De este "hagamos esto entre todos" (que entre todos significó que sólo nosotros dos lo hicimos).

   Era un Exploit Me! bastante sencillo, el cual su resolución (y explicación for dummies de lo que es un buffer overflow, altamente recomendado si empiezas) podeis encontrar aquí . En apenas unos minutos conseguimos hacerlo, pero algo nos escamaba. Lo que debería de haber sido (leed primero su post en Highsec antes de seguir leyendo) un simple "metemos los 64 bytes para rellenar el buffer, despues otros cuatro para pasarnos por la piedra EBP, y los 4 con la dirección de go_shell que se meriendan lo que había en EIP", se quedó en un:...¿Porqué cojones hemos necesitado 76 bytes para pisar EBP y otros 4 para meter la direccion de go_shell en EIP?

  Tras divagar buscando las más exóticas respuestas por diversos foros de reversing, nos contestaron. El alineamiento de la pila, el "padding".

  Resulta que el compilador mete su propia basura para poder alinear la memoria, aquí teneis la explicación for dummies   No quiero entrar en detalle sobre este aspecto, porque creo que @ShellShockLabs lo hará más en profundidad en Highsec, con este mismo ejemplo, y no quiero chafarle el post.

   Por mi parte,  para saber cuanta basura había que meter para poder sobreescribir EIP utilicé una estrategia de divide y vencerás: primero le metí 100 "A" y 100 "B", al ver que en EIP habia 0x41414141, necesitábamos meter entre 64 (que era el espacio reservado para el buffer) y 100. Despues metí 70 A y 30 B, como seguía viendo "A"s en EIP, fui haciendo 75 A y 10 B, así hasta que llegué a que se necesitaban 76 + 4.

   Yo, amante de la ley del mínimo esfuerzo y los scripts en perl, me sentía frustrado por perder el tiempo en esta tarea (pues fue lo que más tiempo me consumió), asi que opté por hacerme algunas herramientas para próximas veces. Dichas herramientas las podeis ver en nuestro repositorio de GitHub, justo el botón que pone "Herramientas" en la parte superior derecha.

    Para saber cuantos bytes son necesarios podemos usar "seekHdestroy.pl". Con el argumento --seek te devuelve una cadena bastante larga de caracteres que deberemos de pasarle como argumento a nuestro programa vulnerable:

   Hacemos un "GDB simple_login" para cargar el exploit me y "run". Cuando nos pida el password le pasamos la cadena.

   Si hemos leido el post de Highsec, ya sabeis que hemos sobreescrito de forma brutal más allá de los 64 bytes y que por eso peta. Comprobemos los registers (info registers):





   Como podemos ver en la parte señalada EIP está escrito con 5a5a5a4c. Vale, ahora se lo pasamos a seekHdestroy usando como argumento --destroy:


  En menos de 20 segundos ya sabemos cuantos bytes necesitamos para sobreescribir EIP: 76 + 4 con la dirección de donde queramos que apunte. Para sacar donde está go_shell, usamos pr0lapso.pl que es un pequeño parser para objdump que estoy haciendo (todavía está en pañales, el objetivo final es que te saque directamente la shellcode incluyendo los NOPs necesarios):

  Ya sabemos donde: 0804851c. Ahora, para explotarlo, necesitaríamos meterle los 76 de basura (que calculemos con seekHdestroy) y estos 4 de la dirección pero expresada del revés. Tiramos de perl (esta parte es igual que en el post de Highsec):


Explotado en 5 minutos. Ahora, el siguiente paso es terminar pr0lapso para que me genere las shellcodes directamente, pero poco a poco. Como he dicho más arriba, todas estas herramientas las puedes encontrar en nuestro repo de github ( https://github.com/0verl0adLABS ).

Byt3z!

5 0verl0ad Labs: Buffer Overflow : The lazy way ¡Saludos!     Hace mil que no dedico un poco de tiempo para el blog, pero es que me han estado liado en un par de cosas (como el pasado Na...

No hay comentarios:

< >