Desbordamientos de búfer - Direcciones de memoria

4

Muy bien, últimamente he estado buscando desbordamientos de búfer por curiosidad. Lo que no entiendo es que cuando desarrollas el exploit con una máquina virtual o lo que sea, encuentras la dirección de memoria para desbordar el puntero de instrucción y bam, tu exploit funciona Lo que no entiendo es cómo funciona ese exploit en otra máquina. ¿No sería esa dirección de memoria completamente diferente?

    
pregunta Genthorn 20.12.2016 - 01:45
fuente

1 respuesta

5

Sí y no. Las direcciones de memoria que ve en un proceso no se corresponden directamente con la memoria física (o incluso virtual). Una de las tareas del núcleo es mapear la memoria de cada proceso y dar a ese proceso la ilusión de que es el único proceso que se ejecuta en una máquina.

Por lo tanto, todos los procesos inician su .text (y otras partes de código y bibliotecas estáticas) desde la memoria cerca de 0x0 y su pila comienza desde el final de la memoria. (Eso es en realidad más complejo que eso, pero es una analogía bastante decente. Además, como malloc() es una llamada al sistema, el núcleo le dirá al proceso un problema de falta de memoria sin importar cuánta memoria vea el proceso). Si inicia el mismo proceso con la misma entrada dos veces, su memoria tendrá el mismo aspecto en ambos inicios.

La asignación final entre la memoria vista por un proceso y la memoria física la realiza la CPU mediante el uso de tablas de asignación (de las cuales se indica a la CPU mediante un registro).

Por otro lado, no es tan fácil. Al ver el problema con la posibilidad de que el desbordamiento utilizando la misma aleatorización de pila de direcciones de memoria (ASLR) cobró vida. Varios sistemas operativos hoy habilitan la aleatorización de pila de forma predeterminada, donde el núcleo no inicia la memoria de un proceso desde 0x0 sino desde un valor inicial aleatorio. Esto hace que la memoria del proceso sea desplazada por un puñado de bytes, incluso cuando el mismo proceso se inicia dos veces.

Ejemplo

El siguiente programa trivial:

#include <stdio.h>

int main(void) {
    int i;
    printf("%p\n", &i);
    return 0;
}

Cuando se ejecuta en una máquina con aleatorización de pila (ASLR) habilitada, se imprimirán distintas direcciones, pero cuando la inhabilito, se iniciará la impresión de las mismas direcciones (suponiendo que el archivo con el programa se llame c.c ):

[~]$ gcc -o c c.c
[~]$ ./c
0x7ffd52d0aa3c
[~]$ ./c
0x7ffc27da904c
[~]$ sudo echo 0 > /proc/sys/kernel/randomize_va_space
[~]$ ./c
0x7fffffffe86c
[~]$ ./c
0x7fffffffe86c

Nota adicional

Después de probar esto en dos máquinas muy similares (x86_64 linux 4.8.13) obtuve exactamente el mismo resultado de las dos últimas líneas. Esto se debe a que el programa y el kernel son deterministas.

Sin embargo, puede que este no sea el caso en versiones muy diferentes del kernel. Por ejemplo, kernel 2.x probablemente producirá una dirección diferente para i . Esto significa que la máquina virtual donde se desarrolla un exploit debe reflejar la máquina objetivo tanto como sea posible (de ahí el peligro de la huella digital de la máquina).

    
respondido por el grochmal 20.12.2016 - 02:37
fuente

Lea otras preguntas en las etiquetas