GReAT research

GhostContainer backdoor: malware compromising Exchange servers of high-value organizations in Asia

In a recent incident response (IR) case, we discovered highly customized malware targeting Exchange infrastructure within government environments. Analysis of detection logs and clues within the sample suggests that the Exchange server was likely compromised via a known N-day vulnerability. Our in-depth analysis of the malware revealed a sophisticated, multi-functional backdoor that can be dynamically extended with arbitrary functionality through the download of additional modules. Notably, the attackers leveraged several open-source projects to build this backdoor. Once loaded, the backdoor grants the attackers full control over the Exchange server, allowing them to execute a range of malicious activities. To evade detection by security products, the malware employs various evasion techniques and disguises itself as a common server component to blend in with normal operations. Furthermore, it can function as a proxy or tunnel, potentially exposing the internal network to external threats or facilitating the exfiltration of sensitive data from internal devices. Our telemetry data indicates that this malware may be part of an APT campaign targeting high-value organizations, including high-tech companies, in Asia. Our team is currently investigating the scope and extent of these attack activities to better understand the threat landscape.

GhostContainer: the backdoor

MD5 01d98380dfb9211251c75c87ddb3c79c
SHA1 2bb0a91c93034f671696da64a2cf6191a60a79c5
SHA256 87a3aefb5cdf714882eb02051916371fbf04af2eb7a5ddeae4b6b441b2168e36
Link time 1970-01-01 12:00 AM UTC
File type PE32 executable (EXE) (CLI) Intel 80386, for MS Windows Mono/.Net assemblys
File size 32.8 KB
File name App_Web_Container_1.dll

The name of this file is App_Web_Container_1.dll. As the file name suggests, it serves as a “container”. It contains three key classes (Stub, App_Web_843e75cf5b63, and App_Web_8c9b251fb5b3) and one utility class (StrUtils). Once the file is loaded by the Exchange service, the Stub class is executed first. It acts as a C2 command parser, capable of executing shellcode, downloading files, running commands, and loading additional .NET byte code. One of the most notable features is that it creates an instance of the App_Web_843e75cf5b63, which serves as a loader for the web proxy class (App_Web_8c9b251fb5b3) via a virtual page injector.

Stub: C2 parser and dispatcher

At the beginning of execution, The Stub class attempts to bypass AMSI (Antimalware Scan Interface) and Windows Event Log. This is accomplished by overwriting specific addresses in amsi.dll and ntdll.dll, which allows evading AMSI scanning and Windows event logging.

Next, it retrieves the machine key from the ASP.NET configuration, specifically the validation key, and converts it to a byte array. The code used to generate the validation key was simply copied from the open-source project machinekeyfinder-aspx. The validation key is then hashed using SHA-256 to ensure it is 32 bytes long, and the resulting byte array is returned for use in AES encryption and decryption (to protect the data transferred between the attacker and the Exchange server).

The malware’s primary functionality is to receive requests from the attacker and parse them as follows:

  • Receive the value of x-owa-urlpostdata from the attacker’s request data and then decode it as Base64.
  • Utilize the AES key generated above to perform AES decryption on decoded data. The first 16 bytes of the decoded data are used as the initialization vector (IV).
  • Decompress the decrypted data and dispatch operations based on the command ID (first byte).

To execute commands, Stub checks if the current user is a system account. If it is not, it attempts to impersonate a user by utilizing a token stored in the application domain’s data storage. This allows the application to perform actions under a different identity.

C2 commands and functionality:

Command ID Description
0 Get the architecture type (e.g., x86 or x64) |
1 Run received data as a shell code
2 Execute a command line
3 Load .NET byte code in a child thread
4 Send a GET request
5 Download and save a file
6 Save provided raw data to a file
7 Delete a file
8 Read file contents
9 Execute a .NET program with output
10 Invoke a virtual page injector (create an instance of class App_Web_843e75cf5b63)
11 Iterate and delete files whose names contain App_Global in the defined folder and its subdirectories
14 Perform HTTP POST requests to multiple URLs concurrently

Each time the command is executed, an XML-formatted response is generated, containing the execution result or return value. The value element in the XML starts with a hardcoded string /wEPDwUKLTcyODc4, and the same string is used in another open-source project, ExchangeCmdPy.py, to exploit the Exchange vulnerability CVE-2020-0688.

By further comparing the code of GhostContainer with the ExchangeCmdPy.py open-source project, we observe a high degree of similarity in their entry function structures and keyword strings. This leads us to speculate that the code of the Stub class was developed based on the open-source project. We suspect that the vulnerability exploited in the Exchange attack may be related to CVE-2020-0688.

App_Web_843e75cf5b63: virtual page injector

This class is based on yet another open-source project, PageLoad_ghostfile.aspx, and it is designed to create ghost pages using classes like VirtualProvider. It contains a few classes which inherit from multiple system classes responsible for creating virtual ASPX pages and override some of their methods. It will create a virtual page using the two provided arguments: fakePageName and fakePath. The purpose of this approach is to run a .NET reflection loader (the fake page – see Appendix II) and bypass file checks. The loader is hardcoded into the program as a Base64-encoded .aspx source code.

This fake page is used to locate the web proxy class App_Web_8c9b251fb5b3 in the current domain and execute its static method AppWebInit. As soon as it is created, the attacker starts sending requests to it, which will then be received and parsed by App_Web_8c9b251fb5b3.

App_Web_8c9b251fb5b3: web proxy

App_Web_8c9b251fb5b3 is one core component in the GhostContainer sample, typically loaded indirectly through the fake page (App_Web_843e75cf5b63). This class includes web proxy, socket forwarding, and covert communication capabilities, serving as a typical example of a combined web proxy and tunneling module.

When an instance of this class is created, the static value utcDate is initialized with the current date and time. To identify the current version of the class, the fake page selects and invokes the one with the maximum utcDate value.

There are only two functions in this class. The AppWebInit() function serves as the actual entry point of the module, and it is dynamically invoked through reflection in the fake .aspx page. In the function StrTr, it implements a custom string translation mechanism before decoding Base64-encoded strings.

Again, we linked this algorithm to an open-source project, this time Neo-reGeorg. The function name StrTr and its code are identical. By comparing the code, it becomes clear that this class is a highly customized version of Neo-reGeorg.

The primary behavior of the module is focused on parsing requests the attacker sends to the fake web page. When receiving a request, it first inspects the header. Its further behavior may vary depending on the identified header:

  • The Qprtfva header: identifies proxy forwarding requests.
  • The Dzvvlnwkccf header: identifies socket communication requests.
  • In other cases, the malware will respond with the string "<!-- 5lxBk9Zh7MDCyVAaxD8 -->".

If the header is Qprtfva, the malware establishes a web proxy by completing the following steps:

  • Decode a Base64-encoded string to obtain the target URL.
  • Clone the original request content (headers other than Qprtfva and body).
  • Forward the request to the decoded target address.
  • Return the target response content as the local response.

If the header is Dzvvlnwkccf, the malware establishes or manages a long-lived TCP tunnel connection between the internet and intranet. In order to identify and maintain different socket objects simultaneously, it defines a name for each socket object and then saves that name in pairs with the socket object in global storage. The name of the socket is contained in the first 22 bytes of the value of the header Dzvvlnwkccf. The exact activity is contained in the command section of the request, which starts from byte 23. The module accepts the following socket communication commands.

Command Description
1iGBIM1C5PmawX_1McmR7StamYn23jpfQoENPlm19cH42kceYkm8ch4x2 Extracts the IP and port from an encrypted header, attempts to connect, and saves the socket.
vfhafFQZ4moDAvJjEjplaeySyMA Closes the socket and removes it from the global storage.
M4LubGO0xaktF_YgZpsiH3v1cJ4dloAPOZKdG8AK4UxM Converts HTTP request body content to socket data and sends it to the internal host.
NYIJVBf2PXRn7_BWxFyuheu1O0TuE9B0FtF0O Receives data from the internal network, encodes it, and sends it back to the attacker as an HTTP response body.

StrUtils: string and XML format processing class

StrUtils looks like a utility class for splitting and trimming strings, as well as splitting, extracting, and unescaping XML elements. However, only a few functions are currently referenced by the other three classes, namely the functions responsible for:

  • Splitting the received data into multiple parts
  • Trimming the closing character of the file path

We found no references to the XML unescaping functions in any class.

Infrastructure

The GhostContainer backdoor does not establish a connection to any C2 infrastructure. Instead, the attacker connects to the compromised server from the outside, and their control commands are hidden within normal Exchange web requests. As a result, we have not yet identified any relevant IP addresses or domains.

Victims

So far, we have identified two targets of this campaign: a key government agency and a high-tech company. Both organizations are located in the Asian region.

Attribution

The sample used in this APT attack does not share structural similarities with any known malware. It incorporates code from several open-source projects, which are publicly accessible and could be utilized by hackers or APT groups worldwide. As a result, attribution based on code similarity is not reliable. Based on our telemetry, the attack could not be correlated with other attack campaigns because the attackers did not expose any infrastructure.

Conclusions

Based on all the analysis conducted, it is evident that attackers are highly skilled in exploiting Exchange systems and leveraging various open-source projects related to infiltrating IIS and Exchange systems. They possess an in-depth understanding of how Exchange web services operate and show remarkable expertise in assembling and extending publicly available code to create and enhance sophisticated espionage tools. We believe this is a mature and highly professional team. We continue tracking their activity.

Indicators of compromise

01d98380dfb9211251c75c87ddb3c79c       App_Web_Container_1.dll

GhostContainer backdoor: malware compromising Exchange servers of high-value organizations in Asia

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Reports
Subscribe to our weekly e-mails

The hottest research right in your inbox