Cursos de Ingeniería inversa, análisis de malware y análisis forense de memoria.

Voy a empezar con varios tutoriales técnicamente mas complejos relacionados a la ingeniería inversa (RE), análisis de malware y análisis forense de memoria; estos temas aunque parecen diferentes están muy relacionados entre si.

¿Que es la ingenieria inversa y porque debemos estudiarla?

Como indica Wikipedia “…es descubrir cómo funciona un programa, función o característica de cuyo código fuente no se dispone, hasta el punto de poder modificar ese código o generar código propio que cumpla las mismas funciones…“.

Nos sirve para tener un profundo conocimiento de las aplicaciones o el sistema operativo, crear aplicaciones mas seguras, analizar malware, construir exploits, entre otros.

Algunos de los temas que se abordaran son:

  • X86 y X64
  • ARM
  • El kernel de Windows
  • Debugging y automatizacion
  • Ofuscación
  • Trucos anti RE
  • Analizando packers y manual unpacking
  • Y muchos más

¿Que es analisis de malware y porque debemos estudiarlo?

El malware es un componente muy importante en la mayoría de incidentes de seguridad y su análisis es el arte de diseccionar el software para entender como trabaja, como identificarlo y como eliminarlo.

Algunos de los temas que se abordaran son:

  • Análisis estático y dinámico
  • Análisis en maquinas virtuales
  • Análisis de programas para Windows.
  • Comportamiento
  • Evitar ingeniería inversa
  • Y muchos más

¿Que es análisis forense de memoria y porque debemos estudiarlo?

Cada función desarrollada por el sistema operativo o una aplicación resulta en modificaciones a la memoria RAM, y con frecuencia persiste mucho tiempo después de ejecutada esa función. Datos críticos residen exclusivamente en la memoria tales como llaves criptograficas, mensajes de chat, mensajes de correo sin encriptar, registros de Internet no guardados en cache, entre otros.

En este tema veremos todo lo relacionado con la memoria en Windows, Linux y Mac: como se adquiere, registro, kernel, sistemas de archivos, rootkits, entre otros.

Computer programming is an art, because it applies accumulated knowledge to the world, because it requires skill and ingenuity, and especially because it produces objects of beauty. A programmer who subconsciously views himself as an artist will enjoy what he does and will do it better” Donald Knuth

 

 

 

Fundamentos de Arquitectura 2

Nivel Principiante

Continuando con lo visto en el post anterior esta vez hablaremos de otros temas que nos servirán para buffer overflows, shellcode, análisis de malware, entre muchas cosas más. La teoría es algo aburrida pero es necesaria para luego entrar a la parte divertida.

Proceso de memoria

Cuando un proceso se ejecuta, este es organizado en la memoria tal como se muestra:

Proceso Memoria

El proceso es dividido en cuatro regiones: Text, Data, Heap y Stack.

La parte Text, o segmento de instrucción, es fijada por el programa y contiene el código del programa (instrucciones). Esta región es marcada como read-only, debido a que el programa no debería cambiar durante la ejecución.

La región Data es dividida en inicializada y no inicializada. Datos inicializados incluyen items tales como variables declaradas que son predefinidas y pueden ser modificadas. Datos no inicializados, llamados Block Started by Symbol (BSS), también inicializa variables que son inicializadas a cero o no tiene inicialización explicita (por ejemplo static int x).

El siguiente es Heap e inicia después del segmento BSS. Durante su ejecución el programa puede solicitar mas espacio en memoria mediante llamadas al sistema vía brk y sbrk, y utilizados por malloc, realloc y free. Por lo tanto el tamaño de los datos de esta región puede ser extendido. En otros post profundizamos sobre este tema.

La ultima región de la memoria es Stack, la cual es la mas importante para nuestros propósitos.

Pila (Stack)

La pila es un bloque de memoria tipo LIFO (Last-in-First-out). Esta ubicada en la parte mas alta de la memoria. La pila puede ser usada para guardar las direcciones de retorno de una función, pasar los argumentos de una funcion, almacenar variables locales, entre otros. El propósito del registro ESP (Stack Pointer) es identificar la parte superior de la pila y si es modificada cada vez que un valor ingresa pushed in (PUSH), o sale popped out (POP).

Antes de ver como la pila trabaja y como operar en ella, es importante entender como la pila crece. La pila puede crecer hacia arriba, hacia las direcciones de memoria mas altas y también puede crecer hacia abajo, hacia las direcciones de memoria mas bajas.

En resumen, la pila es una estructura LIFO y las operaciones mas fundamentales son PUSH y POP. El puntero principal para estas operaciones es ESP, el cual contiene las direcciones de memoria para lo mas alto de la pila y cambia durante cada operación PUSH y POP.

instrucción PUSH: PUSH E

Proceso PUSH: Un PUSH es ejecutado, y el registro ESP es modificado.

Valor de inicio: ESP apunta a lo mas alto de la pila

Proceso: La instrucción PUSH resta 4 (en 32 bits) u 8 (en 64 bits) del ESP y escribe los datos a la dirección de memoria del ESP, luego actualiza el ESP a lo mas alto de la pila. Recuerde que la Pila crece hacia atrás, por lo tanto PUSH resta 4 u 8, con el fin de apuntar a la ubicación de memoria mas baja de la pila. Si no lo restamos, la operación PUSH sobreescribira la ubicación actual apuntada por ESP (lo mas alto) y podremos perder datos.

Valor final: ESP apunta a la parte superior de la pila -4

PUSH

Ahora, un ejemplo mas detallado de la instrucción PUSH:

Valor de inicio: ESP apunta a la dirección de memoria 0x0046A3B0

Proceso: El programa ejecuta la instrucción PUSH 1. ESP disminuye en 4, llegando a ser 0x0046A3AF, y el valor 1 sera empujado a la pila.

Valor final: ESP apunta a la siguiente dirección de memoria: 0x0046A3AF

PUSH1.png

Proceso POP: Un POP es ejecutado, y el registro ESP es modificado.

Valor de inicio: ESP apunta a la parte superior de la pila (Previo ESP +4)

Proceso: La operación POP es lo opuesto a PUSH y recupera datos de lo mas alto de la Pila. Por lo tanto los datos contenidos en la ubicación de la dirección en el ESP (la parte superior de la pila) es recuperada y almacenada (usualmente en otro registro). Después de la operación POP el valor de ESP es incrementado, en x86 por 4 o en x64 por 8.

Valor final: ESP apunta a la parte superior de la pila (igual que la ubicación anterior antes del PUSH).

POP

Ahora, un ejemplo mas detallado de la instrucción POP:

Valor de inicio: ESP contiene el valor de la dirección de memoria. Después de PUSH 1, ESP apunta a la siguiente dirección de memoria: 0x0046A3AF

Proceso: El programa ejecuta la instrucción inversa POP EAX. El valor (00000001) contenido en la dirección del ESP sera sacado de la pila y sera copiado en el registro EAX. Luego ESP es actualizado agregando 4 y llegara a ser 0x0046A3B0.

Valor final: ESP apunta a la siguiente dirección de 0x0046A3B0. El regresa a su valor original.

POP1.png

Cuando el valor es sacado de la pila no es borrado o puesto es cero. El se mantendrá en la pila hasta que otra instrucción lo sobreescriba.

Ya que conocemos mas sobre la Pila, en el siguiente post analizaremos como trabajan los procedimientos y funciones, esto es importante ya que los procedimientos y funciones alteran el flujo normal del proceso.

D3N.