Heap spraying en seguridad de la información es un ataque que utiliza errores en el trabajo con la memoria de la aplicación . Al atacar con heap spraying, un pirata informático obliga a una aplicación a asignar memoria para una gran cantidad de objetos que contienen código malicioso . Esto aumenta la tasa de éxito de un exploit que mueve el hilo de ejecución a alguna posición dentro del montón . Es importante comprender que sin un exploit que le permita cambiar el flujo de ejecución, la pulverización de montones no causará ningún daño. El ataque se basa en la previsibilidad de la ubicación del montón en el espacio de direcciones del proceso . Además, la asignación de memoria en el montón es una operación determinista, lo que hace posible aplicar con éxito esta técnica. Heap spraying es especialmente eficaz en los navegadores , donde un pirata informático puede asignar memoria utilizando varias líneas de JavaScript en una página web . La similitud de la asignación de memoria en diferentes sistemas operativos juega un papel importante , lo que hace que este ataque sea multiplataforma. Como resultado, es posible insertar una determinada secuencia de bytes (por ejemplo, una instrucción de máquina) en una dirección predicha en la memoria del proceso de destino [1] .
Cuando se crea un proceso en el sistema operativo , se asigna un espacio de direcciones [2] [3] [4] para sus necesidades , que contiene datos de usuario, código ejecutable y cierta información del sistema que depende del sistema operativo específico. Los datos de usuario se distribuyen entre el montón y la pila dependiendo de cómo se les asigne memoria [5] . Por ejemplo, el segmento de la pila almacena variables con una clase de asignación automática, así como información que se guarda cada vez que se llama a una función, como la dirección de retorno. El montón es un área de memoria dinámica , es decir, cuando la memoria se asigna dinámicamente, el espacio se asigna en el montón. Tradicionalmente, el montón y la pila crecen uno hacia el otro [2] [3] [4] .
La fumigación en pilas no es una vulnerabilidad en sí misma . Sin embargo, se puede usar para enviar código malicioso al área de memoria ejecutable de un proceso . Esta técnica explota el determinismo de la operación de asignación de memoria del sistema . Esto significa que una gran cantidad de memoria suele estar ubicada en el mismo desplazamiento en el espacio de direcciones del proceso . Sin embargo, esta técnica no puede crear una brecha en el sistema de seguridad en sí. Por lo tanto, su uso requiere una vulnerabilidad que permite cambiar el orden de ejecución de los comandos (instrucciones máquina) [6] .
Es difícil utilizar esta técnica porque la cantidad de factores que afectan la ejecución del proceso (desde el punto de vista de un hacker) es muy grande. Sin embargo, al usar el rociado de montones, puede ejecutar una gran cantidad de instrucciones, lo que compensa parcialmente esta dificultad y le permite aumentar la probabilidad de un descifrado exitoso [7] .
El rociado de montones se puede implementar para la mayoría de los sistemas operativos y arquitecturas . La principal dificultad es encontrar una vulnerabilidad que te permita redirigir el flujo de ejecución . La asignación dinámica de una gran cantidad de memoria, como se mencionó anteriormente, es una operación que le permite predecir la posición del montón en la memoria (en el momento de mapear la memoria virtual a la memoria física ) [8] . Cada vez que se realiza la misma secuencia de accesos a la memoria, lo más probable es que el montón termine en el mismo lugar [6] [7] .
Sin embargo, para aumentar esta probabilidad, es necesario que el tamaño de una parte de la memoria asignada sea comparable al tamaño de un segmento o página , dependiendo de la forma en que esté organizada la memoria [7] .
El principal problema de este ataque es cambiar el flujo de ejecución . Sin la capacidad de interceptar la ejecución, este tipo de ataque no tiene sentido. Algunas funciones pueden almacenar la dirección de retorno en el montón, en cuyo caso un pirata informático podría intentar cambiarlas. En este caso, al regresar de dicha función, se moverá a una ubicación de memoria que sea conveniente para un pirata informático y, como resultado, comenzará a ejecutarse un código malicioso . Cualquier función que lea una dirección en el montón puede explotarse como una vulnerabilidad. Un pirata informático puede reemplazar esta dirección con la dirección de una parte de la memoria que ha modificado. Esto puede llevar a redirigir el hilo de ejecución a un código malicioso. Sin embargo, esto no es tan fácil como parece [1] [8] .
La corrección de la dirección (su tamaño, desplazamiento con respecto al comienzo de la página) utilizada para la sustitución depende en gran medida de la arquitectura. Por lo tanto, en la práctica, se utilizan bloques, que consisten principalmente en NOP s, agregando el código necesario al final. Esta técnica le permite no preocuparse por la precisión del cálculo de direcciones y dirigir el flujo de ejecución a una ubicación aproximada en el espacio de direcciones [1] .
Pasos para implementar la fumigación en pilas:
Este tipo de ataque es muy efectivo en los navegadores . La mayoría de los navegadores admiten la ejecución de scripts . Un pirata informático puede asignar la memoria requerida utilizando unas pocas líneas de JavaScript o ActionScript en una página web. La similitud de la asignación de memoria en diferentes sistemas operativos juega un papel importante , lo que hace que este ataque sea multiplataforma. Además, las direcciones a las que debe saltar serán similares [9] .
La fumigación en pilas se utilizó por primera vez en 2001 y se generalizó en el verano de 2005. Desde entonces, se han encontrado una gran cantidad de vulnerabilidades en Internet Explorer [10] [11] . Las hazañas eran muy similares entre sí. Cada uno de estos exploits consistía en la pulverización de montones, cuyo método de implementación no cambió, y la transferencia del contador del programa a la ubicación requerida en la memoria . Por lo tanto, se obtuvo un nuevo exploit cambiando algunas líneas de HTML y cambiando a una nueva vulnerabilidad [1] .
La forma más fácil de asignar espacio en la memoria del navegador es declarar una variable de cadena e inicializarla [1] .
Ejemplos de asignación de memoria en JavaScript [9] :
var myvar = "¡CORELAN!" ; var myvar2 = nueva cadena ( "CORELAN!" ); var mivar3 = mivar + mivar2 ; var mivar4 = mivar3 . subcadena ( 0 , 8 );Estos son ejemplos muy simples porque las líneas resaltadas son pequeñas. Un fragmento de shellcode es mucho más grande, pero aún menos que una página completa de memoria .
Hipotéticamente, es posible escribir el código shell necesario muchas veces en cada bloque que asignemos, pero luego el atacante tendrá que hacer un seguimiento de a qué dirección específica va el puntero, ya que no debe caer en medio del código ejecutable . Por lo general, actúan de manera diferente: seleccionan piezas que contienen muchos NOP y, al final, prescriben los comandos necesarios. Entonces, debido a la disposición lineal de los bloques en el montón, es más fácil observar la linealidad de la ejecución del código y no hay necesidad de preocuparse por la precisión de golpear el comienzo de una parte de la memoria [9] .
Con la elección correcta de tamaño, los fragmentos de memoria asignados deben estar muy cerca del tamaño del elemento del montón. Si la parte de memoria asignada es más pequeña, el espacio restante estará libre. El administrador de memoria , en el mejor de los casos, dejará la basura del sistema en este "espacio no asignado" y, en el peor de los casos, colocará un objeto del tamaño adecuado. En cualquier caso, esto dará como resultado un error al intentar ejecutar esta ubicación de memoria [1] [9] .
Por lo tanto, el script utilizado por los atacantes se ve así [9] :
< html > < script > var shellcode = unescape ( '%u\4141%u\4141' ); // esta es la etiqueta CORELAN var bigblock = unescape ( '%u\9090%u\9090' ); //90 es el código NOP var headersize = 20 ; var slackspace = tamaño de encabezado + código de shell . longitud ; // tamaño inicial de nuestro trozo: código útil + tamaño del encabezado while ( bloque grande . longitud < slackspace ) bloque grande += bloque grande ; //rellenar con NOPs var fillblock = bigblock . subcadena ( 0 , espacio de holgura ); //código útil - relleno var block = bigblock . subcadena ( 0 , bigblock . length - slackspace ); //solo NOP mientras ( bloque . longitud + espacio de holgura < 0x40000 ) bloque = bloque + bloque + bloque de relleno ; //llenar hasta el tamaño del elemento del montón - en este caso es 0x40000 var memory = new Array (); for ( i = 0 ; i < 500 ; i ++ ){ memory [ i ] = block + shellcode } // selecciona varios de estos elementos. </ script > </ html >unescape()es una función que le permite colocar los bytes exactamente en el orden especificado en el argumento [1] .
VBScript se usa en Internet Explorer para crear cadenas con string. Conceptualmente igual que la implementación de JavaScript , solo cambian los nombres de las funciones [6] .
En julio de 2009, se encontraron exploits que permiten usar ActionScript para implementar heap spraying en Adobe Flash [1] .
En septiembre de 2012 , se presentó una nueva implementación en EuSecWest 2012 [12] . Federico Muttis y Anibal Sacco han demostrado que la pulverización de montones altamente granular se puede implementar utilizando tecnologías HTML5 . Utilizaron la interfaz de mapa de bits de bajo nivel proporcionada por la API de lienzo .
Hay métodos que utilizan la carga de imágenes. La imagen se compone de NOP s y luego se procede como en los casos anteriores [1] [9] .
Al igual que con todos los desbordamientos de búfer , existen tres defensas principales. [1] A menudo es más fácil evitar un cambio en el flujo de ejecución que el uso real del búfer. Los sistemas operativos modernos utilizan todos los métodos siguientes:
Proyectos relacionados con este tipo de ataque: