Sobre la técnica de Hawkes para evitar los canarios

5

Encontré esta referencia para eludir canarios: enlace

Se recomienda forzar la fuerza bruta del byte por byte canario. No entiendo cómo funciona esto: "La técnica es la fuerza bruta en cada byte del canario individualmente junto con el análisis del tiempo". ¿Cómo se puede hacer un análisis de tiempo byte por byte? ¿No se compara todo el canario a la vez? Pensé que los cuatro bytes se compararon con una sola instrucción.

También se hace referencia a este ataque en enlace

    
pregunta mikezed 17.11.2013 - 14:56
fuente

2 respuestas

4

La idea es controlar la duración de tu ataque para que solo sobrescribas el primer byte del canario. Luego puede forzar la fuerza bruta de los 256 valores posibles para este byte, y usar algún tipo de canal lateral que sea correcto. Una vez que tienes esto, puedes forzar la fuerza bruta en el segundo byte y continuar hasta que tengas todo el canario.

    
respondido por el paj28 17.11.2013 - 16:56
fuente
1

Este tema también me estaba confundiendo. Solo hay una o dos oraciones en ese problema de Phrack que incluso mencionan el control inteligente de la longitud del exceso de búfer (probablemente porque esta es una técnica típica). Paj28 parece tener la respuesta correcta, pero todavía es un poco vago en cuanto a cómo se podría adquirir un canal lateral lo suficientemente preciso para que esto funcione en la práctica. Si se requiere un gran número de intentos para realizar un análisis estadístico, esto claramente reducirá la efectividad del ataque (especialmente en el caso remoto donde se produce una nueva conexión de red y un syscall de fork () para cada intento).

Los métodos comunes de SSP utilizan un solo canario que se copia a la pila desde una variable de todo el programa almacenada en una sección protegida. Esta inicialización ocurre durante la carga ejecutable. Las tres variantes conocidas de esta inicialización son (a) por parte del núcleo durante el syscall exec * (), (b) por un fragmento de código de inicio para ejecutables enlazados estáticamente, o (c) por el fragmento de código del cargador dinámico que se inserta en una imagen en tiempo de ejecución de ejecutables vinculados dinámicamente.

Lo más importante es que este truco de byte por byte puede ser derrotado. Considera lo siguiente:

{01} En lugar de asignar espacio para una palabra de 64 bits, podemos dejar dos espacios de longitud de palabra en el marco de la pila. Una de estas ranuras variables se coloca antes de los búferes donde es improbable que un desbordamiento pueda modificarlo.

{02} Al ejecutar el prólogo de la función, en lugar de copiar un canario fijo a estas dos ranuras, en realidad derivamos un canario dinámico a partir de dos valores (que a su vez pueden ser dinámicos hasta cierto punto). Lo más probable es que nuestros valores de origen se tomarían de un bloque de memoria protegida aleatoria preinicializada, similar a cómo se establecieron los viejos canarios.

{03} El método de derivación podría hacerse arbitrariamente fuerte, incluso criptográfico, pero no es necesario que esta técnica funcione.

{04} Una estrategia simple puede hacer que la vida del atacante sea muy difícil. Supongamos que el método de derivación es meramente algo como A + B = C, donde A y B son valores de 64 bits pseudoaleatorios. C, el valor de verificación, también sería de 64 bits.

{05} Ahora, cuando el atacante sobrescribe el canario, solo puede llegar a B. A sobrevive en la pila sin tocar debido a que existe en una dirección virtual más baja.

{06} A + B! = C, por lo que, obviamente, el control del canario falla como esperamos.

{07} Sin embargo, ¿qué ha aprendido el ataque al sobrescribir el primer byte de B? Sólo que A + B no es igual a C, naturalmente. Como el ataque no tiene información disponible sobre lo que realmente son A y C, esto crea una gran cantidad de valores posibles para B.

{08} No es factible en este esquema subdividir ingenuamente los valores de palabra en bytes y atacarlos a todos por separado. Debido a la naturaleza de la aritmética modular (ajuste), A [0] + B [0] = C [0] NO garantiza que A + B = C. Los bits de los bytes inferiores pueden transportarse a bytes más altos y los bits de la superior Los bytes pueden desbordarse en bytes inferiores. Es probable que el atacante sea capaz de averiguar cuál debería ser el primer byte de B, pero se vuelve cada vez más difícil con cada byte posterior.

{09} Suponiendo que uno encuentra un medio para derrotar de manera factible este ejemplo de tres palabras de 64 bits en un tiempo razonable, el concepto se extiende arbitrariamente a un mayor número de variables y métodos de derivación de funciones más sofisticados que la aritmética modular. Parece prácticamente evidente que existe un esquema que es lo suficientemente rápido para el uso en el mundo real y lo suficientemente seguro para disuadir casi todos los ataques plausibles.

{10} La técnica puede mejorarse aún más si reservamos y aseguramos alguna región de memoria para almacenar las entradas del canario. En realidad, solo uno de los valores de cálculo canario debe aparecer en la pila para detectar la saturación del búfer. Todos los demás pueden existir en otro lugar, lo que impide que se lean fácilmente, incluso si el atacante logró sobrepasar la pila durante un contexto de ejecución de función diferente.

Es muy improbable que sea la primera persona en darse cuenta de que hay mejoras significativas que se pueden realizar en el esquema de protección de la pila para defenderse contra este y ataques similares. Simplemente presento esto como una prueba de concepto trivial, "por si acaso".

    
respondido por el kagerato 03.02.2015 - 22:36
fuente

Lea otras preguntas en las etiquetas