¿La compilación de fuentes "un poco" protege de los ataques de desbordamiento de búfer?

17

Al discutir los desbordamientos de búferes, alguien me dijo que compilar su propio binario para una aplicación (con indicadores de compilación específicos) en lugar de usar el "binario principal" hace que sea más difícil que un atacante aproveche el búfer desbordamientos.

Aparentemente porque "cambia la asignación de memoria" en comparación con el binario principal.

pregunta Brian Clozel 18.07.2011 - 23:26
fuente

4 respuestas

17

Como la pregunta aparece en el encabezado, "¿La compilación de fuentes ... protege de los ataques de desbordamiento de búfer?", la respuesta es en general no .

Sin embargo, aquí hay una conjetura sobre lo que su amigo podría haber estado pensando: las versiones actuales del Compilador GNU C (GCC) pueden usar opcionalmente el GCC Stack-Smashing Protector cuando se invoca con los indicadores de línea de comando -fstack-protector . Hay varias otras técnicas que se deben habilitar en el momento de la compilación, consulte el enlace de Ubuntu a continuación. Supongo que uno o más de estos es lo que quiso decir tu amigo, y asumió que las acciones de Linux / BSD no usan esto ya.

Pero compilarse a sí mismo no es útil si su distribución de Linux / BSD ya usa estas técnicas. Y muchas de ellas lo hacen hoy en día, aquí hay una descripción general útil de lo que Ubuntu lo hace en sus Ediciones de Servidor (vea los titulares Stack- & Heap Protector, Poff Offuscation, 5x ASLR y 4x "Built ...").

Por último, no todo el software funcionará con estas técnicas. Si quieres hacer esto por tu cuenta, entonces te arriesgas a pasar bastante tiempo rastreando errores esquivos. Su proveedor de distribución ascendente está en una mejor posición para aplicar estos cambios y ofrecer a los binarios resultantes pruebas y control de calidad suficientes para considerarlos estables.

Estas técnicas son útiles y agregan una capa significativa de defensa en profundidad. Pero no compiles desde la fuente para esto. En su lugar, elija una distribución de Linux / BSD que tenga una buena mentalidad de ingeniería de seguridad y que ya haya aplicado mecanismos de protección relevantes (superficie de ataque mínima, protección contra desbordamiento de búfer, tal vez SELinux / AppArmor) según corresponda a sus necesidades.

    
respondido por el Jesper Mortensen 19.07.2011 - 01:49
fuente
20

Es en su mayoría falso. Al usar un compilador de una versión diferente a la utilizada para el binario "mainstream", o usarlo con diferentes banderas de compilación, puede resultar en algunas cosas ordenadas de manera diferente, pero es probable que la mayoría del código Los elementos aparecerán en el mismo orden. En la medida en que cambia algo con respecto al aprovechamiento del desbordamiento del búfer, la compilación de las cosas puede facilitar las cosas para el atacante exactamente de la misma manera que puede hacer las cosas más difíciles.

La mayoría del aprovechamiento del desbordamiento del búfer consiste en pisotear una dirección de código (por ejemplo, la dirección de retorno de una función, en la pila o un puntero de función en algún lugar, en particular en vtables para objetos en C ++), de modo que el atacante obliga a la ejecución a ir a donde deseos de Tradicionalmente, el atacante intentó hacer que la ejecución saltara a los datos con los que acababa de llenar el búfer, pero las pilas no ejecutables y, en general, las llamadas W ^ X evita que tenga éxito: los datos no se interpretarán como código. Así que el atacante ahora apunta a la biblioteca C (o una biblioteca del sistema similar, dependiendo del sistema operativo), que contiene funciones agradables para ejecutar otros archivos, por ejemplo. como el infierno. Esto implica adivinar donde dicha función agradable está en la memoria. Línea inferior: si desea que la recompilación tenga algún efecto en eso, entonces debe recompilar la biblioteca de C , no la aplicación.

La aleatorización del diseño del espacio de direcciones es solo una forma genérica de hacer que la dirección de una función sea imposible de adivinar. Es mucho más exhaustivo que la recompilación (incluso suponiendo que la recompilación realmente cambia las cosas, lo que no ocurre) porque la aleatorización del diseño del espacio de direcciones es aleatoria otra vez en cada ejecución . En particular, un atacante no obtendrá información sobre la dirección de la función de destino al obtener una copia del archivo ejecutable, porque esa dirección aún no se ha decidido.

Sin embargo, la aleatorización del diseño del espacio de direcciones no es una bala de plata, ya que debe operar bajo una restricción severa: no puede colocar la biblioteca en cualquier lugar debido a la alineación (generalmente, la dirección de carga debe ser un múltiplo de 4 kB) y los problemas de fragmentación (un El espacio de direcciones de 2 GB (en un sistema de 32 bits) es demasiado pequeño para permitir la dispersión de bibliotecas en todas partes; esto evitaría artificialmente la asignación de grandes bloques de memoria).

(Además, una "bala de plata" es una forma de matar a los hombres lobo. Es una "solución ideal" solo si su idea de la medicina es dispararle a los pacientes).

Un desbordamiento de búfer es un error. Si el atacante puede hacer que su aplicación sobrescriba partes de sus datos con bytes elegidos por el atacante, de manera silenciosa, entonces no hay un límite a priori sobre el daño que puede hacer el atacante. Esa es la razón por la que se inventaron lenguajes como Java: al menos, con Java, en un desbordamiento de búfer, se produce un bloqueo inmediato del hilo, no una corrupción de datos silenciosa.

    
respondido por el Thomas Pornin 18.07.2011 - 23:59
fuente
8
  

[¿Hace] que compilar su propio binario para una aplicación (con indicadores de compilación específicos) en lugar de usar el "binario principal" hace que sea más difícil para un atacante aprovechar los desbordamientos de búfer?

Depende del sistema operativo, el idioma en el que está escrita la aplicación y el compilador.

Primero, el lenguaje de programación debe ser un lenguaje compilado: C, C ++, C #, Java, Objective-C, Delphi, etc. Los lenguajes interpretados (JavaScript, PHP, Ruby, etc.) se ejecutan desde la fuente (no compilados) Para modificar el comportamiento de la memoria, debe cambiar la configuración del intérprete o la fuente. Obviamente, no hay compilación, no hay protección.

Segundo, el lenguaje de programación debe permitir la gestión manual de la memoria. Java y C # utilizan la administración automática de memoria, lo que evita la vulnerabilidad básica de desbordamiento de búfer. C y C ++ permiten la gestión manual de memoria dinámica. Si el lenguaje de programación tiene memoria administrada, la compilación no ayudará.

En tercer lugar, el compilador o las bibliotecas utilizadas en la aplicación deben admitir cierto control o supervisión de la gestión dinámica de la memoria extendida. Los compiladores Microsoft C ++, Intel C ++, GNU C ++, LLVM Clang C ++ son compatibles con -fstack-protector, IBM XL C ++ admite -qstackprotect. Algunas bibliotecas como LibSafe de Avaya Labs, también tienen mecanismos para proteger la pila. Si el compilador no admite la protección de la pila y no hay bibliotecas de protección de la pila disponibles, la compilación no ayudará.

Cuarto, el sistema operativo puede proporcionar cierta protección. Algunos sistemas operativos ya protegen la pila con bits exeables, punteros de base de pila y guardando direcciones de retorno en los registros. Si el sistema operativo ya está protegiendo la pila, la compilación no ayudará.

  

¿Es mucho menos eficiente que la distribución aleatoria del espacio de direcciones?

La asignación aleatoria de espacio de direcciones es una técnica que evita que un atacante utilice una dirección conocida para llamar a una función del sistema. Por ejemplo, si setuid () está siempre en la dirección 0xDEADBEEF, el atacante puede intentar sobrescribir una dirección de retorno con 0xDEADBEEF y ejecutar setuid. La aleatorización no evita los desbordamientos del búfer, solo evita el uso de valores de dirección estática.

  

¿Este punto se vuelve discutible por las nuevas estrategias de administración de memoria en los núcleos del sistema operativo?

No necesariamente. Depende del sistema operativo. Algunos sistemas operativos están más centrados en el rendimiento que en la seguridad. Esos sistemas operativos pueden introducir más vulnerabilidades con los trucos de administración de memoria.

    
respondido por el this.josh 19.07.2011 - 09:58
fuente
7

De lo que habla es que probablemente, en ciertos casos donde el binario original no se ha compilado con las protecciones disponibles, puede volver a compilarlo para habilitarlo.

En la actualidad, los compiladores y sistemas operativos ofrecen muchas protecciones de seguridad avanzadas, pero a veces depende del desarrollador aplicarlas en su aplicación, y algunas de ellas se aplican en el momento de la compilación, y pueden o no estar "activadas" por defecto. .

Quizás el ejemplo más famoso es la protección contra los desbordamientos de búfer basados en la pila. Esta protección se basa exclusivamente en el compilador: en el momento de la compilación, se agregan instrucciones adicionales al programa para agregar y verificar los canarios en la pila, lo que mitiga (los resultados de) un cierto tipo de desbordamientos. Pero esta protección solo se agrega si, en linux, por ejemplo, aplica la bandera -fstack-protector o en las ventanas la famosa bandera / GS. En los últimos sistemas operativos y compiladores, esos indicadores están activados de forma predeterminada, pero no siempre fue así.

Otras opciones de este tipo son (para gcc) -D_FORTIFY_SOURCE = 2 que agrega algunas comprobaciones de seguridad en ciertas funciones vulnerables de glibc y protege contra otros desbordamientos de búfer, y -Wl, -z, relro que marca ciertas áreas de memoria como solo lectura.

Otra cosa que pudo haber querido decir es que puede incluir otras bibliotecas más seguras mientras compila, por ejemplo libsafe, que anula ciertas funciones inseguras conocidas con versiones "más seguras" que tienen más controles de validez.

Además, DEP y ASLR en Windows están habilitados con / NXCOMPAT y / DYNAMICBASE. Ahora creo que Visual Studio los tiene habilitados de forma predeterminada, pero nuevamente ese no fue el caso. Le sorprendería la cantidad de aplicaciones y archivos DLL que aún no tienen habilitados estos indicadores, incluso proporcionados por empresas como Adobe y Microsoft. Caso en cuestión: Adobe Flash solo obtuvo esas protecciones en la versión 10, antes no estaban habilitadas. Es una práctica común que los escritores de exploits busquen dichos archivos DLL mientras intentan encontrar objetivos explotables (o formas de aumentar los privilegios, etc.).

    
respondido por el john 19.07.2011 - 00:09
fuente

Lea otras preguntas en las etiquetas