Seguridad

Técnicas de ofuscación para AMSI

Muy buenas a todos. En este post vamos a hablar de como los antivirus (AV) detectan scripts maliciosos en tiempo de ejecución y las medidas para ofuscar los scripts en Powershell y que la ejecución de este no sea bloqueada por el AV.
Como ya se ha visto en artículos anteriores , AMSI es una API que conecta el AV con Powershell para identificar si un script puede ser o no malicioso en tiempo de ejecución y en caso de serlo, bloquearlo. Pero la pregunta que hay que hacerse es la siguiente: ¿Cómo los antivirus detectan si el script es malicioso? La respuesta a esta pregunta son las firmas de los AV.

Firmas de antivirus en Powershell 

Las clásicas firmas de virus son una secuencia continua de bytes comunes en cierta muestra de malware, es decir, si esa secuencia continua de bytes está incluida en un archivo, ese archivo es malware.
Siguiendo este concepto, las firmas de antivirus en PowerShell son patrones únicos que representan cadenas características en los scripts escritos en este lenguaje. Cuando un script es escrito en la consola de Powershell, al ejecutarlo, AMSI envía el script al antivirus y este detecta si la firma de alguna de las cadenas incluidas en el script puede ser susceptible de ser maliciosa o si toda la cadena lo es y si estos casos se cumplen, la ejecución del script es bloqueada por el antivirus.
Como ejemplo a esto, si intentásemos usar mimikatz en Powershell, como la cadena de mimikatz es bien conocida por ser un script que podría ser malicioso en manos equivocadas, si se intenta invocar, aunque el archivo no esté en el path, antes de saltar el error de que el script no se encuentra, saltará el error de que el script contiene uno o más elementos malintencionados y que ha sido bloqueado por el antivirus.
Lo mismo ocurre si escribimos la cadena amsiInitFailed que es usada en algunos bypass de AMSI, el antivirus lo va a detectar y bloquear porque hay una firma en el antivirus de esta cadena en concreto:
Esto, por tanto, supone un impedimento a la hora de ejecutar scripts maliciosos en primera instancia, por eso lo que se suele hacer es ofuscar las cadenas del script de manera que estas no tengan firma en el antivirus y por tanto lo hace indetectable al AV.

Técnicas de ofuscación en Powershell

Para evadir la detección del AV, se utilizan técnicas de ofuscación para modificar el código fuente de un script de manera que sea más difícil de detectar y analizar. Este conjunto de técnicas son la siguientes:

Codificación y decodificación en Base64: 

Esta técnica consiste en codificar el contenido del script en Base64 y decodificarlo en tiempo de ejecución, es decir, se codifica en Base64 la cadena que hace de trigger para el AV y se decodifica en dentro del script. 
Como ya hemos visto, la cadena amsiInitFailed es detectada por el AV, pero si la pasamos a base64 la cadena pasa a ser YW1zaUluaXRGYWlsZWQ= y al volver a convertirla en ASCII, ya no la detecta, y se imprimirá por terminal.

Concatenación y escape de caracteres

El operador para concatenar en Powershell, como en otros muchos lenguajes, es el carácter +. Una manera de ofuscar el código de un script es dividiendo las cadenas que lo incluyen y que tienen una firma en el AV, de manera que a la hora de escribir el script y concatenarlas en tiempo de ejecución, el antivirus no detecta la ejecución que sí detectaría sin esta concatenación porque la firma de la cadena dividida no está incluida en el mismo.
Otra manera de ofuscar es incluyendo en las cadenas el carácter de escape que en Powershell es el carácter `. Este tipo de carácter se suele incluir dentro de una cadena de caracteres.

Reordenación de cadenas con formateo

Powershell también incluye el formateo de cadenas mediante el comando -f. Con esto podemos escribir una cadena que normalmente detectaría el AV por tener una firma y reordenarla en tiempo de ejecución.

Reflejo de métodos .NET

En internet existen numerosos scripts que hacen bypass a AMSI. Uno de los más famosos es el de Matt Graeber que usa el método de reflejo.
El reflejo de métodos .NET (reflection en inglés), consiste en inspeccionar, invocar y acceder a datos de tipos .NET que incluyen tanto parámetros públicos como privados. Por defecto, PowerShell proporciona acceso a las propiedades y métodos de acceso público, pero utilizando las API de reflexión, puede acceder a los parámetros privados.
El método es el siguiente:
[Ref].Assembly.GetType(‘System.Management.Automation.AmsiUtils’).GetField(‘amsiInitFailed’,’NonPublic,Static’).SetValue($null,$true)

Sin embargo, ya es tan usado que hay que aplicar alguna de las técnicas descritas arriba y la siguiente técnica que se va a explicar para que el antivirus no lo detecte.

División de scripts en distintas líneas

Existen muchos scripts de una sola línea (one-liner en inglés) que usan métodos como reflection junto con concatenación de cadenas, etc. Aunque, el uso de estos scripts está tan extendido que ya hay firmas para este tipo de scripts. 
No obstante, una manera simple de evitar que AMSI se queje, es dividiendo el código en distintas líneas o si es un código de una misma línea como el de Matt Graeber, dividiéndolo en distintas variables. De esta manera, aunque a primera vista pueda parecer absurdo, como ya hemos explicado cómo funcionan las firmas de los antivirus en Powershell y AMSI, tiene sentido que sea posible esta manera de ofuscar el script.
Veámoslo en un ejemplo.
En la imagen podemos ver que el primero es el script original y al segundo se le ha aplicado concatenación de cadenas de caracteres para intentar evitar al AV. Sin embargo, es tan usado que algo así no es válido.
Pero si dividimos este script en distintas líneas, el tema cambia como os voy a demostrar en la siguiente imagen:
Como se puede ver, al dividirlo en distintas variables más el uso de la concatenación de cadenas de caracteres es posible evitar que AMSI detecte este script y se efectúa correctamente el bypass.
Hay que aclarar que normalmente estas técnicas se usan a la vez en un mismo script ya que todas las explicadas en este post son más eficaces si se realizan en conjunto que por separado.
Esto es todo por ahora. En los siguientes artículos de AMSI se verán distintas técnicas de cómo realizar estas evasiones (cuyos scripts evidentemente estarán ofuscados con alguna de las técnicas aquí mencionadas).
¡Hasta el próximo post!
 Justo MartínSecurity Analyst at Zerolynx.

Powered by WPeMatico

Gustavo Genez

Informático de corazón y apasionado por la tecnología. La misión de este blog es llegar a los usuarios y profesionales con información y trucos acerca de la Seguridad Informática.