Desbordamiento de búfer y segmentos

2

Sé que al sobrescribir la dirección de retorno en un programa vulnerable podemos cambiar el desplazamiento de la siguiente instrucción y hacer que apunte a nuestro búfer inyectado. pero este búfer está en el segmento de la pila y el desplazamiento (ip) se calcula para el "segmento de código", entonces, ¿cómo es posible hacer que el programa ejecute el código en el segmento de datos? (Supongamos que está cerca de la llamada).

    
pregunta user2808671 15.03.2015 - 17:30
fuente

1 respuesta

2

En la mayoría (si no todos) los sistemas operativos modernos que se ejecutan en hardware x86, los segmentos se ignoran. Los registros de segmento están configurados para comenzar en la dirección 0 y extenderse por todo el espacio de direcciones de 32 bits; por lo tanto, las compensaciones calculadas en relación con un segmento son válidas para todos los segmentos, ya que todas comienzan en el mismo lugar y se superponen exactamente entre sí. En la práctica, el código de aplicación no se maneja en absoluto con registros de segmento; solo asume que ya están configurados como se describe anteriormente, y se olvida de ellos.

En consecuencia, en un sistema operativo moderno, no hay "llamadas lejanas". Todas las llamadas, todos los accesos de datos están "cerca". La noción de "SO moderno" incluye aquí todas las versiones de Windows desde Windows 95 (y también la versión anterior de Windows 3.1 cuando se instalan las extensiones de "win32s"), y todas las versiones de Linux desde el primer día.

Algunos detalles más finos:

  • Cuando la máquina tiene capacidad para 64 bits, y el kernel del SO se ejecuta en modo de 64 bits, aún puede ejecutar código en modo de 32 bits, pero eso es solo una "emulación". En ese modo emulado, los segmentos son realmente fijos en la dirección 0, y no pueden ser cambiados por el núcleo. Esto significa que la postura de "olvidemos los registros de segmentos" también se ha afianzado firmemente en el hardware.

  • Algunos sistemas operativos harán que la pila (y otros elementos de datos) sean "no ejecutables" para hacer la vida más difícil para el atacante; Esto se llama Prevención de ejecución de datos . Un truco posible para eso es, de hecho, el uso de registros de segmento: por ejemplo, el segmento CS cubrirá las direcciones 0 a 1073741823, y el sistema operativo organizará que los elementos no ejecutables (en particular la pila) se ubiquen en un desplazamiento por encima de 1073741824. En ese caso, cualquier intento de saltar al código que está en la pila hará que la CPU intente leer códigos de operación (por lo tanto, relativamente a CS ) más allá del límite de ese segmento, que luego activa una excepción. Sin embargo, los accesos de datos se realizarán con DS o SS , cuyo límite superior se mantiene en 4294967295 y, por lo tanto, no tendrá obstáculos.

    Como mecanismo de DEP, los registros de segmento no son muy flexibles, ya que requieren una separación clara entre las áreas que se pueden ejecutar y las que no. compiladores JIT , en particular, no están muy contentos con eso, ya que necesitan asignar RAM, escribir código en él, haga que el área sea ejecutable, lo que no se puede hacer si no se asignó en el "espacio ejecutable" (el área cubierta por CS ) en primer lugar. Además, como se dijo anteriormente, los trucos basados en segmentos no funcionan cuando el kernel está en modo de 64 bits. Esta es la razón por la que el sistema operativo moderno, al hacer DEP, prefiere hacerlo a través de la MMU , que permite permitir o evitar la ejecución en una base por página, y para cambiar dinámicamente los derechos de ejecución para cada página.

    (Además, DEP es solo un intento de obstaculizar al atacante, pero existen soluciones . Por razones de seguridad, es mucho mejor no permitir que se desborden los búferes, en lugar de intentar recuperar más o menos limpiamente de un búfer desbordado.)

  • El registro GS es especial; su dirección base es no la dirección 0, y aún funciona cuando el kernel está en modo de 64 bits. Se utiliza para el almacenamiento local de subprocesos eficiente .

respondido por el Thomas Pornin 15.03.2015 - 19:30
fuente

Lea otras preguntas en las etiquetas