27 mayo, 2017

De 0 a exploiting (IX)

Buenas coleguirigis, y a estas alturas, exploiters de fama. Soy Fare9, y  como suelo traer, vengo con el cursillo de "De 0 a exploiting", como ya anuncié en redes sociales, estoy preparando el sistema operativo LovatOS (mi ubuntu modificado para que podáis usarlo para hacer las prácticas), aquí una imagen del arranque:
He cambiado el estilo de la letra, pero ya veis la clase de chorradillas que le voy haciendo.

Hoy los preparativos cambiarán, pues aunque esta vez será necesario volver a compilar quitando la protección de pila, veremos como saltarnos a la torera la protección ASLR, en binarios compilados sin la opción PIE (creo que es esa,si):

###############################################

gcc -g -fno-stack-protector -z execstack codigo.c -o programa

###############################################

Como dije, vamos a ver técnicas para bypasear técnicas anti exploiting, conocida como ASLR, el cual hace que los valores de la pila se muevan en cada ejecución. Por tanto ya no nos vale con saber dónde se encuentra uno de nuestros buffers o alguna función en una librería compartida.
Las técnicas que aquí usaremos, se basarán en funciones donde no importa las direcciones absolutas, si no, que aprovecharemos direcciones relativas.

Antes de poder ver estas técnicas tendremos que ver algo de teoría, muy básica. Hablaremos sobre, dónde se establecen las variables, tales como los argumentos en el programa. Los argumentos se encontrarán:

  1. Dentro de la zona de memoria reservada a los argumentos,y apuntada por estos.
  2. En buffers locales (variables locales de función)
  3. Y en los argumentos pasados a funciones
A nosotros donde nos interesa que estén, es en los argumentos pasados a las funciones, con un dibujo lo entenderemos mejor:
Bien, este dibujo nos es de sobra conocido, por encima de RET, al llamar a una función, se meten en la pila (push), los argumentos de la función de derecha a izquierda. Además eso siempre estará ahí si es el argumento de una función, con las técnicas que vamos a ver.


ret to ret

La instrucción ret, ya sabemos más o menos a estas alturas qué hace. Coge el valor al que apunta ESP (o cima de la pila) en ese momento, lo mete en EIP, y como este es el contador de programa, la CPU salta a esa instrucción.
Ahora imaginemos, que sobreescribimos EIP, con el puntero a una instrucción ret, sabemos que ESP estaría 4 bytes por encima del valor ese de EIP, y se repetiría lo de meter el valor a EIP y saltar a esa instrucción.
Pero, ¿nosotros podemos controlar el valor que ahí está después del EIP del programa?. Si es uno de los argumentos pasados al programa, entonces ya está, todo controlado.

Vamos a ver un programa, donde un programador se equivocó al añadir un pequeño numeríto:
 Ya vemos que alguien tuvo un error fatídico a la hora de establecer el valor para strncpy, pero abajo tuvo una gran idea, para detectar intento de hacking, estableció una función que checkea que no se meta ningún byte igual a 0xbf en los argumentos, así evitamos que establezca ahí el valor de un buffer.
Compilaremos como arriba dijimos. Y seguiremos los siguientes pasos para la explotación:
  1. Ver cuantos bytes es posible establecer hasta sobreescribir EIP
  2. Ver la dirección de un ret al que podamos saltar
  3. Establecer un payload que meter como argumento
  4. Explotar
Bien, intentaremos llenar el payload con un shellcode y si eso un relleno de NOPS así estamos más seguros de que la ejecución se ha llevado a cabo correctamente.  Luego el valor de EIP lo sobreescribimos con la dirección de un ret así saltaremos al argumento pasado a la función el cual es un puntero a nuestro payload, como payload pondremos una simple shell.
Ahora entonces seguiremos los pasos

1. Ver cuantos bytes es posible establecer hasta sobreescribir EIP

Para ello vamos a usar nuestro Pattern petater con por ejemplo 100 bytes:
 Y usaremos gdb para ejecutar el programa con este argumento y ver el error:
Introduciremos el valor que nos ha dado en PatternPetater, a ver si nos devuelve el máximo número de bytes que tenemos antes de sobreescribir EIP:
Como vemos el buffer acepta de máximo 52 bytes, tras esto, se sobreescribe EIP.

2. Ver la dirección de un ret al que podamos saltar

Para esta ardua tarea, usaremos objdump de la forma:

objdump -d ./nombre_programa

Vamos a ejecutarlo un par de veces, y ver cual de ellos no se ha movido de su sitio. Tras un par de veces, vemos que el ret de la función que se ejecuta no se mueve, al no haber sido compilado con la opción PIE, aunque tenemos ASLR el binario siempre se carga en la misma posición.
Aquí la dirección:
Tenemos ahí la dirección del ret: 0x080484bb (ya que son 32 bits o 4 bytes). Saltaremos a este ret después del primer ret, que realmente será lo mismo, pero esta vez haremos que retorne al argumento pasado.

3. Establecer un payload que meter como argumento

Meteremos un shellcode que sea una shell típica de AlephONE sin valores nulos '\xeb\x18\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'
Aquí la tenéis y podéis copiar y pegar sin problemas, luego tendremos que meter bytes hasta llegar a 52, este shellcode si lo miramos con python y la opción len veremos su longitud:
Y bueno nuestro python y nuestra inteligencia nos dirán que para llegar a 52, pues con restar nos vale. Y así tenemos que meter 14 bytes más, los cuales serán NOPs. Tras eso meteremos la dirección del ret. Quedando un payload tal que así:
 Como vemos la dirección la metemos en Little endian, el byte menos significativo primero.
Creo ya tenemos lo suficiente para el 4º paso

4. explotación

Aquí tenemos la linea de comandos a ejecutar:
Y... ¿qué pasará con esto?

Pues vamos a verlo ya de una vez:

Como vemos hemos conseguido una shell sin una dirección de un buffer en la pila, este buffer además se estaba moviendo cada dos por tres en cada ejecución así que habría sido imposible.

Pero como no me quedo muy bien, me gustaría mostrar qué está pasando a bajo nivel. Para ello vamos a ver unas imágenes con edb debugger:
Si vamos a la linea donde se hace el call de la función en la stack se verá el argumento pasado, ese argumento le hacemos click derecho y podemos poner "Follow in DUMP" así lo veremos en el dump de memoria:
Como vemos, en el DUMP de memoria del argumento, tenemos los NOPs metidos uno tras otro, la shell y la dirección de memoria.
Ahora al ejecutar hasta el ret de la función, veremos a donde apunta en la stack:
En la stack, en ESP y sobre todo edb nos lo dice, EIP está apuntando al mismo ret que se va a ejecutar, por tanto se ejecutará el ret, se volverá a ejecutar el ret y nos llevará al mundo de las camas de NOPs:

Ahaaa, ahí tenemos NOP NOP NOP NOP NOP NOP....

Así funciona a bajo nivel el ret2ret.



jmp2esp

Esta técnica es parecida a la anterior, y se suele dar en sistemas windows en las DLLs, que fueron compiladas sin seguridad, o en binarios que igual no tienen protección en ASLR, y no tienen DEP activado.
En este caso vamos a simular un programa en producción que por ahí tiene una instrucción "jmp esp". Digo que es parecida a ret2ret, ya que se basa en lo mismo, tenemos que al ejecutar el primer ret, se carga el valor en EIP y se salta a esa instrucción, ESP apunta además al primer argumento, por tanto si la instrucción que ejecutamos es un jmp esp, saltaremos al primer argumento y si además en este argumento metemos NOPS y un shellcode, viviremos felices y comeremos perdices.
Vamos a verlo en memoria a ver que tal suena la flauta:
Esto suena bien, pero ¿funcionará?


Vamos a ver nuestro programa de ejemplo:

Hemos simulado eso la instrucción del salto a ESP, además vemos un problema ahí con strcpy, tenemos un printf, que nos muestra la dirección del buffer, así que si lo ejecutamos un par de veces, vemos como cambia de dirección:

Como vemos el principio del buffer se modifica en cada ejecución, por tanto no valdrá eso de los buferiles.
Ahora lo único que haremos serán los siguientes pasos:

  1. Buscar un jmp esp en el ejecutable
  2. Ver cuantos bytes podemos meter de relleno
  3. Montar el payload (ya lo tenemos medio hecho)
  4. Explotar la vulnerabilidad

1. Buscar un jmp esp en el ejecutable

Para ello usaremos la gran herramienta Radare2 de pancake (https://github.com/radare/radare2).
Seguimos entonces estas órdenes:
 Ya tenemos la dirección del jmp esp : 0x0804846e

2. Ver cuantos bytes podemos meter de relleno
Tiraremos otra vez de nuestro querido pattern petater:
y seguido de GDB:
Ahora enchufamos ese valor en Pattern petater y a ver que sale:

Nos dice que tenemos 140 bytes para rellenar, luego sobreescribimos EIP.

3. Montar el payload
Como ya dijimos está medio hecho, metemos 140 purreles, seguido de la dirección a jmp esp, y seguido de un shellcod, metemos los NOPS que queramos, tampoco vamos a arriesgarnos:

Como vemos, tenemos el relleno de 140 bytes, la dirección de jmp esp, una cama de 10 NOPs y luego el shellcode.
Vamos a pasar a la explotación en el paso 4, a ver si tenemos suerte.

4. Explotación

Vamos entonces a juntarlo con el programa, a ver cómo queda:
 Parece incluso algo real, pero vamos a ver si funciona:

Como vemos, ha funcionado, con edb debugger se podría mirar de nuevo la ejecución:
Como vemos estamos en el ret, de la función, y si miramos la pila, tenemos la dirección del salto a esp y finalmente el shellcode.

Vemos la ejecución del jmp esp, y finalmente la del shellcode.


Hasta aquí he enseñado, técnicas de exploiting avanzadas para saltar las protecciones de ASLR. Estas técnicas a lo mejor podéis encontrarlas que tendréis que usar en CTFs o en máquinas vulnerables.

Espero que vaya gustando el curso y en el próximo POST veremos qué es un integer overflow, y un exploit remoto.

Ha sido un placer como siempre, y que usen estas técnicas en su propio beneficio...Digo... para hacer el bien y alertar a las empresas de que tienen fallos de seguridad...

19 mayo, 2017

Juguetes Hacking VIII



Hola a tod@s

Los chicos de Hack5 nos sorprenden con otro juguetito, después de la piña, el pato y la tortuga, ahora es el turno del conejito. Su nombre Bash Bunny, se trata de un dispositivo de almacenamiento masivo, similar a su primo Rubber  Ducky. El conejo también posee por decirlo de alguna manera lenguaje propio, tiene la apariencia de una simple memoria USB y es capaz de robar todo tipo de información de cualquier sistema al que se conecte en cuestión de segundos.


Tenemos la posibilidad de ejecutar scripts y además cuenta con un entorno de pentesting o lo que es lo mismo la posibilidad de ejecutar Nmap, realizar descubrimiento de la red o creación de portales cautivos entre otros ejercicios.

El dispositivo emula ser un dispositivo de confianza tales como tarjetas de red Gigabit, memorias Flash, teclados y demás dispositivos. Además existe una gran fuente de scripts capaces de atacar fácilmente cualquier sistema informático y además de permitir a cualquier usuario crear sus propios scripts.

 
Si queréis adquirir este nuevo juguete o añadir a la lista de Papa Noel.

07 mayo, 2017

De 0 a exploiting (VIII)

Muy buenas a todos, una semanita más, ya sabeís soy Fare9 y aquí viene otra de "De 0 a exploiting". Tras el anterior post, aunque fuera algo largo y teórico, me quedé con ganas de más y necesitaba mostrar más cosicas.
Estas dos técnicas son: ROP y Falseo de Frame (Para esta última recomiendo entender bien bien bien esta: De 0 a exploiting (V) )

Además como noticia, he de decir que he cambiado de sistema operativo, ahora utilizaré un Ubuntu 17.04, con la última versión de edb debugger ( le doy un Farenain point ).
Aquí os dejo con la imagen, de lo que llamo mi "LovatOS":
(que bien ha quedado lo de ubuntu ahí abajo, justo en la linea)
Antes de empezar con toda la teoría hoy como es un post largo, vamos a poner algo de musiquita al asunto para tener una lectura amena:
The prodigy - Voodoo People
The offspring - You're gonna go far
Panic at the disco - I write sins not tragedies
Paramore - Misery Business
Demi Lovato - La la land


Bien, pues como dije hoy hablaremos de ROP (Return Oriented Programming) y Falseo de Frame, estas son técnicas avanzadas de exploiting, así que os digo que podéis contactar conmigo por ejemplo a través de twitter: Fare9 (sin problemas, más aprende un sabio de preguntas tontas...)
Antes de nada ya sabéis, igual que en el post anterior sólo desactivaremos ASLR, para ello hacéis lo siguiente:
###############################################

Desactivar la aleatoriedad en las direcciones de la pila, para ello debeis ejecutar el comando (como root):
echo 0 > /proc/sys/kernel/randomize_va_space

###### ACTUALIZACIÓN
Recompilando los ejecutables en la última versión de Ubuntu, me activa el stack protector por defecto (conocido como canary value), por tanto para compilar, podéis quitar las opciones de -g -z execstack.

Podéis utilizar esto para compilar:
gcc -fno-stack-protector codigo.c -o programa  ###############################################

Podéis compilar con gcc normal y corriente pues aplicaremos Return to Libc =)


Return Oriented Programming (ROP)

de partida iremos con el mismo código de el anterior post:
ya sabemos que con 254 bytes, podíamos a partir de ahí sobreescribir EIP con 4 bytes más, apuntabamos a &system, a &exit y a la cadena &/bin/sh... Bien ahora lo que haremos será encadenar funciones.
¿ Por qué se llama Return Oriented Programming ? recordemos como se establecía la memoria en el post anterior para ejecutar la función system y exit:
Ejecutabamos system y tras su ejecución teníamos que ret, era el "EIP" de system, en este caso metíamos la función exit.
Partiendo de esto, sabemos que al salir de system, ESP (cima de la pila) apunta a la función exit, se ejecuta el ret de system y EIP ahora apunta a exit y ESP a &/bin/sh (cosas de ejecutar un ret). Pues haremos que EIP apunte en lugar de exit, al siguiente código:

               popl <lo que sea>
               ret

¿Teóricamente esto que hará?, el popl hará que algo se meta en un registro, y ESP avance 4 bytes (pasará de &/bin/sh) y ¿qué le estará esperando tras esa cadena?, eso es un puntero a otra función, lo que llamaremos &func2, entonces se ejecutará func2 y podremos poner un exit para que se ejecute tras este func2... Todo esto es muy lioso pero vamos a hacer un dibujito y nos enteramos más:

Es muy parecido al anterior, pero bueno ahora nuestra primera función será system("/usr/bin/id"), tras esta función ESP apuntará a &/usr/bin/id y EIP apuntará a &(popl;ret), al ejecutar el popl ESP avanzará hasta &func2, la cual cuando se ejecute el ret, cargaremos en EIP &func2 y tachaaaaan se ejecutará func2 como explicabamos en el post anterior, y luego además se ejecutará exit.
Como vemos podemos ir encadenando funciones, con la única limitación de que estas funciones tengan un solo argumento, ya que popl sólo nos quita de en medio un solo argumento, necesitaríamos algo en plan (popl;popl;ret) para meter dos argumentos.

Vamos a ir ya entonces al turrón, veamos que pasos vamos a seguir:

  1.  Obtención de la dirección de system
  2. Obtención de dirección (popl;ret)
  3. Creación de variable SHELL3=/usr/bin/id y obtención de dirección
  4. Obtencion de la dirección de exit
  5. Creación de variable SHELL2=/bin/sh
  6. Explotación
Obtención de la dirección de system

Para obtener el puntero a system ejecutamos el programa dentro de gdb, y tras acabar ejecutaremos dentro de la consola de gdb "p system":
 
 Bien, ya tenemos el puntero a system:

&system = 0xb7e36060

Obtención de dirección (popl;ret)

Nos vale cualquier dirección donde existe un popl con un registro, seguido de un ret. Para ello usaremos objdump -d ./ret_to_libc y buscaremos cualquier dirección que cumpla esto:

Hemos cogido una función cualquiera, la última que salía por hacer algo el vago. Vemos al final un pop %ebx (son 4 bytes, lo que buscamos) y un ret. Tomamos la dirección del pop, y el ret se ejecutará por efecto dominó (o porque la cosa es así y EIP luego apunta a ret).

&(popl;ret) = 0x080485a6


Creación de la variable SHELL3=/usr/bin/id y obtención de dirección

Igual que vimos la otra vez, con export y luego usaremos el programa que dí en la actualización del anterior post obtendremos la dirección de memoria:
Bien, hasta aquí fácil, creamos la variable, ahora obtengamos la dirección con el programa getenv que vimos en el post anterior:

Ya tenemos otro punterito más:
&/usr/bin/id = 0xbffffac0

Obtención de la dirección de exit

pues más o menos como buscamos la dirección de system, pero escribiendo exit, no tiene más misterios:
Punterito de exit:

&exit = 0xb7e29af0

Creación de variable SHELL2=/bin/sh

Pues ya hemos visto como se crea SHELL3, ahora igual SHELL2 y obtenemos su puntero:
El último puntero que nos faltaba:

&/bin/sh = 0xbffffab1


Explotación

Ahora queda la parte que más gusta a estos Hackers, lo de exlotar:

Tenemos que montar una cadena como la que vimos en memoria:

524 'A's, puntero a system, puntero a pop;ret, puntero a /usr/bin/id, puntero a system (de nuevo), puntero a exit y finalmente puntero a /bin/sh:

Como vemos, es un exploit bastante amplio, metemos los bytes de relleno y EIP apunta directamente a system, lo que debería pasar es que se ejecute id y luego una shell, finalmente si salimos de la shell, se ejecutará exit y no dará una violación de segmento:
SIIIIIIIIIIIIIIIIII explotado, conseguimos ejecutar esta vez dos funciones y podríamos volver a ejecutar popl;ret y ejecutar más funciones, así una tras otra. Como diría mi compañero A.d.R. "vamo a echarno un bailecito para celebrarlo":
video

Ahora veremos la siguiente técnica, esta técnica igual está muy muy chula, y la verdad que está bien pensada, implica que tengamos bien sabido la teoría del quinto post de esta saga el abuso del frame pointer.


Falseo de frame

Si recordabamos (veis si al final lo acabo explicando), el abuso del frame pointer consistía en modificar ESP a través de la modificación del valor guardado en memoria de EBP, teníamos una función que modificabamos EBP en memoria con un valor X, al ejecutar leave;ret, cargabamos ese valor X en el registro, al volver de la función teníamos otro leave;ret, el cual ejecutaba lo siguiente el leave:

mov %ebp, %esp # cargamos en esp el valor de ebp para limpiar el frame pointer
popl %ebp # metemos el top de la pila en %ebp y sumamos 4 a ESP

Como vemos, a ESP se le suma 4 al hacer el popl, luego al ejecutar un ret, en EIP se carga lo que hay en ESP y se salta a esa dirección. Aprovechabamos a meter en el buffer un payload y cargabamos en EBP el puntero al payload - 4, así cuando llegara a EIP era el puntero al payload directamente.


Bien esto era al tener la posibilidad de ejecutar código en la pila, ahora usaremos nuestros conocimientos en return to libc, para crear otro payload que no se ejecute en la pila, pero fijate que apañaditos somos, además en EIP (como ahora si podemos acceder), para no tener que esperar un leave;ret de otra función, meteremos un puntero a leave;ret, así tras ejecutar el leave;ret y cargar una dirección X en EBP, ejecutamos de nuevo leave;ret y cargamos en ESP (y por ende EIP) X + 4.
Fijate que con pocas cosillas nos montamos un rico exploit, esto me recuerda a alguien: A quién me recordará

Vamos a ver una imagen de como quedaría en memoria esto, así lo entenderemos mejor:

En donde se guarda EBP meteremos &buffer, y en donde se guarda EIP meteremos &(leave;ret), así cuando se ejecute este segundo leave;ret, saltaremos a la dirección del buffer + 4, por eso al principio del buffer metemos 4 'A's, seguidamente ejecutamos un system(/bin/sh) como hacíamos anteriormente, y sabemos que después se ejecutaría el &leave;ret que viene después de system, vamos a probar a ejecutar.

La dirección &system, y &/bin/sh, las tenemos del ejemplo anterior, entonces seguiremos los siguientes pasos:

  1. Obtención de la dirección de un leave;ret
  2. Obtención de la dirección del buffer
  3. Explotación
Obtención de la dirección de un leave;ret

Para esta tarea usaremos nuestro amigo objdump, el cual nos dará direcciones y opcodes, además de las instrucciones ensamblador: 

Como, vemos y para no irnos mu lejos, cogemos la dirección del leave;ret directamente de la función vulnerable. Por tanto lo añadimos a la lista:

&(leave;ret) = 0x080484a3


Obtención de la dirección del buffer

Este trabajo nos llevará un poquito más (no todo el monte es oregano), usaremos edb debugger para saber dónde carajos strcpy guarda nuestra preciada cadena.
Para ello ejecutaremos edb con todos los datos que tenemos menos con la dirección del buffer, que es lo único que nos queda:
"Fare9 eres un egocéntrico", Últimas reflexiones de Nietzsche...

En lugar de la dirección del buffer, hemos puesto otras cuatro 'AAAA'.

Bueno, vamos a ver que pasa si ejecutamos esto:


Tenemos aquí, un montón de código, pero edb no nos carga directamente nuestro Main, según EIP estamos en ld, y ld es el enlazador... Bueno da igual, pulsamos F9 y vamos al main:
Esto es ya el main, el nuevo edb debugger además, nos indica perfectamente que estamos en el main de ret_to_libc en el desplazamiento 0, ya os digo que las mejoras son realmente buenas.
Vamos a ir ejecutando con F7, hasta llegar a nuestra función fvuln, como hemos metido el número correcto de argumentos no tendremos problemas:

Aquí tenemos la última frontera , en la pila vemos que los argumentos pasados son los que hemos metido en la shell. Pues igual F7, y llegaremos al call de strcpy, ahí entonces veremos los argumentos pasados a esta función de copia de cadenas, el primer argumento será nuestro puntero a buffer:

Como vemos, en la pila, el último argumento que se mete (recordemos se meten de derecha a izquierda), es el primer argumento de strcpy. Por tanto ese será el puntero al buffer:

&buffer = 0xbfffec60


Explotación

Ahora tendremos que montar la cadena antes vista, ya sabemos, 4 'A's , puntero a system, puntero a leave;ret, puntero a /bin/sh, muchas 'A's, puntero a buffer y puntero a leave;ret:

Y veamos que pasa en su ejecución:

Otra vez lo hemos vuelto a hacer, hemos explotado un programa con otra nueva técnica, ahora que vemos que la ejecución se completó vamos a darle a exit y nos vamos al carajo:
Vaya, vaya, parece que nos hemos ido al carajo de verdad...

Ha habido un problema, tras la ejecución del leave;ret, que había después del system, dentro del cual podríamos haber puesto un exit, pero quería enlazar con lo siguiente. Dejamos el leave;ret para seguir la ejecución, pero ¿qué se ha cargó en EBP y luego en ESP y EIP?.

Si recordamos el primer leave;ret cargó en EBP la dirección del buffer, el segundo cargó en ESP la dirección del buffer + 4 y se metió en EIP la dirección de buffer+4, pero en EBP metimos el valor al que apuntaba la dirección del buffer, en este caso AAAA, entonces al ejecutar el tercer leave;ret, se cargó en ESP 0x41414141, y se intentó hacer un popl y un ret de eso, con lo cual son direcciones de memoria extrañas para nuestro programa al no estar direccionada.
Por tanto vemos que el problema fue que se intentó saltar a AAAA, ¿cómo podemos solucionarlo?, pues podemos meter una segunda función en un segundo "buffer", entonces tendremos que se saltará a una segunda función y otra vez tendremos un encadenamiento de funciones. Lo veremos mejor con uno de mis dibujitos:
Como podemos ver, he dibujado la memoria, vemos que tenemos el gran buffer arriba separado en dos buffers, seguido de EBP y EIP en memoria. Vemos que la primera ejecución nos llevaría al primer system, y la segunda saltaría las 4 'A's del buffer2 e iríamos directos al segundo system, el cual se encargaría de parar la ejecución con un exit.
La dirección del segundo buffer es sencilla de calcular, si el primer buffer estaba en 0xbfffec60 contamos, hasta &system +4, hasta &(leave;ret) + 4, hasta &/usr/bin/id +4, y para finalizar hasta el principio del segundo buffer AAAA +4. En total tenemos que sumar 16, que como bien sabeis en hexadecimal es 0x10.
Si sumamos, integramos, y metemos un módulo por aquí, nos da que el segundo buffer comienza en 0xbfffec70.

Vamos entonces a la explotación:
Este es el exploit, como vemos se ha compliccado algo, al final añadimos 488 'A's ya que máximo se podían meter 524 hasta llegar a EIP, así que si vamos restando 4 y 4 y 4 ... de las direcciones de memoria metidas (sin contar la última que es la de EIP) es el número de 'A's que necesitamos (en el exploit anterior pasaba lo mismo).

Veamos su ejecución:
Como vemos la primera ejecución es de system("/usr/bin/id") y seguido nos encontramos con nuestra rica shell, hemos encadenado funciones, y podríamos encadenar más mientras nos diera el buffer con la misma técnica. Finalmente tras exit, se ejecuta la función exit (valga la redundancia) evitando cualquier violación de segmento.

--------------------------------------------------------FIN

Hoy hemos aprendido cosas interesantes, dos técnicas que son usadas para poder movernos por la pila con libertad, además de poder saltar algunas medidas de seguridad como la ejecución de código en la pila.

Espero estén gustando los posts y arriba tienen mi twitter para cualquier clase de duda, si les gustó compartan y así más gente podrá ir aprendiendo paso a paso.

Hasta el próximo post, Fare9.