How To Quickly Extract Malicious Macros From Maldoc & Triage Incident

Macro Enabled Doc

Ever received an Incident where a user machine got infected by a malicious attachment which he/she received in the email and as an Incident Responder it suspects you of having a malicious macro that takes advantage of Windows' own legitimate tools like CMD and PowerShell. But not sure how to quickly extract and analyze macros without going through a lot of hassle? Or let's say want to quickly get into the conclusion as to what has happened.

Incident Response (IR) is not just about mitigating incidents but how quickly you respond to those incidents such that the malware doesn't do much damage to the system(s) and future attacks can be prevented in a timely manner once you know how to proceed with a particular case. As malware authors keep their malicious code highly obfuscated, it actually becomes really difficult to go through the 100s of lines of obfuscated code, understand it's functioning and try to properly de-obfuscate it so that the code actually makes sense. It is a time-consuming process and time is the key factor when it comes to responding to such incidents. But if you want to have a sneak peek on how we can analyze a macro manually then have a look at the link below:

Read more:

So, In this post, I'll actually be demonstrating how quickly we can extract malicious macros from a document be it a word doc file or a pdf file or any other attachment without going into much detail about the functionality of what the macro does. The goal here will be to quickly extract the macros, deobfuscate it and identify the C2 servers from where the malicious binaries will be downloaded. But some would say such information can be extracted by running the sandbox like Hybrid Analysis, VirusTotal or Cuckoo. I agree, but what's the fun of just dropping the file in a sandbox and waiting for the report to appear. I think that's fine but it doesn't answer my question “how things work” and “how such info. is extracted” and I am more of a practical guy so… I think you got it what I am trying to say.

Warning: All my analysis is done on an isolated machine Flare VM as I will be infecting that machine intentionally. And once done will revert back to the clean snapshot.

So, Let's Get Started

Ok, so enough talking and let's dive into it. I was provided with a malicious document after an incident where the user opened a malicious word document and enabled macros. The infection was however prevented by one of the security tools and was asked to further investigate this.

SHA1 of a doc file – 644f4dd0405eef53114a7a5a75aadb4d

Macro Enabled MalDoc
Macro enabled malicious document

Initially to check whether a document is having macros embedded, one can use a tool called Oletools suite provided by Didier Stevens. Oledump returns a list of the document structure and specifies which module contains the macros which can be identified by M or m tag. In our case, the modules 10, 11 and 12 show the presence of macros.

Macros in document
Oledump showing modules having macros

Another tool olevba, which is a part of oletools, shows the summary of the word document and also tells what all suspicious indicators are present in the document. Here, AutoExec is the most important one to remember as it tells that the macros will run the moment word document is opened. Rest it tells the presence of base64 encoded strings.

Suspicious Indicators in Doc
Suspicious indicators in a document

Now, once we have identified that our document is indeed malicious and contains macros, our next step would be to extract macros. But we will not be extracting manually but directly from the memory after executing a malicious document. A tool called API monitor would do its purpose. With this, we will be actively monitoring the API calls our word document calls when it is launched and macros are enabled. Here, I am monitoring some of the API calls like CreateProcessW, CreateProcessA, GetCommandLineA, GetCommandLineW. CreateProcess is responsible for creating a new process whereas GetCommandLine retrieves the command-line string for the current process. Notice A or W as a postfix after the function calls. It simply indicates that the function call accepts either of the string parameters where A is for ASCII strings and W for wide-character strings.

Monitoring API calls
Monitoring API calls

Here, after launching the malicious word document (don't click the macros yet), we will start monitoring the process.

Monitoring Word
Monitoring Word for Capturing Macros

And soon after enabling the macros, we can see that the PowerShell process being launched and a command-line code that it executes is also visible. Here, we will click on the monitor button and continue monitoring this process as well. As now it is clear that the macro launches the Powershell and performs some commands our next step would be to extract this Powershell obfuscated code directly from memory.

PowerShell Process Launched
PowerShell launched

If we go and check the API monitor dashboard we can see that our Powershell code is visible under the API call GetCommandLineA and the module which calls this function is a module named rasman.dll. Voila.

PowerShell Mal code
PowerShell malicious code in memory

As we were unable to see the full Powershell code in API monitor, we can use another tool Process Hacker to extract that obfuscated code. In the Processes tab look for the process WINWORD.EXE.

Getting full PowerShell code
Getting full PowerShell code

Once we are in the properties section of that particular process and under the Memory tab, performing a string search will provide us with the whole list of strings that are residing in the memory.

macro IR 14
Extracting Powershell code from memory

Filtering to what string we are looking for powershell -w hidden, as we saw earlier during monitoring API calls, a result was provided. Below were the 3 results where all the strings were the same. So, clicking on any of the results and saving it to a separate text will copy our fully obfuscated Powershell code.

Powershell code
Powershell code

Below is the Base64 encoded code that we have extracted from the memory without actually looking at the macro modules. This is one of the fastest ways to extract shellcode from memory. But other methods do exist as well. Any other method that suffices your purpose is recommended.

Obfuscated Powershell Code
Obfuscated Powershell Code

Now, to have a look at what's actually happening behind the code we have to deobfuscate the above code. Since it is a base64 encoded code I will use one of my favorite tools CyberChef to decode it. Well, it can be used for other operations as well and is not just limited to Base64. CyberChef actually works on the basis of recipes and provides the flexibility of using a ton of operations on a set of code. After decoding the Base64 code the output seems to make sense a little but it is still hard to read as it still has a lot of gibberish code. So, let's clean it up.

Decoding with CyberChef
Decoding Base64 code with CyberChef

After applying some of the operations to our code, it looks lot nicer now and we can see the presence of 5 URLs (C2 servers) from where more binaries will be downloaded to the system and then executed. The script also uses the environment variable $env:userprofile to fetch the user's profile directory of the logged-in user. The file is then saved to the user's profile directory (C:\Users\<Username>) with the file name as 47.exe.

Further, it also checks whether the dropped file is greater than or equal to the size of 34 KB. If the dropped file is greater than or equal to the mentioned size then it executes the file 47.exe from the user's profile directory using the System.Diagnostics process which provides access to local and remote processes and enables you to start and stop local system processes as per Microsoft documentation.

CyberChef Recipe
CyberChef Recipe

One of the recipes of the CyberChef is to quickly extract URLs from the deobfuscated code without modifying anything. Pretty interesting.

Extracting C2 Server
Extracting C2 Server

I was quick enough to triage the incident but while trying to get those binaries; 2 URLs were already down and was managed to get 3 binaries all having the same hash values but with different names. Because these C2 servers don't stay for long, a quick triage is required to identify such C2 servers and extract binaries out of them so that the advanced analysis can be performed later.

Indicators of Compromise (IOCs)

  • SHA1 (a9QKWhDB.exe) – c288b07fe8e4bdac648373b463c6a0c41347ca69
  • SHA1 (47.exe) – c288b07fe8e4bdac648373b463c6a0c41347ca69
  • Delivery URL – hxxp://rmcentre.bigfilmproduction[.]com/wp-includes/LrOqh
  • Delivery URL – hxxp://lecadeaugourmand[.]fr/47mn04/oS8DkV/
  • Delivery URL – hxxp://datnentayhanoi[.]info/wp-includes/pyZrddg/
  • Delivery URL – hxxp://bietthuvinhomesgialam[.]xyz/cgi-bin/acB4q4y/
  • Delivery URL – hxxp://clickbankbreakstheinternet[.]com/oA6enI8/