Técnicas de ofuscación de comandos en la consola de Windows (CMD)

En una APT ejecutar comandos en la consola de windows o CMD es sinónimo de ofuscación. Al hilo de ésto, recogemos varias técnicas para ofuscar comandos que pueden evadir las detecciones más simplistas y que aún en día se utilizan y suelen ser muy efectivas para conseguir evadir muchos sistemas de detección. Hagamos un repaso a las mismas:

Empezamos con lo más fácil o tonto, en CMD no se distingue entre mayúsculas y minúsculas, ping = PINg = PING:


Ahora pasamos a los caracteres especiales comúnmente utilizados para ofuscar comandos:

1. El carácter "^" es el carácter de escape más común en la consola de comandos ya que no afecta a la ejecución. En el entorno cmd, algunos caracteres tienen funciones especiales, como >, >> para redireccionar, | para canalizar otros comandos, &, &&, y || para conectar con más instrucciones. Todos tienen funciones específicas. Si se necesitan mostrar como caracteres, se debe escapar de éstos primero: agregue un carácter de escape ^ antes de cada carácter especial. Por ejemplo: echo ^>, echo ^|, echo ^|^|, echo ^^ y c^m^d.


2. La coma "," y el punto y coma ";" son intercambiables y pueden reemplazar los espacios permitidos en el comando. Los espacios múltiples no afectan la ejecución del comando.


3. Los paréntesis emparejados () también pueden aparecer en los parámetros del comando y no afectarán la ejecución del comando. Los paréntesis indican grupos de subcomandos integrados, que también son interpretados por el intéprete de parámetros.


4. Comillas dobles. Ajustar caracteres con comillas dobles es equivalente a conectar caracteres.


Otra técnica muy común es usar variables de entorno para ofuscación.

Las variables de entorno en cmd.exe se dividen en las variables de entorno existentes y las variables personalizadas del sistema. Usando caracteres o cadenas de caracteres en el valor de las variables de entorno, se pueden unir comandos y escapar de las detecciones estáticas.

En cmd, el comando set se usa para mostrar, establecer o eliminar variables de entorno cmd.exe. Formato de comando:

SET [variable = [cadena]]
  •     variable especifica el nombre de la variable de entorno.
  •     string especifica una serie de cadenas que se asignarán a la variable.
Al ingresar set en la línea de comandos, se enumerarán todas las variables de entorno en cmd.exe. La interesante es la variable %ComSpec%. El valor predeterminado es "C:\WINDOWS\system32\cmd.exe".


Podemos usar las variables de entorno existentes en el sistema para extraer el comando cmd deseado usando las variables de entorno. El formato es el siguiente:

%VarName:~offset[,length]%

Se utiliza principalmente para obtener el valor de la variable de entorno VarName, y la longitud después del byte de desplazamiento. [,length] puede omitirse. El subíndice predeterminado comienza en 0, y el desplazamiento también admite números negativos, lo que significa que el subíndice de la cadena se recorre a la inversa. Por ejemplo: sacar cmd.exe a través de %comspec%.


Por lo general, también podemos personalizar una o más variables de entorno, usar los caracteres en el valor de la variable de entorno, extraer y unir el comando cmd que queremos finalmente. Por ej.:

cmd /c " set envar1=ser&& set envar2=ne&& set envar3=t u&&call echo %envar2%%envar3%%envar1%"


Nota: cmd / C "string" significa: ejecutar el comando especificado por la cadena string y luego finalizar.


Como se ve en la ayuda, el parámetro /V:ON puede extender el uso de la variable de entorno en tiempo de ejecución. Podemos usar también !Var! en lugar de %var%:

cmd /V:ON /C " set envar1=ser&& set envar2=ne&& set envar3=t u&& call echo !envar2!!envar3!!envar1!"


Además de set, cmd.exe también tiene assoc, ftype, etc. Podemos usar la información generada por estos comandos internos para unir los comandos cmd que queramos.

assoc: Comando de asociación de extensión de nombre de archivo, utilizado para mostrar y establecer la asociación de extensión de nombre de archivo. Un archivo con un cierto nombre de sufijo puede abrirse o ejecutarse de acuerdo con un tipo específico de archivo. El formato del comando es:

assoc [.ext[=[fileType]]]


(Como veis, en la máquina virtual en la que he estado haciendo las pruebas no tengo ningún lector pdf instalado).

ftype: muestra o modifica el tipo de archivo utilizado en la asociación de extensión de archivo, y especifica qué programa ejecutar o abrir para un tipo de archivo de forma predeterminada. El formato del comando es:

ftype [fileType[=[openCommandString]]


Uso de loops o bucles

Los bucles se usan a menudo para ofuscar comandos cmd, lo que hace que los comandos cmd parezcan complicados y difíciles de detectar, lo cual es un uso de nivel relativamente alto en la ofuscación.


Con el bucle For, los parámetros más utilizados son /F y /L.

FOR /L %variable IN (start,step,end) DO command [command-parameters]

Este conjunto representa una secuencia de números desde el principio hasta el final en forma incremental. Por lo tanto, (1,1,5) producirá la secuencia 12345, (5, -1,1) producirá la secuencia (54321)

FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
FOR /F ["options"] %variable IN ('command') DO command [command-parameters]

Por ejemplo, para generar con el loop For comandos:

for /f " delims=f= tokens=2" %f IN ( 'assoc .cmd' ) do %f

delims=f=: Separar cadenas con f y =
tokens=2: seleccionar la segunda columna después de la separación


Después de dividir el contenido devuelto de assoc .cmd, la segunda columna es exactamente cmd, y el resultado final es la ejecución de cmd.

Programas para ofuscación

Basado en los principios anteriores, Daniel Bohannon creó hace un tiempo una herramienta especial de ofuscación de comandos en cmd:

https://github.com/danielbohannon/Invoke-DOSfuscation:


Exiten tres niveles de ofuscación. Usaremos ipconfig para el ejemplo:

1. Ofuscación elemental simple a través de variables de entorno

cmd /C"set 4i=ipc&&set E3z=onfig&&call set sfkl=%4i%%E3z%&&cmd.exe /C %sfkl%"

2. Intermedio

^c^M^D, , , , /^c", ,(, , , , , (s^et ^ w^3=i^pco) , )&& (S^Et ^ eH^P=n^fig)& , , C^aLl, sE^t GyHE=%w^3%%eH^P%& , , %LoCaLAPpdata:~ -3,+1%%pRoGramw6432:~9,1%d, ,/^R, , %Gy^HE%"

3. Avanzado

^F^o^r; /^F ; , " delims=i=f tokens=2 " ,,%^2, IN; ( ,; ' ; , ^^A^^ssoC ,.cmd '; ; ) ; , ^DO ; ,%^2; ;M, , QbYcFKyL5/R "; ;(^se^T ^ ^ -,^]=^p)&&(,,,(s^e^T^_^*=^i);;)&&(^s^E^T^^@,+=^f)&& (^S^Et ^ ^{^$^+=^i)&& ( ,; ,;, (S^e^T ^.^[,^$=^g) )&& ( , (^S^e^t ^ ^#@^;=^co) ,)&&(,,,(s^E^t \^;'^?=n) ; ; )&& ; ^cA^ll ; s^e^T @}=%^{^$^+%%^ -,^]%%^*#@^;%%\^;'^?%%^@,+%%_^%%^.^[,^$%&&; ^C^A^LL,E^C^Ho; %^@^}%"|, ; F^Or , /^f ;;"tokens= 1 delims=qfNzR" , ; %^D ; ^In ; (; ; ' ;, ^^^^Ft^^^^YP^^^^E ; ,^^^|; ,^^^^F^^^^iN^^^^Dst^^^^R,^^^^c^^^^m ' ; ); , ^d^O, , %^D;

Contramedidas

Existen cuatro métodos principales de detección: detección estática, IA, análisis semántico y ejecución en sandbox.

Detección estática

De acuerdo con los métodos de ofuscación mencionados anteriormente, se extraen las ramas de características clave para el análisis sistemático. Se sabe que los mejores proyectos son de código abierto, como por ejemplo:

https://github.com/We5ter/Flerken

Esta es una herramienta multiplataforma, no solo puede detectar ofuscación en CMD, sino que además detecta shell, powershell y otros métodos de ofuscación de comandos.

AI

Por ejemplo FireEye usa inteligencia artificial para la detección de ofuscación de comandos. Detalles de diseño:

https://www.fireeye.com/blog/threat-research/2018/11/obfuscated-command-line-detection-using-machine-learning.html

Las características extraídas son las siguientes:

- Longitud de la línea de comandos
- Número de intercalaciones en la línea de comandos
- Número de símbolos de tubería o pipe
- Porcentaje de espacios en blanco en la línea de comandos
- La proporción de caracteres especiales
- Entropía de strings
- La frecuencia de las cadenas "cmd" y "power" en la línea de comando

Análisis semántico

Es recomendable echar un vistazo al siguiente artículo que, aunque es solo un producto sin acabar, se muestra un script de Python para restaurar el análisis semántico del comando ofuscado.

https://ddvvmmzz.github.io/Windows-CMD%E5%91%BD%E4%BB%A4%E5%8E%BB%E6%B7%B7%E6%B7%86

Aunque solo se realizó una parte de la restauración del comando ofuscado, la idea sigue siendo buena. Las características son:

- Reemplazar el símbolo ^
- A través de las reglas de = y %, encuentra variables ofuscadas
- A través de la palabra clave set, encuentra variables ofuscadas
- A través de palabras clave %: ~ n, m%, encuentra variables ofuscadas

Antes de restaurar:

cmd /C"set uZxp=t u&&set RuT=ne""&&set HvW=s""er&&call set iQl=%RuT%%uZxp%%HvW%&& call cmd /C %iQl%"

Después de restaurar:

cmd /C"call cmd /C net user"

Ejecución en sandbox

Siguiendo con Fireeye proporcionan la solución flare-qdb, sin mencionar los detalles, que utiliza el depurador para monitorizar las variables de registro, a fin de obtener el proceso de restauración de comandos.

https://github.com/fireeye/flare-qdb/blob/master/doc/dedosfuscator.md

Fuente: https://mp.weixin.qq.com/s/hJ6gn9EMKNmMOofEg3i6Iw

Referencias:

Comentarios