The "Finding Malware," blog series is authored to empower the Google Security Operations community to detect emerging and persistent malware threats. This post dives deep into the NUMOZYLOD malware family and the detection opportunities available within the Google Security Operations (SecOps) platform. You can read the other installments to the series here. Happy hunting!
Also known as: FakeBat, EugenLoader, PaykLoader
Since mid-2023, Mandiant Managed Defense has responded to a surge in malware infections originating from malvertising campaigns. These attacks are opportunistic in nature, targeting users seeking popular business software. The infection utilizes a trojanized MSIX installer, which executes a PowerShell script to download a secondary payload.
Mandiant tracks this PowerShell script as NUMOZYLOD and attributes its distribution to UNC4536, a threat actor operating under the moniker "eugenfest." The actor is part of a Malware-as-a-Service (MaaS) operation, distributing malware such as ICEDID, REDLINESTEALER, CARBANAK, LUMMASTEALER, or ARECHCLIENT2.
Our research into NUMOZYLOD reveals an interesting glimpse into the growing and thriving underground economy, where threat actors actively seek out partners to fulfill the supply and demand for specialized tools and services for their objectives. It also highlights how threat actors are exploiting MSIX to covertly bundle and distribute malware alongside legitimate software.
Figure 1: NUMOZYLOD Attack Lifecycle
UNC4536's modus operandi involves leveraging malvertising to distribute trojanized MSIX installers disguised as popular software like Brave, KeePass, Notion, Steam, and Zoom. These trojanized MSIX installers are hosted on websites designed to mimic legitimate software hosting sites, luring users into downloading them.
A key feature of MSIX is its ability to execute scripts with the help of the Package Support Framework (PSF). Installers can instruct the PSF to run a script before the main application starts by adding a configuration item called startScript. Similarly, to run a script after the application finishes, add a configuration item called endScript.
Threat actors have exploited this feature bundling a malicious payload, such as NUMOZYLOD, within the MSIX package, which will be executed during the software installation process.
Analyzing the structure of the NUMOZYLOD trojanized MSIX files structure provides interesting insights into how threat attackers stage their resources and abuse MSIX features to gain initial access and evade detection.
Figure 2: MSIX File Structure embedded with a malicious PowerShell script, NUMOZYLOD.
Here's a breakdown of its key MSIX components.
1. AppxManifest.xml
This xml file is the heart of the MSIX installer. It specifies how the package is to be installed. Interesting information includes, but is not limited to:
Figure 3: Package language resource
Figure 4: Package capabilities
Figure 5: Package EntryPoint, Executable and ID
Figure 6: Package build
2. Config.json
config.json is a configuration file used by the PSF to handle things that standard MSIX installations cannot directly support, such as launching specific processes alongside the main application. In essence, the config.json file instructs the MSIX installer to trigger the execution of the malicious PowerShell script during the installation of the software.
Figure 7: The config.json shows the trojanized MSIX is designed to execute a PowerShell script named "Refresh2.ps1" (NUMOZYLOD)
and launch "Trello"
3. StartingScriptWrapper.ps1
The StartingScriptWrapper.ps1 file is an essential component of the PSF that serves as a wrapper for executing PowerShell scripts specified in the config.json file.
Figure 8: The wrapper was observed to execute the malicious PowerShell script "Refresh2.ps1" (NUMOZYLOD) specified in the config.json
4. Virtual File System (VFS) folder
The VFS folder is a virtual storage space within an MSIX package. It holds the application's files and folders, separating them from the main system. This isolation protects both the application and the system.
Mandiant observed that in some variants, files within the VFS folder (such as gpg.exe and iconv.dll) were written to locations like AppData\Local. These files may be intended for a later stage of a multi-stage malware attack, as we observed the use of gpg.exe to decrypt the downloaded encrypted payload.
Once the trojanized installer package is prepared, the threat actor will distribute it through malvertising, waiting for a victim to download and execute it.
Figure 9: Trello users are being targeted by malvertising attacks that redirect them to a fake website at trello.confesapp[.]com.
This installation action will initiate the download of a secondary payload and any additional packages hidden within the MSIX installer. The below illustration demonstrates the triggering of the PowerShell payload during the execution of the malicious installer.
Figure 10: A PowerShell payload (NUMOZYLOD) was executed discreetly in the background during the installation of the legitimate software.
UNC4536 operates as a malware distributor, leveraging NUMOZYLOD as one of its vehicles to deliver tailored payloads for their “business partners.” Managed Defense has observed a range of secondary payloads, to be executed through various techniques.
In the following section we will review two NUMOZYLOD variants and their previous delivery of the CARBANAK and LUMMASTEALER payloads.
Variant 1: NUMOZYLOD distributing CARBANAK
In 2023, Managed Defense observed a campaign utilizing UNC4536's distribution network to spread the CARBANAK backdoor. This campaign exploited SEO poisoning tactics, directing unsuspecting victims to a malicious website that mimicked the legitimate KeePass open-source password manager. The observed trojanized installers contained a NUMOZYLOD downloader that was configured to retrieve CARBANAK backdoor.
The following code snippet is from the NUMOZYLOD malware variant. Upon infecting a system, this variant will transmit host information and then download and execute the CARBANAK malware via DLL Search Order Hijacking.
Figure 11: A code snippet of this NUMOZYLOD variant that leads to CARBANAK .
Execution of this NUMOZYLOD variant would perform the following:
Variant 2: NUMOZYLOD distributing LUMMASTEALER
Figure 12: An obfuscation NUMOZYLOD variant
In another campaign, Managed Defense observed a heavily obfuscated NUMOZYLOD sample utilized to deliver the LUMMASTEALER payload. Its use of numerous curly brackets makes analysis difficult. However, here are two effective methods to dynamically analyze the content of this obfuscated PowerShell script.
1. Analyzing Obfuscated PowerShell Script - PowerShell Script Block Logging
Turn on PowerShell Script Block Logging - Once Script Block Logging is enabled, PowerShell will log details about PowerShell operations, and the executed PowerShell commands. Using the Windows Event Viewer, a user can filter for eventID 4104 and review the deobfuscated PowerShell script.
The following screenshots illustrate how the NUMOZYLOD variant utilizes several obfuscation techniques to impede analysis and evade security measures.
Figure 13: Multiple layers of obfuscation to hinder analysis and evade detection
2. Analyzing Obfuscated PowerShell Script - Reviewing AMSI events
Generating and analyzing Antimalware Scan Interface (AMSI) events - Alternatively, you can conduct dynamic analysis with the help from AMSI events. This method not only enables users to review the deobfuscated PowerShell script, but also reveals whether AMSI successfully blocked the malicious content.
The following screenshots show the same NUMOZYLOD variant after deobfuscation using the AMSI event generation and analysis method.
Figure 14: Analyzing AMSI events
Essentially, this obfuscated NUMOZYLOD variant downloads and executes a secondary PowerShell payload from a C2 server. The following screenshot illustrates this second-stage payload.
Figure 15: Multiple layers of obfuscation to hinder analysis and evade detection
Execution of this NUMOZYLOD variant would perform the following:
In this NUMOZYLOD variant, the downloaded payload is identified as LUMMASTEALER, a known infostealer malware.
NUMOZYLOD gathers system information, including operating system details, domain joined, and antivirus products installed. In some variants, it gathers the public IPv4 and IPv6 address of the host and sends this information to its C2.
In some variants, NUMOZYLOD creates a shortcut(.lnk) in the StartUp folder as its persistence.
As a part of a Malware-as-a-Service (MaaS) operation, NUMOZYLOD completes its mission upon the successful deployment of the second-stage malware from its C2 server and hands it over to its buyer for the subsequent mission.
Mandiant Hunt surfaces otherwise undetected malicious activity by employing a detection strategy that uses both strong signals - high enough fidelity to be reviewed 1:1, and weak signals - low fidelity on their own, but provide broad coverage of threat actor tactics. These signals or combinations thereof are used to sequentially funnel the gargantuan amount of customer telemetry data to a number of cases worthy of analyst review. Mandiant uses security frameworks like MITRE ATT&CK® to help label data, (discussed further below) find interesting sequences of activity, and share actionable results with customers
The NUMOZYLOD attack chain presents several opportunities for engineering strong detections. Examples of detections used by Mandiant Hunt within Google Security Operations include:
metadata.event_type = "FILE_CREATION" OR metadata.event_type = "FILE_MODIFICATION" AND target.file.full_path = /\.msix$/ nocase
metadata.event_type = "FILE_CREATION" OR metadata.event_type = "FILE_MODIFICATION" AND target.file.full_path = /startingscriptwrapper\.ps1$/ nocase
(target.file.full_path = /gpg\.exe$/ nocase AND (principal.process.file.full_path = /copy\.exe$/ nocase OR principal.process.file.full_path = /xcopy\.exe$/ nocase)) AND target.file.full_path != /cygwin/ nocase AND target.file.full_path != /git\\usr\\bin/ nocase
Mandiant threat hunters use various signals captured in Google Security Operations to identify later stages of compromise all the way through threat actor mission completion, if attackers progress to that point.
Enterprise and Enterprise Plus customers will benefit from these detections being applied automatically through curated detections. Standard customers can use the YARA-L rules below to create single or multi-event rules to detect the malware. You can even ask Gemini in Google Security Operations to do it for you.
rule POWERSHELL_EXECUTE_SCRIPTWRAPPER_FROM_WINDOWSAPPS_VIA_REMOTESIGNED_EXECUTION_POLICY {
meta:
author = "Mandiant"
description = "This rule detects when startingscriptwrapper.ps1 is executed with Advanced Installer. The process is executed with MSIX files as package support framework and may point to an additional malicious powershell script within the ps1."
mitre_attack_tactic = "Execution"
mitre_attack_technique = "Command and Scripting Interpreter"
mitre_attack_url = "https://attack.mitre.org/techniques/T1059/001/"
mitre_attack_version = "v14.1"
severity = "High"
priority = "High"
platform = "Windows"
type = "hunt"
events:
(
$e.metadata.event_type = "PROCESS_LAUNCH"
) and
(
re.regex($e.target.process.command_line, `StartingScriptWrapper.ps1`) nocase and
re.regex($e.target.process.file.full_path, `powershell`) nocase and
re.regex($e.target.process.command_line, `RemoteSigned\s\-file.*\\WindowsApps\\.*Powershell(.exe).*RemoteSigned\s\-file.*\.ps1`) nocase
) and
(
re.regex($e.principal.process.file.full_path, `\\ai_stubs\\`) nocase or
re.regex($e.principal.process.command_line, `\\ai_stubs\\`) nocase
)
condition:
$e
}
rule XCOPY_WRITING_GNUPG_PROCESS_METHODOLOGY {
meta:
author = "Mandiant"
description = "This rule is designed to detect on gpg.exe (GnuPG) being copied to the path %localappdata%. This technique has been previously observed in NUMOZYLOD compromises."
mitre_attack_tactic = "Command And Control"
mitre_attack_technique = "Ingress Tool Transfer"
mitre_attack_url = "https://attack.mitre.org/techniques/T1105/"
severity = "Low"
platform = "Windows"
type = "hunt"
events:
(
$e.metadata.event_type = "FILE_CREATION" or
$e.metadata.event_type = "FILE_MODIFICATION"
) and
(
re.regex($e.target.file.full_path, `gpg\.exe$`) nocase and
re.regex($e.target.file.full_path, `\\appdata\\local`) nocase and
not re.regex($e.target.file.full_path, `\\localsum\\cygwin\\bin`) nocase and
not re.regex($e.target.file.full_path, `temp\\rest\\bin`) nocase and
not re.regex($e.target.file.full_path, `Git\\usr\\bin`) nocase and
(
re.regex($e.principal.process.file.full_path, `xcopy\.exe$`) nocase or
re.regex($e.principal.process.file.full_path, `copy\.exe$`) nocase
)
)
condition:
$e
}
Have questions or feedback for the Managed Defense team? Comment on the blog or ask a question in the Managed Defense Forum.