Dynamic Office Template Injection for Sandbox Bypass
You’ve sent your phishing email with a malicious Microsoft Office document. You pored your blood, sweat, and tears into that sexy Macro of yours. However, modern appliances can easily run that macro in a sandbox and determine if it’s evil or benign.
Sure, you could use common techniques to enumerate if you’re in a sandbox or not but, that requires more code and for the love of god, we’ve all written too much VBA as is. Or, you could encrypt the document and supply the password within the email/title but, some sandboxes have caught on to that as well or maybe the user is too lazy. So, what are some other options, cleaner options?
There are some massive benefits to using template injection such as:
- Ability to send a Docx and not a Docm
- Macro does not “Live” within the Docx
- Can “Hot Swap” payloads
- Can remotely turn macros on and off
Template injection works via the following process (for the example moving forward, I will be using Microsoft Word):
- Build your malicious macro into a .Dotm (Microsoft Template containing a Macro).
- Host your .Dotm publicly via an S3 bucket, GCP Bucket, DO Space, etc.
- Create a .Docx document with a Microsoft Template.
- Unzip the .Docx and modify a single XML file
- Zip contents back up and change .zip to .Docx
Create the Dotm Document
Here is the Macro that we will add to the .dotm document:
Dim Execute As Variant
Execute = Shell("calc.exe", vbNormalFocus)
In the example case, the Macro simply opens up calc.exe, as all good malware does in its infancy. Once we have the Macro working, we make sure to save the Word Document as a .dotm.
Create the Docx Document
When creating the .docx document, you need to select a real Microsoft Template. I like to use a resume template as they usually do not contain images or extremely fancy formatting.
Now that we have both documents created [example.dotm, resume.docx], let’s host example.dotm on a Digital Ocean space.
Get the URI to example.dotm and move back to where we have the resume.docx. If you have 7-zip, winzip, etc., right click resume.docx and select
Extract Here. If successful, you will be presented with a few new folders and a single xml file as seen below.
Navigate to word –> _rels –> and open the settings.xml.rels in any text editor. We are going to replace the
Target variables data with our example.dotm URI.
Save settings.xml.rels and go back to the root directory of the original .docx. Select all the files/directories that were generated from the unzipping:
Add them all to a single .zip archive and then change the .zip suffix to a .docx suffix to complete the transformation.
The resulting resume.docx will now attempt to pull down the example.dotm template from our Digital Ocean Space each and every time it is opened. The fun part is, we can change the permissions on the example.dotm URI to be Public or Private.
Dynamic Macro Enabling/Disabling
What makes this interesting is the fact that we can change access to the example.dotm file hosted on Digital Ocean simply by making the URI Private or Public.
Resume.docx does not crash when it attempts to navigate to the non-existent example.dotm URI, it just doesn’t load a macro because there’s not one there. Simply put, it looks like any standard docx should.
When we change the example.dotm URI back to Public, and re-open resume.docx, we are presented with a macro enabled document since the URI is alive.
Disable Docx Macro:
By “disable” I simple mean change access to the URI where the .dotm document is located. If the .docx can’t find it, then there’s no macro.
Enable Docx Macro:
Setting the example.dotm to Public and re-opening resume.docx will give us a macro enabled docx that opens calc.exe when we click
At the top of this post I outlines four (4) of the positives when using this technique. The most objective one being bypassing Email filtering by sending a truly benign docx. Yes, you risk a user opening the document without detonating your macro if they’re really motivated to open everything in their email immediately. But hell, send the phish, wait 5-7min, and arm the link.
It’s also worth noting that an attacker can easily change payloads. For example, if for some reason your initial C2 has been burned but the infection point is undetermined, you can swap out the example.dotm with one of your backup C2’s.
There are a ton of use cases!