Hola a tod@s!!

Un amigo estaba jugando con una muestra, entrenando y/o analizando el comportamiento del documento RTF y cuando le pasó alguna que otra regla YARA para ver si era detectado o no, se llevó una sorpresa, no detectaba el tipo de documento que se trataba, pero ¿Por qué no? ¡¡Si era una muestra de hace casi 3 años!! ... Pues ahora veremos porqué…

Antes de nada, sepamos de qué estamos hablando:

Muestra Virustotal

Para los que no lo conozcan, aquí disponéis de toda la información al respecto.

* Descripción : Microsoft Office 2007 Service Pack 3, Microsoft Office 2010 Service Pack 2, Microsoft Office 2013 Service Pack 1 y Microsoft Office 2016 permiten que un atacante ejecute código arbitrario en el contexto del usuario actual al no gestionar correctamente los objetos en la memoria. Esto también se conoce como "Microsoft Office Memory Corruption Vulnerability". El ID de este CVE es diferente de CVE-2017-11884.

Le pregunté sobre los repositorios de reglas Yara que había utilizado y me dijo los siguientes (entre otros):

Pensé que sí que era curioso, porque también los utilizo y suelen contemplar casi todo. Encontré las siguientes referencias al cve en cuestión:

$ grep -iR "CVE-2017-11882" ./* | awk -F\: '{print $1}' | grep ".yar" | sort -u
./Open-Source-YARA-rules/one offs/packager_cve2017_11882.yar
./Open-Source-YARA-rules/ReversingLabs/CVE_2017_11882.yar
./Open-Source-YARA-rules/Trend Micro/cracked_loki.yar
./rules/cve_rules/CVE-2017-11882.yar
./rules/cve_rules_index.yar
./rules/index_w_mobile.yar
./rules/index.yar
./signature-base/yara/exploit_cve_2017_11882.yar

Y comprobé lo que me habían dicho sobre la detección del malware.

for i in 'grep -iR "CVE-2017-11882" ./* | awk -F\: '{print $1}' | grep ".yar" | sort -u'; do echo -n "$i => "; yara "$i" insurance-2017-2018.doc 2>/dev/null | wc -l ; done
./Open-Source-YARA-rules/one => 0
offs/packager_cve2017_11882.yar => 0
./Open-Source-YARA-rules/ReversingLabs/CVE_2017_11882.yar => 0
./Open-Source-YARA-rules/Trend => 0
Micro/cracked_loki.yar => 0
./rules/cve_rules/CVE-2017-11882.yar => 0
./rules/cve_rules_index.yar => 0
./rules/index_w_mobile.yar => 0
./rules/index.yar => 0
./signature-base/yara/exploit_cve_2017_11882.yar => 0

Lo primero que suelo hacer es obtener las strings del fichero (comando strings).

String Reglas YARA

Comprobamos además qué tipo de fichero es, ya que la vulnerabilidad se aprovecha de uno concreto como vimos en la descripción de la vulnerabilidad, no vale cualquiera:

$ file insurance-2017-2018.doc
insurance-2017-2018.doc: Rich Text Format data, unknown version

Si queréis comprobar el “Magic Number” ya que os será útil para utilizarlo en las reglas yara, podéis hacerlo de esta forma:

$ xxd insurance-2017-2018.doc | head -1
00000000: 7b5c 7274 6635 2050 4c45 4153 4520 454e {\rtf5 PLEASE EN

Como habéis podido leer en la misma Wikipedia, el formato, concuerda con el encontrado:

Formato RTF

Así que no hay lugar a dudas, se trata de un documento RTF (Rich Text Format).

A simple vista llama la atención un par de detalles, ( Los encuadro ) :

Detalles Reglas YARA

Utiliza “Equation.3” y hay cadenas de caracteres en hexadecimal que habrá que ver de qué se trata.

Para ello se puede utilizar una herramienta de conversión entre diferentes formatos llamada CyberChef - The Cyber Swiss Army Knife

El funcionamiento es sencillo, a la izquierda tienes una tabla en la que tienes que seleccionar la entrada (en nuestro hexadecimal), un delimitador (en este caso auto) y nos muestra la salida:

CyberChef

Bien, dicho esto,  introducimos esa cadena en hexadecimal y veremos su contenido.

Salida CyberChef

Como puede verse en la imagen, se ejecuta un comando “mShta http://…./rtf1.txt”. También he encuadrado esa cadena “eQUATION NATIVE”, comprenderéis porqué en unos instantes.

He visto reglas en las que si el fichero es un RTF y contiene la palabra Equation ya es considerado como “malicioso”. Vamos a tratar de, además de eso, considerarlo de esa forma siempre y cuando realice algo más, como en este caso. Claro está, se puede escapar algo.

Una vez me puse a ver porque para esa muestra no era detectada, vi que en muchos casos no se contempla si alguno de los caracteres en las cadenas se cambiaba de mayúsculas a minúsculas o viceversa. Un método muy común para evasión de Antivirus o reglas varias que puedas encontrar.

Si yo espero “Equation.3” y me lo cambian a “equation.3” y no contemplo que sea “case insensitive”, la regla no será efectiva. Lo que pude ver en las reglas es eso mismo, seguramente en las primeras muestras que salieron se detectaba de esta forma y los que se dedican a hacer el malware se dieron cuenta y fueron cambiando los valores hasta que estas reglas no lo detectaran.

Regla YARA Case Insensitive

Cuando son cadenas, poniendo “nocase” al final se podría solucionar. Pero ¿qué ocurre cuando son valores en hexadecimal como hemos visto? Véase la primera regla de la imagen anterior.

En una de la imágenes ya se veía lo que os acabo de contar, lo vemos de nuevo:

Equation3 CyberChef

equation.3 => 6571756174696F6E2E33
Equation.3 => 4571756174696F6E2E33

A mí me interesa todas las combinaciones posibles, equation.3, eQuation.3, eqUation.3 … EQUATION.3. Y además me interesa si utilizan unicode, 006500710075006100740069006F006E002E0033.

Seguro que habrá varias formas de conseguir esto con las reglas YARA, pero a mí se me ocurrió hacerlo con Regex.

Con el siguiente script podemos obtener estas reglas en el formato que nos interesa (perdonadme,  no me he complicado mucho):

import sys

if len(sys.argv) != 3:
print "Usage: %s <String_to_HEXA_Regex> <A|W> - by Rafa\n" % (sys.argv[0])
sys.exit()

myregex = ''
myasc = ''
mystring = sys.argv[1]'
myformat = sys.argv[2].upper()
if myformat == 'W':
myasc = '(00|)'
for i, mychar in enumerate(mystring):
myregex += myasc + '[' + format(ord(mychar.lower()), "x") + '|' + format(ord(mychar.upper()), "x") + ']{2}'

print myregex

Queremos, por ejemplo, sacar la regex que nos interesa para el comando powershell.

$ python stringtoregexhexa.py powershell W
(00|)[70|50]{2}(00|)[6f|4f]{2}(00|)[77|57]{2}(00|)[65|45]{2}(00|)[72|52]{2}(00|)[73|53]{2}(00|)[68|48]{2}(00|)[65|45]{2}(00|)[6c|4c]{2}(00|)[6c|4c]{2}

Esto lo incluiremos de la siguiente forma en nuestra regla yara:

$pwsh = /[70|50]{2}(00|)[6f|4f]{2}(00|)[77|57]{2}(00|)[65|45]{2}(00|)[72|52]{2}(00|)[73|53]{2}(00|)[68|48]{2}(00|)[65|45]{2}(00|)[6c|4c]{2}(00|)[6c|4c]{2}/

Le podemos quitar el “(00|)” inicial y comenzar directamente en el valor de la P en mayúscula y minúscula.

Lo mismo con el resto de comandos que queramos detectar. Voy a coger una de las reglas y modificarla para la detección del documento.

rule RTF_CVE_2017_11882_REGEX {
meta:
description = "Detects suspicious Microsoft Equation OLE contents as used in CVE-2017-11882"
license = "https://creativecommons.org/licenses/by-nc/4.0/"
author = "rule EXP_potential_CVE_2017_11882 modified by Rafa"
reference = "Internal Research"
date = "2020-10-24"
score = 60
strings:
$equation1 = "Equation.3" nocase ascii /* Equation 3.x */
$equation2 = /[65|45]{2}(00|)[71|51]{2}(00|)[75|55]{2}(00|)[61|41]{2}(00|)[74|54]{2}(00|)[69|49]{2}(00|)[6f|4f]{2}(00|)[6e|4e]{2}(00|)[20|20]{2}(00|)[6e|4e]{2}(00|)[61|41]{2}(00|)[74|54]{2}(00|)[69|49]{2}(00|)[76|56]{2}(00|)[65|45]{2}/ /* E.Q.U.A.T.I.O.N. .N.A.T.I.V.E */
$mshta = /[6d|4d]{2}(00|)[73|53]{2}(00|)[68|48]{2}(00|)[74|54]{2}(00|)[61|41]{2}/
$http = /[68|48]{2}(00|)[74|54]{2}(00|)[74|54]{2}(00|)[70|50]{2}(00|)[3a|3a]{2}(00|)[2f|2f]{2}(00|)[2f|2f]{2}/
$https = /[68|48]{2}(00|)[74|54]{2}(00|)[74|54]{2}(00|)[70|50]{2}(00|)[73|53]{2}(00|)[3a|3a]{2}(00|)[2f|2f]{2}(00|)[2f|2f]{2}/
$cmd = /[63|43]{2}(00|)[6d|4d]{2}(00|)[64|44]{2}/
$pwsh = /[70|50]{2}(00|)[6f|4f]{2}(00|)[77|57]{2}(00|)[65|45]{2}(00|)[72|52]{2}(00|)[73|53]{2}(00|)[68|48]{2}(00|)[65|45]{2}(00|)[6c|4c]{2}(00|)[6c|4c]{2}/
$exe = /[2e|2e]{2}(00|)[65|45]{2}(00|)[78|58]{2}(00|)[65|45]{2}/
condition:
( uint32be(0) == 0x7B5C7274 or uint32be(0) == 0x7B5C2A5C ) /* RTF */
and $equation1 and $equation2
and any of ($mshta, $http, $https, $cmd, $pwsh, $exe)
}

Si os fijáis en la cabecera “0x7B5C7274” corresponde con parte del “Magic Number” que habíamos visto.

Magic Number Reglas YARA

Ahora solamente nos queda probar el resultado.

$ yara RTF_CVE_2017_11882_REGEX.yar insurance-2017-2018.doc 2>/dev/null
RTF_CVE_2017_11882_REGEX insurance-2017-2018.doc

$ yara RTF_CVE_2017_11882_REGEX.yar insurance-2017-2018.doc 2>/dev/null | wc -l
1

Y como podéis comprobar ya es detectado. La causa, posiblemente, será la que os he comentado, al principio se detectaba cualquier fichero RTF que quisiera explotar la vulnerabilidad pero con el paso del tiempo, han ido alterando ciertas cadenas para evadir tanto antivirus como reglas yara existentes.

Utilizar reglas yara para detectar lo que tienes delante es imprescindible, siempre te da idea por donde tirar y son de mucha ayuda. Esos repositorios que puse al principio son la base (entre otros), puede que haya que retocar alguna regla de vez en cuando, pero no es lo normal, según los utilizas comienzan a salir detecciones que luego te ayudan, como he dicho, a analizar la muestra que sea de forma más adecuada, hay que utilizarlo, sin duda.

Espero que os haya gustado y nos vemos en el siguiente post!