smashing the stack

Anuncio
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
Descargar