“Inhibiting Malicious Macros by Blocking Risky API Calls”

 

Microsoft Office Macros have been the bane of security analysts’ lives since the late 1990s. Their flexibility and functionality make them ideal for malware authors to use as a primary stage payload delivery mechanism, and to date the challenge they pose remains unsolved. Many organisations refrain from blocking them completely due to the impact it would cause to their users, and instead rely on a combination of detection and mitigation technology to compensate for the risk they pose.

I have long thought that it would be ideal if Microsoft were able to implement granular controls via group policy over which activities macros were permitted to perform, for example allowing the blocking of process execution or network activity. In the interim, I have been experimenting with alternative methods to limit which functions a macro can call, either by redefining or patching the high risk API calls to prevent their intended outcome.

Below we can see a very basic example of what a malicious macro might look like. The fact that the subroutine is named “AutoOpen” means that it will be run as soon as the document is opened (and if required, macros are enabled). The command “Shell” at the beginning of the line instructs Word to execute the process as specified in the parameter, so in this case the macro will launch the Windows calculator.

 

SS4

 

Option 1 – Using global templates to override built-in functions

Shell is the function built into VBA which is used to launch new processes, and as such, can often be found in malicious macros. Malware authors leveraging macros as a primary stage payload typically want to either download or drop a file, and then execute it. Alternatively, they could decide to execute an existing process on the system, such as powershell, with parameters which will take actions against their intended target. Common to both of these methods is the requirement for something to be run, and this is where Shell comes in. If we were able to somehow disable the Shell function, then we might be able to prevent the malicious macro from succeeding in it’s goal.

The first experiment involved redefining the Shell function, with the hope that the newly defined function would override the built-in one. We can achieve this by placing the code in the global template which is named normal.dotm or within an add-in (which is effectively a template that is loaded every time Word is opened), either way, our code will become part of the malicious macros execution.

Below we can see the redefined function used as part of this experiment. This was saved within normal.dotm (the global template), with the intention that when Shell was called, rather than calling the system function to launch the process, our redefined function would be called, resulting in a popup warning the user that the activity had been blocked.

 

ss_normal_dot_macro

 

Then, using the one line test macro that attempts to execute ‘cmd.exe /c calc.exe’, we can see that the redefined function worked well and blocked the execution of the process. Unfortunately, it only seemed to work when the malicious code was placed within the document and not when it was within a seperate module. The reason for this is unknown and warrants further research, as if solved, this would be the easiest way to achieve our goal.

 

SS1

 

Option 2 – Patching associated API in VBE7.dll to alter behaviour

For a more surgical approach we can look at API hooking the dll which is leveraged when macro code is executed. Looking through the dlls, which are loaded into Word at runtime, we can observe that VBE7.dll includes a large number of exports that appear related to the execution of macro code. Below we can see a snapshot from the list of exports with one in particular highlighted, rtcShell, that warranted further investigation.

 

ss_vbe_exports

 

Digging into this function we can see that it’s nothing more than a small wrapper around the CreateProcess Windows API call. The particular code block which executes the process is listed below. Looking at the parameters being passed to the API, we can see that the EBX register is being used to hold a pointer to the name of the process to be executed.

 

ss_ida_prepatch

 

At this point, if we want to alter the way the process is launched we can patch the instructions to alter the process creation flags, which is one of the parameters passed to the CreateProcess API. Alternatively, we could completely patch out the API call to prevent the execution from occurring.

In this case we are going to leverage the CREATE_SUSPENDED process creation flag to allow the process to launch, but immediately be frozen into a suspended state, preventing the code from running.

 

ss_msdn_createsuspended

 

The patch sets the ECX register to 4, which is the numeric value of CREATE_SUSPENDED, and then this is pushed as the creation flags parameter to the CreateProcess API call, resulting in the process being instructed to launch in a suspended state.

 

ss_ida_postpatch

 

Following this patch, a test macro that was designed to launch powershell was executed, and as we can see from the process explorer window, it was placed into a suspended state, thus mitigating any impact and allowing an opportunity for endpoint protection sensors to scan and identify any threatening behaviour.

 

ss_taskmanager

 

These are just proof of concepts, and would require more research and work before they were used in a production environment. I still believe that the ideal state would be for Microsoft to implement more granular security controls against macros, allowing organisations to continue using them, but at the same time empowering them with the ability to limit their capabilities depending on individual risk appetites.

 

Any comments or feedback would be very welcome!

 

-Adam (Twitter: @CyberKramer)



*** This is a Security Bloggers Network syndicated blog from SANS Digital Forensics and Incident Response Blog authored by Adam Kramer. Read the original post at: http://feedproxy.google.com/~r/SANSForensics/~3/V16Lv5PNWFs/inhibiting-malicious-macros-by-blocking-risky-api-calls