Vulnerability Open Redirect LogicBoard CMS

Hello everybody,

Today I could my first post in english. These are a vulnerability open redirect at CMS of Russian origin. From Russia with Love ;) 

Description:
URL: mysite.com/forum/away.php?s=
Affected Component: /forum/away.php?s=

Vulnerability Type: 
Vulnerability Open Redirect  https://cwe.mitre.org/data/definitions/601.html 

Vendor of Product: 
LogicBoard CMS 

Version: 
3.0, 4.0, 4.1

Attack Type: 
Remote

Impact: 
A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks. An http parameter may contain a URL value and could cause the web application to redirect the request to the specified URL. By modifying the URL value to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts have a more trustworthy appearance.
 Attack Vectors: s=   Infection from malware and phishing attack.

About:
LogicBoard CMS: It's a CMS oriented forums engines, ideal for corporate sites, online shops, communities and so on.
 
Credits:
These vulnerabilities have been discovered by
Francisco Javier Santiago Vázquez  aka "n0ipr0cs"
https://es.linkedin.com/in/francisco-javier-santiago-v%C3%A1zquez-1b654050 
https://twitter.com/n0ipr0cs

Disclosure Timeline:
Agust 28, 2016: Vulnerability acquired by Francisco Javier Santiago
Vázquez. aka "n0ipr0cs".
29 Agust, 2016 Responsible disclosure to Babylon Security Team.
30 Agust, 2016 Responsible disclosure to Babylon Security Team.
31 Agust, 2016 Responsible disclosure to Babylon Security Team.
03 January, 2017 Forward mail, please let me know when the vulnerability be solved in order to publish it.
31 January, 2017 Disclosure.

Sample for proof of concept web site: http://burgman-club.ru/forum  /away.php?s=https://www.exploit-db.com/




Do not be a bad.

De 0 a exploiting (IV)

Buenas amigos, soy Fare9, y hoy traigo conmigo la cuarta entrega del curso "De 0 a exploiting", donde veremos paso a paso como va esto del exploiting.

Vamos con los preparativos:
###############################################

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

Compilar (hoy si) con:
gcc -g -fno-stack-protector -z execstack codigo.c -o programa

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

(yo ya tengo hecho un bash para pasar de uno a otro y un bash para compilar).

Hoy vamos a ver el tema de sockets. A través de sockets, en un ordenador, nos conectamos a la red (normalmente utilizando el protocolo TCP/IP). Para usarlos normalmente seguimos una serie de funciones, en este caso si suelen ser funciones específicas de un sistema operativo, aquí dejo las más usuales en C:

Aunque aquí vemos distintas funciones, en realidad las llamadas a la syscall tienen el mismo índice, recordemos del archivo unistd32.h:

#define __NR_socketcall 102

Tras establecer en EAX este valor, seleccionamos en EBX el tipo de llamada, y finalmente en ECX estableceríamos la dirección en la pila de los argumentos(ya no podemos tener un registro por argumento).
Para ver los sockets, veremos como estos funcionan, ya que estos funcionan en un modelo cliente-servidor:
 Como se puede observar, tenemos un servidor, el cual reserva un puerto para empezar a escuchar conexiones, este es un puerto lógico siendo un valor entre 1 y 65535 (64K), tras reservar el puerto, se pone a la escucha hasta que llegue una conexión. 
El cliente entonces realiza una conexión a un servidor con una IP y un puerto, sin contar con firewalls, NIDS ni cualquier otra cosa, tenemos que se ha realizado un establecimiento de la conexión, entonces ambos cliente y servidor tienen un objeto socket por el que pueden pasar streams (flujos) de datos de uno a otro.

Hasta aquí el rollo teórico, bien nosotros queremos algo más, queremos que un atacante esté a la escucha de una víctima al que se le acaba de realizar un ataque a una vulnerabilidad, o queremos que al atacar una vulnerabilidad, dejar en la víctima un puerto a la escucha (lo que llamamos un backdoor). Finalmente tras realizar una conexión queremos obtener una shell, para poder ejecutar comandos, aquí entonces tendremos dos tipos de conexiones Bind Shell y Reverse Shell:
 En esta imagen se muestra un reverse shell, donde es la víctima quien se conecta al atacante, por tanto aunque la victima tenga por delante un router, es posible realizar la conexión, ya que es este quien la comienza.


Bind Shell

Empezaremos explicando Bind Shell, en este caso al explotar la vulnerabilidad, dejamos en la víctima un puerto a la escucha de conexiones. En este caso actúa como servidor y sigue los siguientes pasos:
Primero llamamos a socket, con los valores siguientes, recordemos que los argumentos pasamos primero a la pila, los que están más a la derecha. El primer argumento pasado a socket sería AF_INET con lo que nos referimos a que tenemos que usar el protocolo IPv4, seguido tenemos el argumento SOCK_STREAM para realizar secuenciado de paquetes y añadir fiabilidad, y finalmente tenemos IPPROTO_TCP para que el socket a usar sea TCP en lugar de UDP, finalmente establecer un 0 (como vemos con push %ecx), es para finalizar los argumentos. 
Finalmente hacemos que ecx apunte a la cima de la pila, en este momento y este caso, los argumentos. 
Como vemos al principio metemos en %al el valor 0x66, el cual en hexadecimal es 102, y en bl el valor 0x1, que es el valor de la función socket.
Para acabar realizamos un int $0x80 para ejecutar la función, y metemos en esi lo que devuelve la función socket(), un descriptor del socket (como si fuera un fichero).


Ahora tenemos que "reservar" un puerto para dejarlo a la escucha, para esto rellenamos una estructura del tipo sockaddr, para ello primero insertamos un valor NULL, seguido establecemos el valor del puerto (en hexadecimal) y un valor 0. Tras esto hacemos que ecx apunte a esta estructura por medio de esp. Ahora introducimos los valores de los argumentos en la pila, la longitud en bytes de la estructura (16 bytes), un puntero a la estructura (con ecx) y finalmente el descriptor del socket (con esi), hacemos que ecx apunte a estos argumentos y llamamos a int $0x80, con un valor en eax de 102 y un valor en ebx de 2.

Ya tenemos el puerto, ahora hay que establecerse a la escucha, un servidor puede establecer cuantas conexiones aceptará por un puerto, por tanto en este caso, establecemos que escucharemos por 1 conexión y luego introducimos el descriptor del socket, hacemos que ecx apunte a los parámetros y finalmente realizamos la llamada a Listen.
Una vez estamos a la escucha, debemos hacer que el servidor acepte las conexiones, para ello simplemente necesitamos pasar a la función un único argumento, el descriptor del socket, lo demos podemos establecerlo a NULL. Finalmente llamamos la función accept, y veremos luego que este se queda a la espera, espera que alguien se conecte, y una vez conectado, metemos en ebx el socket de la conexión.

Ahora vamos a realizar un paso, muy sencillo pero bastante interesante, además de en el libro, vi como lo realizaba un troyano, estableceremos los descriptores de ficheros de STDIN, STDOUT y STDERROR en lugar de los normales (teclado y pantalla), los estableceremos al socket, así todo lo que se envíe será tomado como el teclado, y las respuestas en lugar de por pantalla se enviarán por el socket. Para ello vamos a usar la llamada dup2 con la cual podemos reasignar descriptores de ficheros en Linux, en lugar de usar los STD* antes dichos, estableceremos el socket:
Como vemos, realizamos un bucle, para ello metemos el número de rondas en cl muy típico en ensamblador, para llamar a dup2, tenemos en ebx el socket de conexión, y en ecx tendremos los valores 2,1 y 0, con esto al llamar a dup2, modificamos entradas y salidas del programa.
Finalmente llamamos a la shell igual que hicimos en el anterior post en "pusheando cadenas":
Como modificación, añadimos que las variables de entorno estén a NULL.


Si juntamos todo este código en un archivo (por ejemplo bindshell.s) y realizamos lo siguiente:

as bindshell.s -o bindshell.o
ld bindshell.o -o bindshell

Tendremos un programa el cual deje a la escucha un puerto (el 31337), podemos conectarnos a él con una herramienta como "Netcat" o "Ncat":
Tenemos aquí a la espera de conexiones un puerto.
Nos conectamos a la IP donde escucha el bindshell y al puerto, vemos que a partir de ahora podemos ejecutar comandos.

Bien, antes de ver la explotación, veremos el reverse shell y finalmente explotación.

Reverse Shell

En este caso imaginemos que como todos, la víctima tiene un router o tiene un firewall, el cual evita las conexiones desde fuera, por tanto necesitamos que esta vez la víctima sea el cliente, y se conecte a una IP y un puerto.
Esta vez el código será más sencillo, ya que simplemente, creamos el socket y llamamos a connect, finalmente abrimos la shell.

Como vemos, igual que antes,  llamamos a socket para poder obtener un descriptor con el cual realizar las operaciones.
Ahora tenemos algo muy importante, pues debemos realizar una llamada a connect, y necesitamos introducir una IP y un puerto, lo que pasa que en la IP, no podemos establecer nunca un byte 0, por tanto la IP no puede ser algo como "192.168.0.12", así que en mi caso tengo una tarjeta Wifi de red con la IP 192.168.1.32, como vemos insertamos primero la IP (en hexadecimal en Little Endian con los bytes al reves primero el 32 luego el 1 luego el 168 y luego el 192), el puerto al que debe conectarse (en hexadecimal) y luego bx que en este caso tiene un 2 para elegir AF_INET
Hacemos que ecx apunte a esta estructura, y para la llamada a connect, introducimos el tamaño de la estructura, puntero a la estructura y finalmente el descriptor del socket.

Igual que en bindshell, con el socket de conexión en ebx vamos recorriendo los STD*, para pasarlos al socket y finalmente ejecutamos la shell.


Ahora compilamos igual que antes, por ejemplo lo llamaremos al código reverseshell.s y para ejecutarlo antes, necesitamos tener un puerto a la escucha, igual que antes con ncat.
Ncat a la escucha en el puerto 31337, ahora ejecutamos reverseshell.
Al ejecutar reverseshell obtenemos una shell, que va por el socket.



Explotación

Antes de nada tenemos que crear un programa ejemplo2.c , donde poder introducir más caracteres que antes, ya que los opcodes actuales pues son bastantes más, dejo aquí el código:
Como vemos ahora tenemos un buffer de 128 bytes.

Para sacar cuantos bytes son necesarios para llegar a EIP, podemos usar igual que antes Pattern Petater, el cual nos dicen que son 144 bytes (pero animo a probarlo), y luego usando edb debugger, obtenemos la dirección de retorno.

Ahora tenemos un problema, y es que el código antes visto... No vale, ya que al introducir datos en la pila, y estar el código en la pila, los datos van sobreescribiendo el código, por tanto necesitamos código que vaya aumentando la pila. Aquí voy a dejar el código y luego preparamos el exploit típico de Python:

bindshell2.s


reverseshell2.s
 


Exploit

Una vez finalizado, compilamos y obtenemos los opcodes con Objdump, y lo insertamos finalmente todo en un exploit:

Con el bindshell, nos conectaremos con Ncat y con reverseshell, dejaremos un puerto a la escucha.


Bueno hasta aquí el tema de sockets, hemos creado dos shellcodes bastante extensos, pero vamos aprendiendo poco a poco, como crear nuevas formas de shells y nuevos exploits en otros programas.

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

Fare9 en Ciberseg 2017 UAH

Buenas amigos, soy Fare9 y antes de subir este viernes una nueva entrada de "de 0 a exploiting" hoy subiré aquí las diapositivas que usé para hablar sobre AndroidSwissKnife.


Como estudiante de la universidad de Alcalá, para mi ha sido un placer participar en las jornadas de la CIBERSEG de 2017. Este último curso presentaré AndroidSwissKnife con mejoras para mi trabajo de fin de grado, y aquí vine a explicar un poco de que iba.

Como es propio de mi no faltaron ni chistes fáciles, ni referencias a mi cantante favorita, además de mostrar toda la teoría sobre mi framework de análisis.

Así que, aquí dejo las diapositivas y la URL con AndroidSwissKnife cada vez con más mejoras :)

Diapositivas en Slideshare:
http://es.slideshare.net/EduardoBlazquez1/android-swissknife

AndroidSwissKnife:
https://github.com/Fare9/AndroidSwissKnife

 Twitter Ciberseg:
https://twitter.com/ciberseguah

Twitter de Fare9:
https://twitter.com/Erockandblues

De 0 a exploiting (III)

Buenas amigos, soy Fare9. Vengo con la tercera entrega de "De 0 a exploiting" donde, paso a paso, vamos a ir viendo como funciona esto de los temas de explotación de vulnerabilidades.

Como siempre los preparativos de este tema (de momento):

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

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

Compilar (hoy si) con:
gcc -g -fno-stack-protector -z execstack codigo.c -o programa

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

Hoy voy a realizar una introducción a las shellcodes, explicando: qué son, de qué se componen, de que manera podemos crear una nuestra...

Lo primero que vamos a necesitar son unos pocos conocimientos en nuestro lenguaje favorito ENSAMBLADOR (Aquí unos apuntes que pueden venir bien de ensamblador de 8086 ensamblador).
Podemos tener dos tipos de sintaxis:

  • Intel: clasicota de windows, es muy usada en muchos debuggers, es la que encontrareis en los apuntes de arriba.
  • AT&T: usada por el compilador GAS usado en Linux para ensamblador, es el que GDB muestra por defecto.
Dejaré aquí unas cuantas claves mostradas en el libro que estoy siguiendo:

  • Valores constantes:
    • Intel: 0x8c,80,0xFF. Escribimos los valores de forma directa.
    • AT&T: $0x8c,$80,$0xFF. Como vemos la diferencia es que estos valores constantes van con el símbolo DOLAR '$'.
  • Registros:
    • Intel: eax, ebx, ecx... Los escribimos directamente.
    • AT&T: %eax,%ebx,%ecx...Se escriben con el caracter %  
  • Terminaciones de varias instrucciones:
    • En Intel, tenemos que las instrucciones las escribimos como mov, push para uso de registros (se pueden añadir WORD, DWORD para modificar el valor)
    • En AT&T, tenemos que dependiendo del valor añadimos 'b' (byte), 'w'(word) o 'l'(long) a la instrucción.
  • Valor destino y origen:
    • En Intel, el primer valor es el destino y el segundo es el origen. Ejemplo: mov eax,ebx (eax es el destino del valor ebx).
    • En AT&T, es al revés, movl %eax,%ebx  En este caso movemos el valor de eax a ebx.
Como esto no es una clase de estructura de computadores, dejo aquí una imagen con los registros que usaremos y una pequeña descripción:

La primera pregunta:

¿Qué es un shellcode?
Es una gran pregunta, ya que bueno, una shellcode es eso que msfvenom nos devuelve en un formato que nosotros le digamos... Pero la pregunta importante es esos numeritos que aparecen que son y por qué son así.

"Nada más que cadenas de códigos en hexadecimal, extraidos de funciones de ensamblador. Se introducen en ciertas zonas de la memoria para finalmente intentar saltar a estas y ejecutarlos."

Para empezar es una gran explicación, ya que un procesador es una unidad hardware que "procesa", según se va encontrando cadenas de unos y ceros, va ejecutando así a choclon. No distingue si son datos o código o cálculos complejos en módulo 2 .Más o menos este gif explica como funciona un procesador tradicional ejecutando códigos uno tras otro:

Bueno, y una vez tenemos estos códigos hexadecimales, tenemos que introducirlos en un buffer, como ya hicimos en anteriores sesiones, debemos tener ciertas cosas en cuenta:
  • Tamaño del buffer (shellcode no puede ser de longitud infinita)
  • La cadena no puede contener bytes NULL ( \0 ), ya que si se copia a memoria, esto significa que aquí se acabaría esa cadena.
  • Los códigos no deben ser dependientes de direcciones de memoria (no sabemos en que dirección se introducirá cada código).
Nuestros objetivos serán: obtener una shell, leer fichero /etc/shadow, añadir usuarios con privilegios ... Cualquier cosa que sea posible programar.

Para esto vamos a pasar ya a la segunda sección:

System Calls, Syscalls o llamadas al sistema

En Linux, a la hora de realizar ciertas funciones que requieren el uso del kernel, se realizan unas llamadas al sistema indicando un número, unos argumentos y ejecutando una instrucción en ensamblador  "int $0x80", con esto se genera un trap que el kernel recoge y decide si ejecutar o no dependiendo de permisos y capacidades. Por ejemplo las llamadas al sistema pueden ser: abrir archivos, escribir o leer archivos, ejecutar llamadas a programas, conexiones de red ...
Todas estas llamadas llevan asociadas un número, este número se introducirá en el registro AX, para que a la hora de ejecutar int $0x80, se sepa que llamada al sistema queremos realizar.
Aquí dejo el enlace con la lista: Syscall 

Un ejemplo sería realizar una llamada a exit(0), una llamada fácil, y la cual podemos escribir en ensamblador así:

mov $0x00, %ebx
mov $0x1,%eax
int $0x80

Esto lo metemos en un archivo con la extensión ".s" y lo compilamos de esta manera:

as salidaProg.s -o salidaProg.o
ld salidaProg.o -o salidaProg

Si lo ejecutamos veremos que... no pasa nada. Es normal estamos realizando una llamada a exit. 
Para obtener los opcodes de estas operaciones ejecutamos lo siguiente:

objdump -d salidaProg

Y obtendrems una salida como la siguiente:

Esto como shellcode no vale un pimiento, tenemos demasiados 00, lo cual cortaría la cadena, bien podemos aplicar varios trucos, por ejemplo en lugar de mover 0 a ebx, podemos realizar un XOR de si mismo, realiza el mismo trabajo pero es más eficiente, seguido, podemos hacer lo mismo con eax un XOR para ponerlo a 0, y realizar un incremento (inc) para obtener 1.

Como vemos, ahora tenemos OPCODES más válidos. Por tanto nos podríamos montar una cadena tal que así:

"\x31\xdb\x31\xc0\x40\xcd\x80"

Nuestro primer shellcode propio, que realmente no vale para nada...

Nuestro primer objetivo va a ser ejecutar una shell para poder ejecutar comandos, por ejemplo con la llamada "execve", con la cual podemos ejecutar una shell de la forma:

execve("/bin/sh\0",["/bin/sh\0",NULL],NULL)

Lo complicado aquí es referenciar una cadena como /bin/sh, para ello veremos dos métodos, uno de ellos usado por Aleph1 (escritor de Smashing the stack for fun and profit) y otro el cual es más directo:


Aleph1 Shellcode

Para crear la shellcode de Aleph1 , se basó en el funcionamiento de la pila al realizar un call. Ahora mostramos el proceso:
  (molan mis dibujitos ¿no?)
Explicamos un poco el código a continuación, tenemos que la primera instrucción a ejecutar es un salto a una etiqueta llamada "truco", tras saltar a truco, se ejecuta un call, a la etiqueta inicio, al realizar el call, en la pila se guarda la dirección siguiente a call, para poder retornar allí al acabar la función, ahora viene la magia, tenemos que la dirección siguiente a call, lo que contiene es una cadena, la cual queremos usar "/bin/sh". Dentro de inicio, hacemos un pop, para sacar la dirección de la pila y la guardamos en %esi (si os acordais es el registro fuente para cadenas). Por tanto ya tenemos referenciada la cadena.

Seguido vamos a mostrar el código original de Aleph1, para escribir el shellcode:

Como vemos tenemos el salto a "a1" donde tenemos un call a "a2", y abajo el string, en "a2", obtenemos en %esi, el puntero a la cadena, seguido en la dirección de memoria que guarda %esi + 8, metemos la dirección de la cadena (si, de nuevo), y ahora entre medias metemos un NULL byte para establecer un final de cadena. En %eax, metemos la syscall 11, la cual es execve, finalmente introducimos los argumentos en registros para que la función pueda obtenerlos (en %ebx la cadena completa, en %ecx, el puntero a la cadena y a \0 o NULL, y en %edx un NULL) finalmente ejecutamos la syscall, la cual ejecutará /bin/sh y nos devolverá una shell. (El resto de código es simplemente para realizar exit, pero no es necesario).

Si compilamos con el proceso anterior y ejecutamos objdump obtenemos la siguiente salida:

Como se puede observar a primera vista, tenemos muchos bytes NULL (00), por lo tanto no podríamos de primeras inyectar esta shellcode. Otra cosa extraña que podemos observar es después del CALL, hay unas instrucciones bastante extrañas, podemos ignorar esto, ya que es los OPCODES de nuestra cadena, corresponden a ciertas instrucciones en ensamblador.

Vamos entonces a aplicar los trucos que vimos antes, utilizar XOR, incrementos, utilizar los tamaños de registros más pequeños posibles, tenemos entonces aquí el código:

Como vemos, ahora para conseguir un valor 0, realizamos un xor en %eax, y es el valor que pasamos a los finales de cadena de %esi, luego el valor 11 de la syscall, en lugar de meterlo en %eax, vamos al registro más bajo %al, el cual puede guardar un byte. La syscall a exit, la comentamos, pues no es necesaria.
Vamos a ver que nos devuelve objdump: 

Si nos fijamos ahora, vemos que ya no tenemos NULL bytes (00), y podemos juntar todos estos OPCODES, unirlos y generar una shellcode, que nos devuelve una shell (ya la cosa no es tan inutil,¿no?).
 Si os acordais nuestro exploit hecho en python de la anterior sesión, utilizabamos este shellcode, y funcionaba, así que tan mal no era.


Pusheando Cadenas

bueno ahora vamos a un método un poco más directo, vamos a introducir directamente nuestra cadena en la pila. Para ello vamos a separar las cosas de 4 bytes en 4 bytes:

/bin/sh\0

Esta es la cadena que queremos insertar en la pila, pero principalmente nosotros no podemos introducir 00 en el shellcode puesto que dejaría de copiar ahí, ya veremos como lo hacemos. Separamos entonces de 4 en 4 bytes:

/bin            <- aquí van 4 bytes

//sh            <- para obtener el 4º byte añadimos otra /
\0               <- podemos limpiar un registro por ejemplo %eax, con xor %eax,%eax

Como vamos a insertarlo en la pila, lo insertaremos al reves (ya que las cosas se insertan de direcciones altas a bajas, y luego al ejecutarlo se ejecutará de direcciones bajas a altas) además cada 4 bytes por ser little endian se introducirán al reves (nib/,hs//) .

La primera llamada que se realizará será a setreuid(0,0), la cual hace que si un archivo con el bit suid activado deja los permisos de su propietario, los recupere (por ejemplo root). Seguidamente introducimos las variables en la pila y ejecutamos execve con el shellcode.


Vemos que primero limpiamos registro y de seguido preparamos la llamada a setreuid(0,0) recordemos que los parámetros se introducen en los registros. Finalmente llamamos int $0x80.
Luego limpiamos el registro %eax (pues contiene el valor de retorno de la función anterior), lo metemos en la pila (\0), metemos una cadena (//sh al reves), metemos otra cadena (/bin al reves), como esta cadena ahora es apuntada por %esp (al ser la cima de la pila), movemos esa dirección a %ebp, metemos en la pila un 0 (NULL), metemos la cadena /bin//sh\0, ahora hacemos que %ecx apunte a esos dos parametros (en C metemos arg[1], arg[0] y finalmente arg). Establecemos en al la syscall y la llamamos.
Bien vamos a compilar y ejecutar a ver que pasa:

Como vemos obtenemos una shell, ahora obtendremos los shellcode y los meteremos en el exploit de la anterior sesión de python:

Cogemos los opcodes y nos vamos al python:


Aquí las partes del código modificadas. Ejecutemos a ver que pasa:

Vaya, no pasó nada... Bueno esto es lo que me encontré al ejecutar la shellcode tal y como venía en el libro, el problema es que cuando realizamos el push de la cadena /bin//sh\0, el código que está abajo de esta cadena se sobreescribe con basura:
Vamos a ejecutar el programa esta vez así, para poder ver que pasa con un debugger visual, iremos directamente a la ejecución de la shellcode.
El trozo de código que nos interesa antes de meter en la pila /bin//sh\0.
El código tras realizar los push, coomo vemos la parte de abajo se ha modificado, pues estamos metiendo datos en la pila donde antes estaba nuestro código, por tanto hemos fastidiado toda posible ejecución.


El arreglo de Fare9

 El problema es que no hemos reservado pila para introducir esos valores, el caller necesita reservar algo de memoria, y como metemos 12 bytes, entonces tenemos que aumentar nuestro tamaño de pila, y como la pila crece hacia abajo, restamos 12 bytes a esp, vamos a ver entonces como quedaría el código:

Como vemos antes de limpiar %eax con XOR, realizamos un sub $0xC,%esp, con eso dejamos 12 bytes para poder introducir las variables en la pila. 
Compilamos, sacamos con objdump los opcodes y los metemos en el exploit. Ahora lo ejecutamos y a ver que pasa:

Vaya, vaya ahora sí que obtenemos una shell, acabamos de realizar un shellcode bastante "básico" y finalmente hemos logrado explotar una vulnerabilidad en un programa.


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

Para la proxima entrada tocaremos el tema de sockets para un shellcode, espero que esteis disfrutando de estas entradas y si recordad que podeis seguirme en twitter ( nombre Fare9 ). En cualquier caso podeis escribir en los comentarios e intentaré responder lo antes posible.

Nos vemos en el siguiente "de 0 a exploiting"