Exploitation: Conocimientos previos I

Con la intención de que más adelante podamos escribir unos artículos sobre exploits algo más avanzados, he decidido publicar poco a poco una serie dedicada al exploiting para que los lectores con menos conocimientos puedan seguir los artículos futuros.

En esta primera entrada trataremos algunos conocimientos necesarios para la comprensión del proceso de explotación de vulnerabilidades. Es importante tener claros estos conceptos, puesto que la falta de los mismos nos inducirá a error, y a situaciones en las que estaremos perdiendo el tiempo. Esta serie de artículos no está dirigida únicamente a gente interesada en la seguridad, sino que también pretende ser útil a aquellos programadores que están preocupados por la seguridad de los códigos que programan. Puesto que habrá algunos conceptos que tocaremos tangencialmente, recomiendo encarecidamente seguir los links y comprender la información que contienen. No obstante, trataré de explicar lo mejor posible la mayoría de los conceptos.

Antes de meternos en el tema, es conveniente definir un par de términos que aparecerán en la lectura de este post.

EIP: Puntero extendido de instrucción, a veces referido como PC. Contiene la dirección de memoria de la siguiente instrucción a ejecutar por el procesador.

EBP: También llamado Frame Pointer (FP) o Local Base Pointer (LB), se utiliza para apuntar a las variables locales dentro del stack frame actual. Para una definición de stack frame, leed más abajo.

ESP: Puntero extendido de pila. Contiene la dirección de la cima de la pila en cada momento.

Ahora que ya hemos recordado algunos de los registros importantes del x86, vamos al lío. Comenzaremos con los segmentos de memoria de los ejecutables. La memoria de un programa está dividida en cinco segmentos: texto (o código), datos, bss, heap y stack. Cada sección de memoria tiene asociados una serie de permisos (lectura/escritura/ejecución) y otras propiedades que veremos a continuación.

Texto: en este segmento es donde se encuentra almacenado el código ensamblado del programa. Como ya imaginaréis, los permisos de escritura están deshabilitados en este segmento, ya que la idea es leer el código, no cambiarlo durante la ejecución. La ventaja de que este segmento sea de sólo lectura es permitir que sea compartido por varias instancias del programa en memoria, y además evitar que alguien altere el flujo de ejecución del programa. Veremos que de eso se trata el exploiting, de aprovechar las reglas que no han sido correctamente definidas para alterar ese flujo de ejecución. Cabe destacar también que este segmento es de tamaño fijo, puesto que el tamaño del código se conoce en tiempo de compilación y no se puede alterar este segmento (entre otras cosas porque no almacena variables).

Datos: almacena las variables globales y estáticas que han sido previamente inicializadas. Aunque se trata de un segmento con permisos de escritura, su tamaño es fijo.

BSS: en este segmento, por el contrario, se almacenan las variables globales y estáticas sin inicializar. Igual que el segmento de datos, el bss es de tamaño fijo y tiene permisos de escritura. Para entender el por qué del tamaño fijo, pensad que las variables globales son persistentes independientemente del contexto funcional. El motivo de que sean persistentes es precisamente el hecho de estar almacenadas en sus propios segmentos de memoria.

Heap: este segmento es de tamaño variable y está a disposición del programador, que puede reservar fragmentos de memoria para alojar lo que necesite. Como veremos más adelante, el heap crece hacia direcciones altas de memoria.

Stack: al igual que el heap, el segmento de pila es de tamaño variable. Este segmento se utiliza para almacenar las variables locales de las funciones y procedimienos, así como para salvar el contexto durante las llamadas a función. Cada vez que se realiza una llamada a función, dicha función puede recibir variables, y además, su código se encontrará en una dirección diferente del segmento de texto. Debido a esto, el contexto, y el EIP tendrán que cambiar. Se utiliza la pila para recordar las variables recibidas, las variables locales y dos punteros para volver a la situación previa a la llamada: el SFP (saved frame pointer, el valor previo del EBP) y la dirección de retorno (el valor previo del EIP). El conjunto de esta información se denomina normalmente marco de pila o stack frame. Tened en cuenta que en la pila pueden coexistir multitud de stack frames.

Para que quede claro, imaginad una función con dos variables locales, local_1 y local_2 y tres variables que recibe como argumentos, arg_1, arg_2 y arg_3. Esa función podría tener la siguiente pinta.


void ejemplo(int arg_1,int arg_2, int arg_3){

int local_1, local_2;

// código
}

Y su stack frame sería algo así.

stack frame

Posición de los elementos del stack frame

Siguiendo con las imágenes clarificadoras, el mapa de memoria de un proceso es algo así (lamento mis dotes de photoshop ^^).

mapa de memoria del proceso

mapa de memoria del proceso

En la siguiente entrada veremos algunos ejemplos de esto con GDB y completaremos los conceptos más básicos para comprender de manera sencilla el proceso de exploiting. Cualquier duda que pueda quedar, o cualquier aportación, en los comentarios 🙂

Anuncios
Tagged with: , , , ,
Publicado en exploiting, hacking
4 comments on “Exploitation: Conocimientos previos I
  1. lodr dice:

    Ale, leído y entendido. A ver cuándo más.

  2. lodr dice:

    Una cosilla útil: http://www.intel.com/products/processor/manuals/index.htm
    Es la documentación para programadores. Sería interesante que marcaras cuáles son los mejores o una guía de las instrucciones en ensamblador del Intel.

  3. A pesar de que es algo antiguo el post pero esta rebueno encontrarlo en español, estoy muy interesado por empezar a aprender emsamblador x86 para luego pasar a buscar vulnerabilidades y explotarlas, lamentablemente solo he podido usar metasploit con libros que he conseguido y entiendo como funciona el buffer overflow, se me a hecho dificil empezar con progra dado que empeze a estudiar networking primero per osi quier oempezar pronto con esto. saludos y gracias

  4. Adrián dice:

    Me alegro de que te sea útil bertinjose!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Archive
A %d blogueros les gusta esto: