En esta segunda entrada vamos hablar lo ultimo de la teoria!, aunque faltan algunas cosas mas por ver, espero que le sirva, para los que se perdieron el primer articulo, se los dejo aqui:


Registros


Los procesadores de la arquitectura x86 disponen de un banco de registros, los cuales son utilizados para las diferentes operaciones realizadas por la Unidad Central de procesamiento (CPU), existen registros de propósito general y registros de propósito específicos. Por ahora nos centraremos en los registros de propósito general, como se puede observar en la siguiente imagen:

Registros de propósito general
Estos registros son utilizados por la CPU durante su ejecución, en nuestro caso debemos enfocarnos en EBP, ESP e EIP. Se puede observar en la imagen de "Immunity Debugger", en el lado derecho se observan los registros de propósito general.

Registros - Immunity Debugger
EIP – Extendend Instruction Pointer


Puntero a la siguiente instrucción, registro solo lectura (Este es con el vamos a interactuar mas). 


Aplicación en memoria


Cuando una aplicación es ejecutada, el propio ejecutable y todas sus librerías (DLL) son cargadas en la memoria. Cada aplicación tiene asignada tiene 4GB (32 bit, hagan cálculos ;)) de memoria virtual, cuando la aplicación es ejecutada el “gestor de memoria” automáticamente mapea direcciones de memoria virtual en direcciones de la memoria física. La gestión de la memoria es responsabilidad directamente del sistema operativo.

La memoria es dividida entre “User mode” y “kernel mode”. “User mode” es el área de memoria donde una aplicación es cargada y ejecutada en memoria, por otro lado el “kernel mode” es la región donde los componentes del kernel son cargados y ejecutados, siguiendo este modelo, una aplicación no podría directamente acceder a un región de memoria perteneciente al “Kernel mode”.

Aplicación en Memoria - Visión General

Endianess


Es la forma de representar la información mayor a 1 byte, “Little Endian” significa que el byte de menor peso se almacena en la dirección más baja de la memoria y el byte de mayor peso en la más alta.
Formato Little Endian

Por otro lado en “Big Endian” el byte de mayor peso se almacena en la dirección más baja de memoria y el byte de menor peso en la dirección más alta.

Formato Big Endian

En python, importando el módulo sys, se puede identificar la forma que los datos son almacenados, como se observar en la siguiente imagen:


Python
Cada aplicación es cargada en 3 diferentes áreas de memoria: Segmento Stack (Pila), segmento Data (Datos) y el segmento (Code, Text), El segmento de la pila almacena variables locales y llamadas a procedimientos, el segmento de datos almacena variables estáticas y dinámicas, el segmento de texto almacena las instrucciones del programa.


El segmento de la pila y datos son privados para cada una de las aplicaciones, es decir entre diferentes aplicaciones no pueden acceder a estos segmentos, el segmento de texto es solo de lectura y puede ser accedido por diferentes aplicaciones. 

Mapa de Memoria Windows

Asignación de memoria: (Pila / Stack)


 La pila (Stack) es un área reservada en memoria virtual usada por la aplicación, la pila trabaja con una estructura (LIFO, Last In First Out), las operaciones más comunes son Pop (sacar) y push (agregar) datos a la pila.

Cuando se hace push sobre la pila la cima actual de la pila (ESP) decrementa 4 bytes antes del recientemente ítem agregado. En tal sentido cuando se hace un Pop de un ítem se incrementa 4 bytes.
Un “Stack Frame” es una estructura de datos creada durante la llamada a una función, el objetivo es de mantener los parámetros de la función principal y pasar argumentos a la función.

Se puede acceder a la ubicación actual del puntero de la pila, accediendo ESP (apuntador de la pila), se puede acceder a la base actual de la pila utilizando el registro (EBP), de igual forma se puede acceder a la ejecución (actual) accediendo al registro EIP.

Asignacion de memoria


Saludos!

Desarrollo de Exploit Win32 : Registros, Memory layout,Stack, Endianess


En esta segunda entrada vamos hablar lo ultimo de la teoria!, aunque faltan algunas cosas mas por ver, espero que le sirva, para los que se perdieron el primer articulo, se los dejo aqui:


Registros


Los procesadores de la arquitectura x86 disponen de un banco de registros, los cuales son utilizados para las diferentes operaciones realizadas por la Unidad Central de procesamiento (CPU), existen registros de propósito general y registros de propósito específicos. Por ahora nos centraremos en los registros de propósito general, como se puede observar en la siguiente imagen:

Registros de propósito general
Estos registros son utilizados por la CPU durante su ejecución, en nuestro caso debemos enfocarnos en EBP, ESP e EIP. Se puede observar en la imagen de "Immunity Debugger", en el lado derecho se observan los registros de propósito general.

Registros - Immunity Debugger
EIP – Extendend Instruction Pointer


Puntero a la siguiente instrucción, registro solo lectura (Este es con el vamos a interactuar mas). 


Aplicación en memoria


Cuando una aplicación es ejecutada, el propio ejecutable y todas sus librerías (DLL) son cargadas en la memoria. Cada aplicación tiene asignada tiene 4GB (32 bit, hagan cálculos ;)) de memoria virtual, cuando la aplicación es ejecutada el “gestor de memoria” automáticamente mapea direcciones de memoria virtual en direcciones de la memoria física. La gestión de la memoria es responsabilidad directamente del sistema operativo.

La memoria es dividida entre “User mode” y “kernel mode”. “User mode” es el área de memoria donde una aplicación es cargada y ejecutada en memoria, por otro lado el “kernel mode” es la región donde los componentes del kernel son cargados y ejecutados, siguiendo este modelo, una aplicación no podría directamente acceder a un región de memoria perteneciente al “Kernel mode”.

Aplicación en Memoria - Visión General

Endianess


Es la forma de representar la información mayor a 1 byte, “Little Endian” significa que el byte de menor peso se almacena en la dirección más baja de la memoria y el byte de mayor peso en la más alta.
Formato Little Endian

Por otro lado en “Big Endian” el byte de mayor peso se almacena en la dirección más baja de memoria y el byte de menor peso en la dirección más alta.

Formato Big Endian

En python, importando el módulo sys, se puede identificar la forma que los datos son almacenados, como se observar en la siguiente imagen:


Python
Cada aplicación es cargada en 3 diferentes áreas de memoria: Segmento Stack (Pila), segmento Data (Datos) y el segmento (Code, Text), El segmento de la pila almacena variables locales y llamadas a procedimientos, el segmento de datos almacena variables estáticas y dinámicas, el segmento de texto almacena las instrucciones del programa.


El segmento de la pila y datos son privados para cada una de las aplicaciones, es decir entre diferentes aplicaciones no pueden acceder a estos segmentos, el segmento de texto es solo de lectura y puede ser accedido por diferentes aplicaciones. 

Mapa de Memoria Windows

Asignación de memoria: (Pila / Stack)


 La pila (Stack) es un área reservada en memoria virtual usada por la aplicación, la pila trabaja con una estructura (LIFO, Last In First Out), las operaciones más comunes son Pop (sacar) y push (agregar) datos a la pila.

Cuando se hace push sobre la pila la cima actual de la pila (ESP) decrementa 4 bytes antes del recientemente ítem agregado. En tal sentido cuando se hace un Pop de un ítem se incrementa 4 bytes.
Un “Stack Frame” es una estructura de datos creada durante la llamada a una función, el objetivo es de mantener los parámetros de la función principal y pasar argumentos a la función.

Se puede acceder a la ubicación actual del puntero de la pila, accediendo ESP (apuntador de la pila), se puede acceder a la base actual de la pila utilizando el registro (EBP), de igual forma se puede acceder a la ejecución (actual) accediendo al registro EIP.

Asignacion de memoria


Saludos!

2 comentarios:

  1. Excelente Articulo
    Pregunta :
    que son los NOP ?
    en los exploit que funcion cumplen y son necesarios ??

    ResponderEliminar
  2. Gracias Ivan!,

    Son operaciones que no realizan nada (NOP) Not Operation, opcode 0x90, en un exploit no cumplen una función vital al realizar "nada" son utilizados como relleno para llegar a shellcode dependiendo de la tecnica utilizada, algunos dicen (gurus en exploiting) que no deberia ser utilizados, ya que el offset deberia ser calculado de forma quirurgica

    Saludos!

    ResponderEliminar