Buffer Overflow Smashing the Stack Obra realizada bajo licencia FreeBeer para ser utilizada únicamente con fines educativos. El autor de esta obra no se responsabiliza por el fin que se le de a dicha información. El uso indebido de los contenidos aquí expuestos tiene responsabilidades legales en quién incurra en ellos. Pasen y dejen sus sombreros en la puerta, no importa el color que sean... $: WHOAMI */ * * * * * * * * * * */ My.Name : Facundo M. de la Cruz → _tty0 _tty0 My.E­Mail: fmdlc <at> code4life.com.ar My.Blog : http://www.codigounix.com.ar/ 0x41) Consultor en IT 0x42) Coordinador de SanLuiX 0x43) Estudie gastronómia y fui ayudante de cocina 0x44) Amigo de OpenBSDeros Intel i386 Modos de operación Los procesadores Intel x86 tienen distintos modos de operación. → Modo real → Modo protegido → Modo virtual 8086 → Long Mode → System Management Mode Rings de ejecución Los procesadores modernos utilizan rings para determinar los distintos permisos. Se protege : Memoria, I/O Ports, y el uso de algunas instrucciónes por parte de la CPU. Ring 3 → User Space Ring 0 → Supervisor Ring ­1 → Hypervisor User Space Kernel mode Memory management Cada proceso en un sistema operativo multi tareas corre en su propio sandbox de memoria. Esto es el VIRTUAL ADDRESS SPACE . Esta direcciones virtuales son mapeadas a la memoria física por las TABLAS DE PAGINAS mantenidas por el kernel y consultadas por la CPU. Una porción de las direcciones virtuales son reservadas para el propio kernel. Memoria virtual La memoria virtual es una técnica que le permite al software utilizar mas memoria de la que existe fisicamente en el sistema. La mayoría de las PC tiene cuatro tipo de memorias: → Memoria RAM → Registros del CPU → Memoria Caché (L1, L2) → Disco Duro (mas lento, mas grande y barato). La traducción de direcciones virtuales a reales es realizada por el MMU (Unidad de Manejo de Memoria) que incorpora su TLB. El sistema operativo es el responsable de que parte es mantenida en memoría física y que parte en memoria virtual. Paginación Los sistema operativos dividen los programas en pequeñas páginas ; y a la memoria en trozos del mismo tamaño llamados Marcos de Memoria . El kernel mantiene una lista de los marcos y una tabla por cada proceso donde consta en que marco se encuentra cada página de proceso. En la tabla de páginas se encuentra la ubicación del marco que contiene cada una de sus páginas. Que hay en la memoria? El kernel esta siempre listo para ser accedido. En contraste el mapeo para la porción de direcciones en el User­mode cambia entre procesos. Que hay en la memoria? 0xbfffffff 0x08000000 Shared libraries .text .bss .Heap .Stack En GNU/Linux es posible examinar las aréas de memoria de un proceso leyendo el archivo: /proc/`pgrep proceso`/maps env pointer Argv Endianness Es el formato en que se almacenan los datos de mas de un byte. 0xbfbb1a3c Motorola → \xbf\xbb\x1a\x3c → Big Endian Intel → \x3c\x1a\xbb\xbf → Little Endian El estándar de Motorola, se expresa en un orden “natural”. El standart de INTEL va desde el bit menos INTEL significativo al mas significativo. Facilita acceso ya que se hace de forma incremental. Stack LIFO 0xbfffffff POP PUSH 0x00000000 Stack Pointer (TOS) Registros Estructuras internas del CPU utlizadas para comunicar a la UAL con la Memoria. → Registros de propósito general → Registros de control → Registros de segmento → Otros registros Reg. Generales Son registros de 32 bits. → EAX → Acumulador DIV/MUL ­ Número Syscall → EBX → Offset ­ Argumentos Syscall → ECX → Contador de bucles ­ Argumentos Syscall → EDX → Puntero I/O Reg. de control Son registros de 32 bits. → EIP → Extended Instrucion Pointer → EBP → Extended Base Pointer → ESP → Extended Stack Pointer → EDI → Extended Data Index → ESI → Extended Source Index 31 16 0 EIP IP Reg. de segmento Son registros de 16 bits. → CS → Code Segment → DS → Data Segment → ES → Extra Segment → SS → Stack Segment CS : EIP Próxima instrucción SS : ESP Ubicación del Stack Disassemble main Frame Pointer Apunta a la localización dentro del stack de las variables locales y parámetros de una función. Estos pueden ser localizados dando sus OFFSETS desde BP (EBP). A Data SP Data Data Data Data BP FP RET Par 1 FP Procedure Log void function(int a, int b, int c) { char bufferA[5]; char bufferB[10]; } void main() { function(1,2,3); } bufferA bufferB FP RET 1 2 3 Procedure Log 0x080483a4: push ebp 0x080483a5: mov ebp,esp 0x080483a7: and esp,0xfffffff0 0x080483aa: sub esp,0x110 0x080483b0: mov eax,DWORD PTR [ebp+0xc] 0x080483a5: Crea un nuevo FP Epilog 0x080483c8 leave 0x080483c9 ret Veamos un ejemplo en la realidad!... Smashing the stack Buffer Definimos a Buffer como una porción o bloque contiguo de memoria utilizado para almacenar y contener datos. En el leguaje de programación C, el tipo de buffer más común es el array. array Buffer Overflow Es un error de programación que se produce cuando se copia una cantidad de datos a un aréa que no es lo suficientemente grande para contenerla, de esta manera los datos que se escriben en el buffer corrompen aquellos datos en direcciones de memoria adyacentes a los destinados para el buffer, debido a la falta de validación de los datos de entrada. Sistemas afectados Entornos Unix: → AIX → FreeBSD → GNU/Linux → HP­UX → MacOSX → NetBSD → OpenBSD → Solaris Entornos Microsoft: Entornos Microsoft: → Windows 95 → Windows 98 → Windows ME → Windows XP → Windows Vista → Windows Seven → Windows NT → Windows 2000 Prof. → Windows 2000 Server → Windows 2003 Server Funciones vulnerables Sistemas afectados → gets() → strcpy() → strcat() → vsprintf() → scanf() → getc() → fgetc() → getchar() BUFFER OVERFLOW $: ./buffer AAAAAAAA $: ./buffer `python ­c 'print “\x41”*8'` $: ./buffer `perl ­e '{print “\x41”x8}'` buffer – Segmentation Fault ¿Pero que sucede? A A A A A Buffer A - Char (6 Bytes) A A A 6 Buffer B – Char (3 Bytes) Controlling the EIP Si podemos controlar el EIP (RET) , podemos dirigir nuestro programa a donde nosotros queremos. Para controlarlo debemos sobreescribirlo con una posición de memoria valida donde se encuentre el comienzo de nuestra shellcode. Utilizando “ The NOP Method ” podemos hacer todo más facil. ./bof <padding><ret><nop><shellcode> NOP = No Operation = 0x90 = \x90 GDB Disassemble main GDB GNU Debugger el es depurador estándar para el sistema GNU creado en 1986 por Richard Stallman. Características generales: → Creado como y para el proyecto GNU. → Software Libre (distribuido bajo GPL). → Multiplataforma. → Funciona con C, C++, Fortran . → Posibildiad de trazar y modificar la ejecución. → Debugging remoto. → No posee GUI ( Frontend: DDD, KGDB, XXGDB). Ultíma versión estable: 6.8 Arquitecturas → Alpha → ARM → AVR → H8/300 → System/370 → System/390 → x86 → x86/64 → IA­64 “Itanium” → Motorola 68000 → MIPS → PA­RISC → PowerPC → SuperH → Sparc → A29K → ARC → EXTRA CRIS → D10V → D30V → FR­30 → Intel i960 → Motorola 8800 → MCORE → MN10200 → MN10300 → NS32K → VAX → V850 → Z8000 Características → Se puede detener la ejecución de un programa generando puntos de rupturas o Breakpoints . → Se puede detener la ejecución por puntos de ruptura por condición o Watchpoints . → Se puede detener la ejecución al recibir señales externas o Catchpoints . → Se puede consultar el valor de distintas expresiones ( Displays ). → Se pueden analizar archivos Core . Iniciando GDB Para iniciar GDB podemos hacerlo de tres formas. → De manera interactiva → Cargar directamente el binario → Atacheando el proceso en ejecución Interactiva $: gdb GNU gdb 6.8 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686­pc­linux­gnu". (gdb) file binario Directamente $: gdb binario GNU gdb 6.8 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686­pc­linux­gnu". (gdb) Attacheando $: gdb attach `pgrep binario` GNU gdb 6.8 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686­pc­linux­gnu". Attaching to process 1187 (gdb) Shellcode Syscall La syscall usa una instrucción especial ( int 0x80) que permite que el procesador int 0x80 transfiera el control a un código privilegiado previamente especificado por el mismo código. “...Cuando una syscall es invocada, la ejecución del programa que invoca es interrumpida y sus datos son guardados en el BCP para poder continuar ejecutandose luego. El procesador comienza a ejecutar codigo en alto nivel de privilegios, para realizar la tarea requerida. Cuando esta finaliza se retorna al proceso orignal...” Shelllcode → La llamada al sistema específica se carga en el registro EAX → Los argumentos de la llamada son puestos en otros registros → Se ejecuta la instrucción int 0x80 → CPU cambia a Kernel mode → Llamada al sistema ejecutada (devolviendo en este caso el string por pantalla) La tabla de syscalls se encuentra en: /arch/x86/kernel/entry_32.S Syscalls SEGMENT .text mov eax, 4 mov ebx, 1 mov ecx, message mov edx, 12 int 80h ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ xor eax,eax inc eax mov ebx,eax int 0x80 message db 'Game Over?', 7, 10 $: nasm ­f elf scode.asm $: $: ld ­o scode scode.o $: $: objdump ­d scode $: Exploit Nuestro Exploit Escribiremos un exploit utilizando Python, una shellcode de 24 bytes para Linux x86 24 bytes que ejecutará la shell /bin/sh. /bin/sh → Definir Shellcode → Definir Magic Address → Definir NOP's → Definir Padding → Utilizaremos ASLR (protección) Protección Disassemble main Non-Executable Stack Consiste en no permitir la ejecución de código desde el Stack, el buffer overflow código desde el Stack aquí es “imposible” ya que no se puede escribir el RET. → Ret2libc → Ret2code → Ret2data → Ret2text → Ret2syscall → Ret2gets → Ret2plt → Ret2strcpy ASLR Address Space Layout Randomization El principio detrás de esto es simple , si las librerías, la aplicación, el stack y el heap son randomizados, el atacante no sabe donde saltar o apuntar punteros. Se puede especular con la diferencia de bytes entre ejecución o bruteforceando. AAAS ASCII Armored Address Space Se trata de cargar las librerias compartidas en espacios de memoria que comiencen con un NULL 0x00, como por ejemplo 0x00001000. 0x00001000 Shared Library 0x00001C00 Shared Library 0x00001F00 Shared Library W ^ X Memory Significa que la memoria puede ser escrita pero no ejecutada. O ejecutada pero no escrita. Esto haría imposible inyectar código pero pueden ser bypasseados con métodos como: → Ret2plt → Retsyscall → Ret2text → Ret2code Canarios Son valores de 32 bits entre los buffers y la 32 bits data sensible. Si estos canarios son modificados, el programa lo detecta y salta a una excepción. Existen diversas formas de bypassear los canarios de ProPolice y StackGuard, los mas ProPolice StackGuard dificiles de bypassear son los canarios randomizados!. Buffer Canario Canario 0x000AFF0D FP RET More information 0x41)BlackHack 0x41) → 0x42)CodigoUnix 0x42) → http://www.codigounix.com.ar/ 0x43)OpenBSDeros 0x43) → http://www.openbsderos.org/ 0x44)Milw0rm 0x44) → http://www.milw0rm.org/ 0x45)Packet Storn 0x45) → http://www.packetstorn.org/ 0x46)Phrack Magazine 0x46) → http://www.phrack.org/ 0x47)Safemode 0x47) → http://www.safe­mode.org/ 0x48)SecurityFocus 0x48) → http://www.securityfocus.com/ 0x49)Shell Storm 0x49) → http://shell­storm.com/ 0x50)w00w00 0x50) → http://www.w00w00.org/ http://www.blackhack.org/ Bibliografía Attacks and Defenses for the Vulnerability of the Decade Crispin Cowan, Perry Wagle, Calton Pu, Steve Beattie, Johathan Walpole http://www.cse.ogi.edu/DISC/projects/immunix Shellcode: the Assembly cocktail Samy Bahra ­ [email protected] Smashing the stack for fun and profit Aleph One – Phrack 49 ­ [email protected] http://www.phrack.org/issues.html?issue=49&id=14#article The Shellcoders Handbook ­ 2 nd Edition. Chris Anley, John Heasman, Felix “FX” Linder, Gerardo Richarte Wiley Publishing INC. ISBN 978­0­470­08023­8 Gustavo Duarte: http://www.duartes.org/ Shell St0rm http://www.shell­st0rm.org/ Wikipedia http://www.wikipedia.org/ Game Over "...Ahora este es nuestro mundo, el mundo del electrón y el interruptor, la belleza del baudio..." The Menthor 08/01/86