Cb Connect 2018 | Power of You | Register Now


Threat Analysis: Malicious Microsoft Word Documents Being Used in Targeted Attack Campaigns

December 19, 2017 / Jared Myers

A Microsoft Word document (.doc) believed to be malicious was recently submitted to Carbon Black’s Threat Analysis Unit (TAU). The submitting organization did not feel that that document (and subsequent payload) was fully executing in their analysis environment, and questioned whether or not it was actually malicious.

The submitted file was part of a targeted attack against an organization, and would not properly run unless the infected system configured for a domain that matched a hard coded pattern. The malicious carrier file contained embedded macros which would launch a series of VB scripts. Ultimately the scripts would inject a Cobalt Strike payload into a running process. While researching this variant TAU discovered numerous other variants (both .doc and .docx formats), which were written in the same manner. Only one instance contained the portion of code to ensure the script would only run at a targeted domain. All of these variants had very low coverage when run through an analysis engine, and as this technique emerges it will continue to be used in targeted attacks and eventually commoditized.

For those reasons TAU is releasing this post to inform customers, practitioners, and other researchers of this technique and that it has been observed in targeted attacks.

The Carbon Black product specific rules and policies (as well as a set of associated Yara signatures) are detailed in the Community User Exchange.

Technical Analysis

Delivery Phase

(NOTE: The metadata for the carrier file is not listed in this report, because it could be used to identify a potentially targeted organization.)  

Upon initial analysis it was observed that this Word Document contained a compressed Visual Basic (VB) Script, contained within a macro in the document.  The Macro was extracted (using oledump) and inflated, which resulted in an approximately 1800 line VBScript.  The script contains a secondary payload which is base64 encoded and built by concatenating string variables.  The Script also obfuscates strings (mostly in reverse order) that could be considered suspicious if in plain text.

First Stage

The script will initially gather the domain information with a call to Environ(UserDNSDomain).  The script will use the return value for a later check and if the return value is empty (if the system is not on a domain), the script will exit.  It will then check to determine if the target system is on a domain that contains a hard coded string.  The string is not specifically referenced in this post, because it contains a portion of a targeted organizations domain.  As an example if the hard coded string had been  ack.co, the script would be looking for a domain like [somecharacters]ack.co[m], where a domain like carbonblack.com would satisfy this check. In the script if the hard coded string is present in the returned domain name it will call the function enterProcess().

 If not present the VBScript will exit, this technique highlighted in green in the image below.  This check is done to ensure that script and the final payload will only be executed on a system which is configured for the targeted organizations domain.  This would result in the script (and the final payload) not fully executing on automated sandboxes or analysis systems if not configured to be on a specific domain.   

Figure 1: Targeted Domain Check

Once the enterProcess() function is called the script will use WScript to locate the registry setting for the current version of Word and change the registry value to allow VBScripts to be run.  This process is highlighted in the red box in the Figure below.

Once that registry modification is complete the VBScript will build a large Base64 encoded string in the variable strString, which is highlighted in green in the below image.

Figure 2: Registry modifications

The strString variable string is then added back to the document itself as a VBComponent, which is visible at line 1842 in the image above.  The script will create a series of COM objects which are used to later add the decoded and converted (to unicode) string back into the document.  It should be noted that the CLSID values that are being called at lines 1840 and 1843 are Microsoft Word and MSXML CLSIDs, respectively.  The strString variable is Base64 decoded in lines 1845-1847 and converted to unicode in line 1849.  This converted string is then written back into the Document as the object set as vntQuantity in line 1840.

The image below (highlighted in green) depicts where the vntQuantity object is run or executed by this script.  This will result in the base64 decoded string (which is another VB Script) to execute in the same process context.

Figure 3: Decoded script execution

Second Stage

The secondary VBScript will build a large Base64 encoded string in the variable mobjectAverage, which is highlighted in green in the below image.  

Figure 4: Payload Concatenation

The mobjectAverage string is first Base64 decoded in the exitName() function (which is displayed in the image below), and then converted to unicode.  This is highlighted in red in the image above.  Also highlighted in red the script is setting the gdtmAverage variable with the location of rundll32.exe for the appropriate operating system architecture.

Figure 5: Payload Decoding

This script declares several private functions (expandfile, makeChecksum, setEnvironment, setDrive, and testFound).  The only difference in the conditional statement (depicted in the image below) is the use of the keyword PtrSafe when declaring functions under VBA7.  This asserts that the statement is safe to run in a 64-bit environment.

Figure 6: Payload Injection

The above set of functions is a variation of a classic VB technique to inject a Dll into a process.  The following table will describe the purpose of the different functions, and list the order in which the functions are used.  

Function Name



This function will create a new Process (and primary thread), in this instance it will create the process rundll32.exe.


This function is used to allocate virtual memory as read/write in the newly created rundll32.exe process’ memory space.


This function will write the previously decoded data into allocated memory (of rundll32.exe) from the previous step.


This function is used to set the NewProtect value of the previously allocated virtual memory to execute/read.


This function will be used to create a thread that will run in the context of the rundll32.exe process.  In this instance the start address of the thread is pointing to the address of the previously allocated and written memory containing decoded data.

Table 1: Process Injection Overview

The above set of instructions will ultimately create a rundll32.exe process.  Memory is then allocated in the process’ memory space and the decoded data (which is a Dll file) is then written to that space.  The memory region is then changed from read/write to read/execute, allowing the script to create a new thread under the context of the process (which is the Dll payload).  The table below shows the metadata for the embedded payload.

Third Stage

File MetaData

File Name       : Cobalt_Strike.dll

File Size       : 206,848

CRC32           : 6d3e6da8

MD5             : f2f52c78d594c37b546f6c09207cb481

SHA1            : 12bc1affe86327d9f78684cde46cfff4dee57149

SHA256          : fa405c36d82b264568219b521886d2e7ef589674874983c7db1d67928003489e

Table 2: Cobalt Strike Payload Metadata

The third stage Dll which is injected into rundll32.exe is a Cobalt Strike payload.  This payload will initially check to see if the fdwReason for loading the Dll is 1, 4 or 6 (depicted in the image below).  It should be noted that arguments 4 and 6 are not documented reason codes.   

Figure 7: Payload initial check

A fdwReason code of 4 correlates to a Dll that is loaded by a Microsoft Application Verification tool, after a process is created.  If the fdwReason is listed as 1, which is typical when a dll is loaded via the LoadLibary() function, it will then unload the Dll.  It should be noted that LoadLibary is the typical manner that a Dll is loaded, such as when rundll32.exe is used to execute a Dll versus where a Dll is injected into another memory’s process space (which is the case here, it is a little confusing at the process they decided to inject into is rundll32.exe, however it could have been any process).

If this condition is met a sub function will be called to decode the Cobalt Strike payload configuration information.  This data is obfuscated with a simple XOR key of 0x69 (which is displayed in red in the image below).  

Figure 8: Configuration decoding

The decoded data contains the C2 callbacks as well as other information that is used by the payload to communicate with the C2 as well as other information related to how the binary will interact with the operating system.  In the image below the primary C2 (carbon-copy-marketing[dot]com)  is underlined in red, the User-Agent is highlighted in green and the primary and secondary page to be requested are underlined in blue.

Figure 9: Configuration Overview

At the time of this report the C2 resolves to, which is currently registered to Vooservers in Germany.

Carbon Black TAU analyzed the Cobalt Strike payload, which revealed that the binary is a feature rich tool, that can be used as an efficient remote administration tool (RAT).  

Related Variants

While researching this carrier file and embedded payload, TAU was able to identify several other variants, where either the VBScript structure was almost identical or the payload (Cobalt Strike) C2 infrastructure overlapped.  The below image highlights how the different samples (which are listed under the IOC section) are related.    

Figure 10: Variant Visualization




Command and Control URLs







Variants Hashes

Hash Values

































TAGS: Carbon Black Threat Research / malware / Threat Analysis Unit