Upload
vanthuy
View
215
Download
0
Embed Size (px)
Citation preview
Introducción¿Para qué vale saber programar en ensamblador?Optimizaciónen cuanto a tamaño.en cuanto a velocidad de ejecución (desenrollado de bucles, sin redundancias, etc.).
Modificación de binarios (no tenemos el código fuente):adaptación de driverscrackingvirus
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Ensamblador en UNIX
Llamadas al sistema (syscalls):
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Ensamblador en UNIX
Llamadas al sistema (syscalls):Normalmente los programas no hacen syscalls, llaman a funciones de la libC:
Programa en C libC Núcleo
...push stringcall printf... KERNEL
printf:.........int 80h
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Ensamblador en UNIX
Llamadas al sistema (syscalls):Diferentes maneras de utilizarlas en Linux, BSD, etc:
open(path, flags, mode);
Linux FreeBSD
open: syscall:mov eax, 05h int 80hmov ebx, path retmov ecx, flags open: mov edx, mode push dword modeint 80h push dword flags
push dword pathmov eax, 05hcall syscall
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Ensamblador en UNIX
Diferentes sintaxis para programar:Intel: nasmoperación destino, fuente: mov eax, 05h
AT&T: gas, asoperación fuente, destino: movl $0x05, %eaxSufijos en los opcodes (l(ong), w(ord), b(byte)) indicando el tamaño de los operandos.Los registros han de ir precedidos de “%” y los literales de “$”.Diferencias en referencias:
mov edx, [ebp+ecx*4+040000000h] =movl $0x4000000(%ebp,%ecx,4), %edx
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Primer programa con nasmsection .text global _start
msg db 'Hello, world!',0Ah len equ $ - msg _start:
mov edx,len mov ecx,msg mov ebx,1 mov eax,4 int 80h mov eax,1int 80h
nasm –f elf hello.asm –o hello.old hello.o –o hello
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Ensamblar y enlazarEnsamblado y enlazado:Ensamblar con nasm:
nasm –f elf fichero.asm –o fichero.o
Enlazado:
ld:ld -s --dynamic-linker /lib/ld-linux.so.2 -lc fichero.o -o fichero
gcc:gcc fichero.o -o fichero
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Demostración
Programar un "hola, mundo!" con nasm.Ensamblarlo y enlazarlo.Ejecutarlo.
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Programando en GNU/LinuxEstructura de un programa con nasm:
section .bss: datos sin inicializar:
temporal resb 255
section .data: datos inicializados:
contador db 0Ah ( � contador EQU 0Ah)zerobuf: times 64 db 0
section .text: código del programa
mov eax, 01h...
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Programando en GNU/LinuxCondiciones iniciales:RegistrosEn kernels > 2.2: todos los registros a 0.En kernels < 2.2: ebp y ecx distintos de 0.
Pila:[esp] = argc[esp+4] = argv[0][esp+8] = argv[1]...[esp+n*4] = envp
Estructura de un ejecutable en GNU/Linux (ELF):
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Programando en GNU/Linux
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Herramientas disponiblesEditores:BIEW, HTE, ELFe...
Volcadores:od, objdump, ELFDump...
Desensambladores:IDA (desde dosemu/wine), LDasm, DCC, Monodis, jad...
Depuradores:GDB, Fenris, PrivateICE, front-ends de GDB...
Trazadores:ltrace, strace, gccchecker...
Pablo Garaizar SagarminagaCopyleft, all rights reversed
BIEW
BIEW:Interfaz intuitivo, similar al HIEW o MC.Múltiples vistas: binario, octal, hexadecimal, desensamblado.Análisis de la cabecera de los ELF.Modificación sencilla del binario.
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Demostración
Abrir un ejecutable con BIEW.Analizar sus secciones y cabeceras.Desensamblarlo.Editarlo.Comprobar el cambio en su funcionamiento.
Pablo Garaizar SagarminagaCopyleft, all rights reversed
GDBGNU Debugger, escrito inicialmente por Richard Stallman.Orientado al debugging durante el desarrollo de software (junto con el código fuente).Optimizado para ejecutables con código fuente en C y C++ principalmente.Es un debugger de RING-3, que utiliza la syscall ptrace para funcionar.Interfaz de usuario en modo texto y mediante comandos. Muchos emplean GDB a través de un “front-end” que oculta los engorros de utilizar comandos.
Pablo Garaizar SagarminagaCopyleft, all rights reversed
GDB
Syscall ptrace:Permite a un programa (típicamente un debugger), “pegarse” o “attachearse” a otro proceso ya en ejecución con el objeto de analizar su comportamiento. Debugging en modo usuario.Tiene un historial de seguridad un tanto triste.
Pablo Garaizar SagarminagaCopyleft, all rights reversed
GDB
Front-ends:Xxgdb: el primero y más simple.GVD: GNU Visual Debugger, algo rústico.KDBG: wrapper para KDE del GDB.DDD: quizá el front-end más sofisticado, combinando las funcionalidades del GDB, con muchas ventajas del modo gráfico.
Pablo Garaizar SagarminagaCopyleft, all rights reversed
GDBPrimeros pasos, carga del ejecutable:gdb ejecutablegdb PIDgdb –args ejecutable arg1 arg2Ejecución del programa:set / show argspath / show pathsshow / set / unset environment varrunrun parámetrosattach PIDdetach
Pablo Garaizar SagarminagaCopyleft, all rights reversed
GDBBreakpoints:info breakbreak [TAB][lista de símbolos]break *0x08040808clear *0x08040808Watchpoints:info watchpointswatch expresión (write)rwatch expresión (read)awatch expresión (acceso: r||w)Catchpoints:catch evento
Pablo Garaizar SagarminagaCopyleft, all rights reversed
GDBEjecutando instrucciones:
n, next (una línea)s, step (una línea y entra)ni, nexti (una instrucción)si, stepi (una instr. y entra)finishc, continue
Examinando la pila:frame nup, downinfo frame nbt, backtrace
Pablo Garaizar SagarminagaCopyleft, all rights reversed
GDBDesensamblado:
disassembleset disassembly-flavor intelset disassembly-flavor att
Registros:info registersinfo all-registers
Memoria:x 0x8048080x/100 0x8048080x/100s 0x8048080
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Demostración
Cargar un ejecutable con GDB.Desensamblarlo.Ejecutarlo y trazarlo.
Método 1: descriptores de ficheros.Cuando se carga un proceso en memoria, antes de que se ejecute se realizan diversas operaciones de lectura sobre varios ficheros implicados en la creación de la imagen del proceso en ejecución.El GDB abre más descriptores que los necesarios y el intento de cierre de los mismos produce un error:
if(close(3)==-1) printf(“Hello shell...\n”);else printf(“Being traced...\n”);
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Técnicas anti-debugging
Método 2: argumentos y variables de entorno.La documentación de la shell bash explica que el valor de la variable de entorno “_” contiene el nombre completo de cada aplicación que se haya ejecutado.Los diferentes debuggers modifican esa variable:
argv[0] getenv(“_”)shell ./test ./teststrace ./test /usr/bin/straceltrace ./test /usr/bin/ltracefenris ./test /usr/bin/fenrisgdb /home/user/test (NULL)
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Técnicas anti-debugging
Método 3: Identificación de procesos.Existe un identificador para el proceso interactivo que se llama proceso “líder” de la sesión: SID.La diferencia entre el proceso padre (PPID) y el proceso líder (SID) determinará si existe un programa intermedio desde el que se está ejecutando la aplicación:
shell gdb strace ltrace fenrisgetsid 0x1968 0x1968 0x1968 0x1968 0x1968getppid 0x1968 0x3a6f 0x3a71 0x3a73 0x3a75getpgid 0x3a6e 0x3a70 0x3a71 0x3a73 0x3a75getpgrp 0x3a6e 0x3a70 0x3a71 0x3a73 0x3a75
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Técnicas anti-debugging
Metodo 4: Forzar un falso desensambladoMediante un salto a mitad de una instrucción, dado un alineamiento, conseguimos engañar al desensamblador:
jmp antidebug + 2antidebug:
db 0666hcall reloc
reloc:pop esi...
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Técnicas anti-debugging
Método 5: Detectando Int 3. Cuando un debugger quiere parar en un punto determinado (breakpoint), introduce un Int 3 (0xCC) que se puede detectar:
void foo(){ printf("Hello\n");}int main(){
if ((*(volatile unsigned *)((unsigned)foo + 3) & 0xff) == 0xcc) { printf("BREAKPOINT\n"); exit(1);
} foo();
}
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Técnicas anti-debugging
Método 6: Introduciendo Int 3. Podemos introducir 0xCCs en el código para “molestar” al debugger:
#include <signal.h>
void handler(int signo){}
int main(){signal(handler, SIGTRAP);__asm__("int3");printf("Hello\n");
}
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Técnicas anti-debugging
Método 7: Llamando a ptrace.Cuando estamos siendo debuggeados por GDB o strace/ltrace sólo es posible llamar a ptrace[PTRACE_TRACEME] una vez por proceso:
if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) {
printf("DEBUGGING... Bye\n");return 1;
}
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Técnicas anti-debugging
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Demostración
Compilar ejemplos de los métodos propuestos.Intentar depurarlos y trazarlos.
Programar y conocer ensamblador nos da una potencia asombrosa, aunque es un trabajo arduo en ocasiones.GNU/Linux, y UNIX en general, no está afectado todavía por las problemáticas que normalmente requieren su uso: virus, cracking de programas comerciales, modificación de programas sin tener su código fuente, etc.Esto provoca que no haya muchas herramientas disponibles, ya que suelen ser creadas por grupos underground.Parece que todo esto esta progresivamente cambiando, así que se auguran desarrollos importantes.
Pablo Garaizar SagarminagaCopyleft, all rights reversed
Conclusiones