Ataque de divulgación de información, utilizando un desbordamiento de montón

6

Una estrategia típica para derrotar a ASLR es encontrar un error de desbordamiento de búfer y un error de divulgación de información. Pero cuando se atacan los servidores que se reinician automáticamente cada vez que se cuelgan o mueren, ¿es suficiente un error de desbordamiento del búfer? ¿Podemos usar ese error de desbordamiento de búfer para también proporcionarnos la capacidad de divulgación de información?

Déjame desarrollar el escenario. Supongamos que tengo un programa de servidor que procesa una solicitud de la red y se reiniciará automáticamente en un bloqueo, y supongo que he encontrado una vulnerabilidad de desbordamiento de búfer (de un búfer asignado B ) en el servidor que puedo aprovechar de manera confiable enviando una solicitud apropiadamente diseñada al servidor. Supongamos también que puedo detectar cuándo se bloquea el servidor (por ejemplo, podría fallar porque le envié una solicitud que dañó su memoria y provocó un fallo de seguridad; en cualquier caso, suponga que puedo enviar una solicitud de mi elección y determinar si se estrelló o no al tratar de manejar esa solicitud). El servidor usa ASLR, y quiero desaleatorizar ASLR para poder montar un ataque de inyección de código, pero no conozco un error de divulgación de información por separado: la vulnerabilidad de saturación de búfer es todo con lo que tengo que trabajar. / p>

¿Puedo usar esta vulnerabilidad de saturación de búfer para la divulgación de información, para conocer el contenido de la memoria después de B ?

Este es un ejemplo del tipo de ataque que estoy imaginando:

  

Suponga que el búfer desbordable B tiene una longitud de 512 bytes, y suponga que hay un puntero secreto de 8 bytes P almacenado inmediatamente después de B . Supongamos que el campo F de la solicitud se copia byte por byte sobre B sin ninguna verificación de longitud.

     

Si envío una solicitud con un valor de 513 bytes para F, se copiará sobre B . Si el 513º byte de mi valor difiere del primer byte de P , entonces el valor de P se corromperá, y (asumiendo que el programa hace poco las referencias P ), el programa probablemente se bloqueará durante el procesamiento de esta solicitud. Por otro lado, si el 513 byte de mi valor coincide con el primer byte de P , entonces P permanecerá sin cambios, y el programa probablemente no se bloqueará.

     

Entonces, puedo imaginar el envío de 256 solicitudes, cada una con un valor diferente para el 513º byte del campo F; si 255 de ellos causan que el servidor se bloquee y uno no lo hace, entonces inmediatamente sé el valor del primer byte de P . Ahora puedo continuar hasta que aprenda cada uno de los bytes de P . Esto podría ser útil si el programa está usando ASLR: al aprender el valor del puntero P , puedo eliminar al azar parte de la memoria.

Esto es solo un ejemplo simple. En la práctica, me imagino que podría haber espacio no utilizado después del final de B y antes del siguiente objeto almacenado en el montón, pero puede imaginar formas de adaptar estas técnicas para tratar esa situación también (por ejemplo, si el byte después de que B no esté en uso, puede sobrescribirlo con cualquier cosa y el servidor no se bloqueará, por lo que es fácil detectar ubicaciones que no están en uso y continuar el ataque hasta que encuentre el siguiente objeto después de B ).

¿Este ataque funciona en la práctica? ¿Proporciona una forma efectiva de vencer a ASLR, cuando tiene un desbordamiento de pila en un servidor que se reinicia automáticamente y cuando tiene una manera de detectar bloqueos?

¿Hay algún obstáculo que haya pasado por alto que evite que esto funcione? Por ejemplo, puedo imaginar que si la asignación de memoria para los objetos en el montón no fuera determinista y aleatoria, el ataque fallaría; ¿Pero las plataformas hacen eso? ¿Son las compensaciones relativas entre objetos en el montón deterministas en la práctica, si ejecuta el mismo programa dos veces en las mismas entradas?

Supongo que el desbordamiento del búfer permite sobrescribir B con datos binarios arbitrarios que están totalmente bajo el control del atacante. (El ataque no funcionará con un strcpy() o un desbordamiento relacionado con la cadena, ya que entonces los datos se verán forzados a terminar en cero). Además, supongamos que el servidor se reinicia con fork (), o para por alguna otra razón, parte del diseño de la memoria es la misma cada vez que se reinicia el servidor. (Por ejemplo, esto se mantiene automáticamente en Windows y Mac, ya que las bibliotecas están en la misma dirección base cada vez que reinicia el servidor, y se mantiene para procesos que no son PIE en Linux).

Crédito: Estoy inspirado en un método que leí recientemente para explotar un error de desbordamiento de búfer de un búfer asignado a la pila para fines de divulgación de información. Esto se describió en The Blind ROP paper recientemente publicado en IEEE Security & Privacidad 2014. Muestran cómo hacerlo cuando el búfer B está asignado en la pila. En esta pregunta, estoy preguntando si su técnica se puede generalizar en el caso donde el búfer B está en el montón.

    
pregunta D.W. 29.05.2014 - 00:13
fuente

1 respuesta

5

Como nota, después de cada intento fallido, el programa se bloquea. Dependiendo del sistema operativo / la solidez de la implementación de ASLR y de cómo se reinicia el programa, esto puede resultar en:

  1. el mismo diseño (por ejemplo, si se usa un fork sin exec para reiniciar el programa);
  2. un diseño parcialmente diferente (por ejemplo, direcciones de código que no son de biblioteca para ejecutables no PIE en Linux, o para direcciones de código de biblioteca en algunas versiones (¿quizás todas?) de Windows y Mac OS X);
  3. un diseño completamente aleatorio (por ejemplo, para un ejecutable PIE Linux).

Por lo tanto, si el valor que está tratando de adivinar no es estático entre los reinicios del programa, puede determinar si acertó, pero tan pronto como adivine incorrectamente, el programa se reinicia y ya no tendrá más información; por lo tanto, no ganas nada adivinando de forma incremental.

Claramente, ASLR no proporciona ninguna protección absoluta, y su efectividad es particularmente limitada cuando solo algunas áreas son aleatorias o se usa el mismo diseño en múltiples ejecuciones de programas, pero parece que realizar un ataque genérico con un desbordamiento de pila es suficiente. No depender de los detalles muy específicos del programa en cuestión, como se hace con los desbordamientos de pila en el Blind ROP paper, sería bastante difícil.

    
respondido por el jbms 29.05.2014 - 04:44
fuente

Lea otras preguntas en las etiquetas