RTF template injection sample targeting Malaysia

This post was authored by Fareed.

This blog post is intended to give a better overall picture of a malicious document attack that believes to be targeted at Malaysians. This blog post might useful for security engineers, researchers, and security analysts to catch up with current cybersecurity issues specifically malware threats and APT hunting. By the end of this blog post, readers will understand the inner working of this recent malware attack that happened to the compromised user via a malicious RTF document. Furthermore, security analysts can collect the given IOCs extracted from the malware to check whether your environment has been compromised or not.


On 30 March 2022, the Netbytesec team come across a tweet from Shadow Chaser Group (@ShadowChasing1) which is well known as one of the groups focused on APT hunt and analysis. The researcher from the Shadow Chaser Group claimed that they found an interesting RTF sample which Netbytesec team believes the samples are linked to Malaysia as the name and content of the RTF samples containing Cyber Security Malaysia's acronym name, CyberGuru logo, and Malaysia Ministry of Communications and Multimedia's emblem.

Figure 1: Shadow Chaser Group's tweet about the RTF sample

Netbytesec team collected all the IOCs from Twitter's thread of the tweet and retrieve the samples from VirusTotal for our further analysis.

Indicator of Compromises

MD5 Hashes

  1. Training Schedule Year 2022.doc - bc3102871cff7431440dbee8d7f1ae55
  2. CSM-ACE_Delegates_Kit.doc - 99f02db0641f2bb5680fdd08e59dd2e0 
  3. CSM 2022.doc - aac4b8e7e637c5b73e0801bc113ec0aa 
  4. CSM-ACE Delegates Kit.doc - 44f989a9dd3958611189eaca5b32444d
  5. Salwa.dotm - d50e5febbbb53fb439df73b976db790c
  6. Training - 3890c7037e01edf40ce6700491a49dd3
  7. GoogleServices.dll - 4ce106b72de51c55781d6d55e758a636
  8. GoogleDesktop.exe - 9f5f2f0fb0a7f5aa9f16b9a7b6dad89f

RTF template injection URLs

  1. hxxps://mckeaguee[.]com/salwa[.]dotm
  2. hxxps://mckeaguee[.]com/suhaimi[.]dotm
  3. hxxps://mckeaguee[.]com/rushidan[.]dotm
  4. hxxps://mckeaguee[.]com/hamizan[.]dotm

Domain name and IP addresses

  1. mckeaguee[.]com - (RTF communication)
  2. mclartyc[.]com - (DLL communication)

RTF document contents

Figure 2: bc3102871cff7431440dbee8d7f1ae55

Figure 3: aac4b8e7e637c5b73e0801bc113ec0aa

Figure 4: 99f02db0641f2bb5680fdd08e59dd2e0 and 44f989a9dd3958611189eaca5b32444d

Executive Summary

Netbytesec team started the investigation by analyzing the RTF specimens. All collected RTF samples used remote template injection techniques to abuse the template function of RTF to load malicious template documents containing malicious VBA code from a remote server. The malicious macro in the template then will load another Word document from the server that contains two PE files object which will be used by the macro to drop malicious EXE and DLL which does the C2 connection capability to the attacker server resulting in the compromise of a victim machine. The infected machine will consistently load the executable during startup as the malware will create a persistent mechanism via registry once the executable is executed for the first time. This behavior will ensure the connection to the C2 server whenever the victim starts their machine from a shutdown state.

Figure: Flow of Malware

Technical Analysis

In this technical analysis, the Netbytesec team was able to retrieve those samples that were being uploaded to VirusTotal and Any.Run. Netbytesec team then conduct RTF analysis, malicious macro analysis and reverse engineering on the samples.

RTF analysis

The Netbytesec team started the analysis by opening the RTF to observe the behavior of the RTF sample. Upon opening one of the RTF samples, Microsoft Word will try to fetch a template as the Word's ribbon shows that the software tries to open a remote template from a URL "https://mckeaguee[.]com". The figure below shows the document trying to retrieve a remote template from the internet.

Figure 5: Word try to load template injection

Observing this behavior, the Netbytesec team assumes that the malware author uses RTF template injection as we have researched this technique last year which can be referred here for an explanation of this new emerging technique. 

Below the figure, our analyst grep keyword "template" from all the RTF samples to display the template injection URLs.

Figure 6: Using grep command to find template injection location

Hence, we confirmed that this RTF implements the RTF template injection technique on the samples.

Malicious macro and malicious Inline shape

After the RTF load the remote template, the document will automatically execute the malicious macro code embedded inside which led to the execution of an executable named "GoogleDesktop.exe". In the figure below, we put comments to explain what the line of codes does.

Figure 7: Malicious macro code

First, the code will determine the temp file path into variable ckal that will be used to save an EXE file and a DLL file. In line 13, we can see that the macro will retrieve a document from URL https://mckeaguee.com/training and replace the document with the currently opened document. 

After doing that, at line 21, the embedded macro gets the EXE file (inline shape) contained in the newly replaced document and checks whether the AlternativeText contains strings ".ex" to identify the existence of the file. It then copies the file into the temp folder with the filename that the malware author put in AltBox of the inline shape. The same goes for line 28 for the DLL copy activity.

At the last line of the malicious code, the macro will execute the EXE file which led to the DLL loading of the GoogleServices.DLL which does the malicious behavior.

In the figure below, we can see that the malware author put the Inline shape object above the emblem.

Figure 8: Inline Shape object

Inside the GoogleDesktop.exe

Inspecting the import functions of the executable reveals that the application will call GoogleServices_1 function from GoogleServices.dll.

Figure 9: Imports functions

If we look down at the address 0x4010D9, the malware invokes the malicious function GoogleServices_1 to start the infection.

Figure 10: GoogleDesktop.exe invokes the malicious function

In the next few sections, we will focus on DLL functionality where most of the malicious behavior is done by the DLL.

Malicious DLL export functions

Netbytesec team first determines the DLL's export to dig down the interesting and malicious functions that reside in the PE file.

Figure 11: The DLL containing an export

In the GoogleServices_1 export, it contains two sub-function which are malicious_function which was renamed by our analyst, and the ExitProcess function. Note that our analyst has rebased the program in the IDA Pro to follow their x32dbg offset. The address might differ from yours.

Figure 12: GoogleServices_1 function

In the "malicious_function" function (0x74881CB0), the function basically will create a registry key, decode the WinAPI function name in runtime and then connect to their command and control server.

Resolve Windows API function names

The malware author uses a function routine that our analyst renamed "wrap_function_resolve_runtime" to resolve a lot of Windows API functions name during runtime. For example, the figure below shows the function "wrap_function_resolve_runtime" (0x736F1BD4) was used to resolve the "LoadLibraryA" name before the malware called LoadLibraryA (0x736F1BF0) function to load wininet.dll during the runtime.

Figure 13: Resolving WinAPI function names

If we track down the reference call of this "wrap_function_resolve_runtime" function, the malware makes a lot of calls for this function to resolve several Windows API function name.

Figure 14: Cross references of function "wrap_function_resolve_runtime"

Digging down to see the inner code of the function will give us hints that the malware author uses PEB structure to get all the loaded module lists, their base address, and exported function addresses.

Figure 15: Decompiled version of "wrap_function_resolve_runtime" function

In this method, malware can simply get all the loaded module lists, their base address, and exported function addresses by using PEB information. The malware will be able to parse PEB information to read the image base of required modules, calculate the export addresses and make the call to the address instead of calling GetProcAddress and LoadLibrary to get the address of a Windows API. As a result, malware can remain stealthier at some level because suspicious functions like GetProcAddress are not being called.

Create registry as persistent mechanism

In the "malicious_function" (0x74881CB0) function, the malware first will call a sub-function that will do a creation of registry key for the persistent mechanism as you can see at address 0x74881BFB in the figure below.

Figure 16: Function create_registry being call

Drilling down the function, the malware first will open the corresponding Registry key which is "Software\Microsoft\Windows\CurrentVersion\Run" using RegOpenKeyExA by calling the EAX value at address 0x748813A1 shown in figure below.

Figure 17: Registry key being open using RegOpenKeyExA

Then the malware will get the current module file name which is GoogleDesktop.exe to be use to set the value in the next function call.

Figure 18: GetModuleFileName being use to retrieve GoogleDesktop.exe path

After, retrieve the GoogleDesktop.exe path, the malware will generate a string "Google Notification" that intend to be used as the Registry name in the mentioned Registry.

Figure 19: The sample generate a string to be use as Registry name

Finally, using the RegSetValueExW function, the malware will set the value of the CurrentVersion\Run registry to perform the persistent mechanism in the victim's machine.

Figure 15: The malware will set the value according to its parameter of RegSetValueExW

If we check the victim's CurrentVersion\Run registry, supposedly we can find the registry name "Google notification" like in the figure below.

Figure 20: Creation of Google Notification registry key

Decrypt domain name and user-agent strings

Before creating and setting up a Command and control connection, the malware first will take a chunk of encrypted data stored in the executable and decrypt it with XOR key 0x9D to generate the C2 domain name and user-agent string.

Figure 21: Buffer containing encrypted data

If we observe the memory dump of the destination of decrypted data, we can see the clear text of the decrypted domain name and user-agent string that will be used for the C2 connection in the next phase.

Figure 22: Decrypted data

Generate URL path

The malware also will generate random strings to be used as the URL path when making a connection with the attacker's C2 server. The figure below shows the function that will return and save the random string that is to be appended to the URL as the URL path.

Figure 23: Function routine use to create random string for URL path

The loop will generate arbitrary characters as the random string.

Command and Control connection

Upon decrypting the domain name and generating random characters for the URL path, the malware will then invoke a function that will be used to create the C2 connection at the end of the function "malicious_function". 

Figure 24: C2 Connection function being call

As we see in the first activity of the "malicious_function" function, the function previously used LoadLibraryA to load the WinInet library. The lifecycle for the WinInet to be used as a C2 connection is pretty simple.

As shown in the figure below, it will start to initialize the library by calling InternetOpenA with the decrypted user agent string "Mozilla/5.0" user-agent as lpszAgent parameter.

Figure 25: InternetOpenA being call

Using the decrypted domain name as parameter lpszServerName of InternetConnectA, the malware initiates the connection by opening an HTTP session for the given site where the ESI value contains InternetOpenA handle.

Figure 26: InternetConnectA

After that, the sample builds an HTTP request handle with the HttpOpenRequestA function along with HttpSendRequestA to send the HTTP Request shown in figure 27 and figure 28.

Figure 27: HttpOpenRequestA 

Figure 28: HttpSendRequestA

Lastly, the sample will pass the handle to InternetReadFile to read the actual data which probably means that the specimen is reading the response of the GET request to the URL domain mclartyc[.]com.

In our case here, the domain mclartyc[.]com has been resolved to the loopback address by the attacker. Hence, deep analysis on behavior of the C2 interaction with compromised machine cannot be done.

Figure 29: Attacker's DNS resolved to

Based on VirusTotal, the resolved IP address of the domain would be

Figure 30: mclartyc[.]com IP Address

By the end of the malicious function, the program will call the sleep function before it loops to the previous generate URL path strings function and create a C2 connection back.

Figure 31: Call sleep function

Malicious DLL summary

The DLL's main activities are as follows:
  1. Resolve a lot of function names during runtime
  2. Create registry name "Google notification" with the value of GoogleDesktop's path
  3. Decrypt C2 domain and user-agent strings
  4. Generate random URL path strings
  5. Create connection to C2 server (Domain already resolved to
  6. Sleep
  7. Repeat step 4

Overall behavior scenario

  1. Victim open RTF document
  2. RTF load remote template from hxxps://mckeaguee[.]com/
  3. Microsoft Word .doc (template) file contains malicious macro loaded
  4. Macro executed
  5. Retrieve another doc file contains malicious inline shape (EXE and DLL)
  6. EXE and DLL dropped
  7. EXE execute and DLL will be load


Netbytesec team believes the samples are linked to Malaysia as the name and content of the RTF samples containing Cyber Security Malaysia's acronym name, CyberGuru logo, and Malaysia Ministry of Communications and Multimedia's emblem. The sample also can be speculated that the malware was crafted by our own local Malaysian threat actor or might be from an outsider or it might come from red team operator out there. The attacker takes advantage of the RTF template ability to leverage RTF remote template injection to load malicious templates in the runtime. Even though the potentially dropped DLL has a unique way to resolve a lot of Windows API functions names during the runtime, the malicious software have simple malicious behavior and characteristics towards its victim which creates a persistent mechanism registry and connects to the C2 server.