Log in

Utilizar ROP para detectar malware es perder tiempo

Todos los meses, el ingeniero de software Asher Langton, especialista en malware del equipo de Sky ATV (Advanced Threat Prevention o prevención avanzada de amenazas) de Juniper Networks, publica un breve estudio sobre algún tipo de malware. Este mes, Langton trata de la técnica “return-oriented programming” (o ROP), que es objeto de mucha discusión entre especialistas en sandboxes.


La discusión ocurre porque algunos tipos de malware utilizan ROP para intentar infectar un sistema y, por lo tanto, según algunos especialistas, sistemas de detección de malware necesitarían también monitorear este vector de ataque, aunque esto cause el excesivo uso de recursos computacionales. Asher argumenta y explica porque el Sky ATP logra ofrecer la misma protección sin buscar detectar el ROP propiamente dicho. Al final, dice él, una técnica de exploración de la seguridad de un sistema, como es el caso del ROP, también puede ser detectada por indicadores comportamentales. Este es el post de Langton:


Tradicionalmente, para que una técnica de exploración (“exploit”) pudiera infectar un sistema algunas cosas necesitaban ocurrir:
 

  1. Encontrar un error de programación en una aplicación (por ejemplo, el Adobe Flash) que permita inputs especialmente creados para transbordar o, de alguna otra manera, corromper una región alocada en la memoria.
  2. Inyectar un código ejecutable (shellcode) en la memoria del programa.
  3. Transferir el control para este nuevo código y substituir las informaciones de control por una dirección de retorno en la pila de llamadas.

Con esta técnica, la simple abertura de un documento o media resultaba en la ejecución arbitraria de un código en el sistema visado. El invasor asumía el control y podía descargar otros tipos de malware, recolectar informaciones del sistema, instalar spyware o hooks persistentes etc.


Aquí está un ejemplo simple de un programa vulnerable a un ataque que corrompe la memoria.


El ataque aprovecha el uso de la función insegura gets(), que lee una string de la consola “algo digitado por un usuario” y la escribe en una localización específica en la memoria sin verificar si hay espacio disponible.

 

 
Cuando la función buggy() es llamada, el computador almacena en la memoria la dirección de retorno (la próxima instrucción en main() después de la llamada de función) en el call stack del programa. Después que buggy() acaba, la ejecución del programa debería retornar a la dirección 0x00401047 (aquí en reverso en la memoria del programa porque la arquitectura x86 es little-Endian).
 

 

El nombre escrito por el usuario también es almacenado en el stack, en los 8 caracteres alocados para 'str'.
 

 

Pero, si el nombre tiene más de 8 caracteres, la función gets() va a despreocupadamente sobrescribir en la memoria adyacente:
 

 

Note que los dos caracteres finales – el ‘n’ final de Langton y el carácter null usado para indicar el final de la string – han atropellado la mitad de la dirección de retorno. El resultado es un cash, porque el control salta para la dirección 0x0040006E. Pero un invasor puede ir más allá e incluir un código shell ejecutable en la string de input para sobrescribir la dirección del original, de manera que el control ahora salte para el propio código del agresor.


Dos técnicas, llamadas de NX (No-eXecute) y DEP (Data Execution Prevention), combaten este tipo de ataque, asegurándole al nivel del hardware que una determinada sección de la memoria es grabable o ejecutable, pero no las dos cosas. Aunque el invasor encuentre una vulnerabilidad de memoria e inyecte un shellcode, la CPU va a recusar la ejecución de aquellas instrucciones.


La técnica ROP supera esta protección, utilizando el código existente en la aplicación de manera equivocada, o sea, de la forma que no originalmente se pretendía.


Para entender como eso funciona, vamos a empezar con una analogía. En Wisconsin, hay un poder del Ejecutivo conocido como veto Frankenstein, que le permite a un gobernante rechazar selectivamente las palabras de determinado proyecto de ley. Un ejemplo:

 


Al vetar determinadas palabras y frases, la ley ha sido modificada de:
[...] el secretario de administración debe transferir para el fondo general o para el fondo general de los saldos no comprometidos de las dotaciones de las agencias estatales, tal como definido en la subsección (1W) (a), además de añadir recursos suficientes y dotaciones de ingresos federales, un monto igual a $ 724,900 durante el año fiscal de 2006-07 [...]


Para:
[...] el secretario de administración debe transferir de los balances del fondo general un importe igual a $ 330,000,000 durante el año fiscal de 2005−06 e 2006-07 [...]



Al redirigir selectivamente el texto existente, el gobernador ha cambiado una apropiación en casi tres ordenes de magnitud. (¡Una versión anterior de este poder de veto permitía a los gobernadores vetar hasta letras individuales en un proyecto de ley!)


De manera semejante, el ROP reúsa fragmentos existentes de instrucciones de la aplicación vulnerable para fines no previstos originalmente. Al substituir partes de la pila de llamada, la técnica ROP permite saltar por todo el programa y cada vez ejecutar selectivamente un pequeño número de instrucciones anteriores a la declaración de una función 'ret' (de ‘return’, de donde viene su nombre).


Como hemos visto, es posible explorar un error de programación para sobrescribir la dirección de retorno de una función en el stack. Esto nos permite transferir el control del programa a un local arbitrario. Vea el siguiente fragmento de función:

 


Al establecer la dirección de retorno en 0x0040A4BB cuando sobrescribimos el stack, saltamos hacia el final de esta función, ajustando el register eax en 0 al hacer un  XOR en sí mismo. La instrucción de retorno en 0x0040ABD espera encontrar otra dirección de retorno en el stack, pero esta también puede ser sobrescrita junto con la dirección anterior. Un fragmento de código cuyo uso se desvía de esta manera se llama dispositivo ROP y una exploración conducida por la técnica ROP se forma por una cadena de tales dispositivos, llamados en secuencia por causa de los errores de la memoria intencionalmente corrompida. Debido a la dificultad de construir una secuencia adecuada de bytes para sobrescribir el stack y controlar el flujo del programa por medio de una secuencia de fragmentos de funciones, esta técnica es usada solo mientras es necesaria; un abordaje común es usar el ROP para ignorar el DEP y después usar técnicas más tradicionales para concluir la exploración del sistema.


Una vez entendido el mecanismo por detrás de la técnica ROP, volvemos a la cuestión que dio inicio a este post: ¿El Sky ATP intenta detectar el ROP directamente?


La respuesta es no, por las siguientes razones:

  1. Detección de ROP es redundante en un sandbox anti-malware. El ROP es usado como un primer paso para rodar un código malicioso en determinado dispositivo. El propósito del malware es hacer algo malicioso: ransomware, una puerta trasera para añadir el computador de la victima a un botnet, robo de datos etc. El análisis dinámico del motor del Sky ATP detecta un conjunto variado de indicadores de malicia, independientemente de que el primer punto de apoyo haya sido un ROP.
  2. Los ROP son específicos para cada sistema y frágiles; entonces, detectarlos en un sandbox es muy improbable. Como se ha dicho, los ROP buscan errores de programación en una aplicación ya instalada, entonces el sandbox también necesita ser configurado con la misma versión vulnerable. Además, como las exploraciones conducidas por los ROP saltan por el código ejecutable bruto, pequeños cambios en la configuración del sandbox (diferentes versiones de bibliotecas del sistema, variaciones de hardware etc.) frecuentemente neutralizan el ataque, resultando como máximo en un crash de la aplicación, no en una exploración exitosa. Las personas deberían preguntar a los proveedores de antimalware con detectores de ROP cuantas veces ellos lograron detectar un verdadero ROP en ambientes de producción.
  3. La detección de los ROP usa muchos recursos. Para observar estándares ROP en el flujo del programa, sería necesario monitorear las actividades de un sistema a nivel de hardware. Es mucho más fácil detectar un malware evasivo.


La baja probabilidad de detectar un ROP en actividad debe ser comparada con el alto costo de emulación a nivel de CPU. Si se multiplica esto por el número de sistemas en que una muestra debe ser ejecutada para asegurar alguna probabilidad de combinación entre la exploración y una vulnerabilidad, la relación de costo-beneficio no tiene fin. Como una exploración exitosa también sería detectada por indicadores comportamentales, la mayor parte de las soluciones antimalware – incluso el Sky ATP – no hace la detección directa de ROP.

Deja un comentario

Asegúrate de llenar la información requerida marcada con (*). No está permitido el código HTML. Tu dirección de correo NO será publicada.

Sportbook sites http://gbetting.co.uk/sport with register bonuses.