By Shelly Raban, Threat Hunting Expert at Team Axon
Executive Summary
Hunters’ Team Axon has been investigating an active campaign targeting Mexico-based users with newly identified multi-stage malware that performs a Man-in-The-Browser attack to redirect users to phishing sites, steal users’ banking information, capture screenshots of the active browsing tab and collect system information.
Attack Flow
The campaign targets Mexico-based users, utilizing evasive techniques and a multi-stage infection chain, relying on remotely hosted payloads. The first stage of the attack is codeless - a ZIP file containing a .url (Internet Shortcut) file - making it challenging to detect and block the activity.This attack flow shares similar characteristics with the recent report by Metabase Q and an older one by SCILabs, including a shared victim profile, techniques, and infrastructure such as IPs and domains. The domains and payloads also share similar naming conventions.
Interesting to note, we have found a strong connection between some of the malicious domains in the different scenarios, such as the JARM fingerprint (29d3dd00029d29d21c42d43d00041d44609a5a9a88e797f466e878a82e8365), certificate issuer (“Issuer: C=US CN=GTS CA 1P5 O=Google Trust Services LLC”), registrar (Namecheap) and redacted or obscured whois information, shared by facturamexico2023[.]com, srlxlpdfmxntetflx[.]com, facturacionmx[.]click and more.
The analyzed campaign occurs over multiple stages:
- Initial access through a ZIP file downloaded from a phishing website. The ZIP file consists of a single .url file.
- WebDAV payload retrieval using a .url file referencing a remote .jse file, masquerading as a PDF.
- .jse downloader module, responsible for fetching the next .hta module.
- .hta - downloader & UAC bypass module, employs multiple levels of obfuscation, leverages an auto-elevated COM interface for UAC bypass, and executes the final Powershell payload with administrative privileges.
- The final Powershell payload installs a malicious browser extension with various capabilities including info stealing, malicious redirections, man-in-the-browser, and c2 communication.
Initial Access: Phishing Website -> ZIP Archive
The attack starts via an initial access vector, which was investigated and documented by the previously mentioned Metabase Q team. Their blog describes a similar attack flow from the same actor (as explained above), which leverages phishing websites with a deceptive pop-up. Upon clicking, users get redirected to a compromised website hosting a malicious ZIP file. This tactic aligns with our team’s observations.
Internet Shortcut File Used for Payload Delivery
The .zip file contains a single file with a .url extension. This .url file is an Internet Shortcut File that points to a specific web address. When opened, it directs the system to access the URL within, which is commonly a web address starting with “https:”. However, URL files can also encompass other types of URLs like “mailto:”, “tel:”, and “file:”. When an Internet Shortcut File uses the “file:” prefix, it refers to a file on the local machine. Interestingly, in this campaign, the “‘file:”’ prefix is followed by a remote UNC path. When a UNC path is navigated to, the protocol used depends on the network provider order, where SMB is configured first by default. If unavailable or blocked by the firewall, it will fall back to WebDAV if the WebClient service is running on the machine (its default startup state is manual). As described here, the specification of a port (@80) within the UNC path enforces Windows to utilize WebDAV over HTTP instead of SMB. This unveils that the file referenced in the .url file’s URL parameter is hosted on a remote WebDAV server.
SAT_Instalar_Complemento.url file contents
The .url file references a .jse file (Jscript Encoded Script) via the URL parameter and overwrites the URL file's default icon with the one referenced in the IconFile parameter - a .pdf icon. This strategic icon replacement, coupled with Windows natively concealing the .url extension (similar to how it handles .LNK files), lures the user into thinking it's a PDF and increases the likelihood of their interaction. When the user clicks the .url file, it triggers a WebDAV connection that makes an HTTP GET request to access the .jse payload on a remote server. Windows prompts the user to authorize the opening of a JScript file from an unknown source. Once the user approves, the .jse file executes on the system using its default application, WScript.exe. It's important to note that the script file is executed directly from the remote WebDAV share.
.jse Downloader
The .jse file contains Encoded JScript - a legacy dialect of the ECMAScript, used in Internet Explorer 11 and older versions. The encoded nature of JSE files comes from the use of Microsoft's tool, Windows Script Encoder. This provides a layer of obfuscation to prevent the file's source code from being copied and arms the actor with a seemingly legitimate obfuscation mechanism that makes the file harder to analyze and detect. The Encoded Jscript script is a downloader, responsible for the retrieval of the next stage from a remote server. It initiates a GET request with the target URL leading to a file masqueraded as a .png file - “enc.png” - however, it is being saved to disk as “enc.hta” in the temp directory. It then executes enc.hta on the victim machine using cmd.exe, which triggers its execution with the default application, mshta.exe.
Decoded \\172[.]86.68.194@80\yes\4545OnINxWmOyPcAXfLWQfhEpjEA.jse file contents
According to our analysis, the remote server is only accessible from Mexico-based IP addresses. When attempting to fetch the payload from other addresses, we received a “403 Forbidden” error.
.hta Downloader & UAC Bypass Module
The .hta file contains obfuscated JavaScript code. The script uses hex-encoded characters and string concatenation to create the strings dynamically at runtime, making it difficult for someone reading the code to understand its purpose. Let's explore the deobfuscation process step-by-step.
JavaScript Deobfuscation
The script ends with:
This is the deobfuscation part of the script. It takes the obfuscated string s, subtracts 1 from each character's ASCII code, and then converts it back to characters to reveal the original script hidden behind the obfuscation. The obfuscation also involves splitting the method names, such as fromCharCode, into smaller parts like “fromC” and “harCode”, and similarly for charCodeAt. This splitting is intended to evade signature-based detection and analysis.
Since we have access to the deobfuscation code, deobfuscating the script is as easy as executing it (in an isolated VM) with a slight modification, replacing the document.write call with a print statement (console.log), or saving the contents to a file.
The result consists of HTML code, containing an obfuscated VBScript block:
VBScript Deobfuscation
Following the JavaScript deobfuscation, we received HTML code with an obfuscated script section:
Once more, the deobfuscation done at runtime is easy to understand, and we can use it to our advantage to statically analyze the code. It utilizes chr() expressions and hexadecimal values. These chr() expressions encapsulate the original characters by shifting their ASCII codes through the deduction of a hexadecimal value. The characters are then concatenated using '&' signs. We wrote a simple Python script that deobfuscates this VBScript section.
Python script for VBScript deobfuscation
The result looks as follows:
Powershell Decryption
If that’s not enough, the result VBScript contains AES-256 encrypted Powershell:
The script is using a 256-bit key for decryption. It then pipes the decrypted content ($OjptJr) to PowerShell using ‘| powershell -’, indicating that the script content will be passed to PowerShell for execution. To decrypt the powershell AES-encrypted content, we can simply replace the 'powershell -' at the end with something like ‘Out-File -FilePath “output.txt“‘ to direct the decrypted contents to a file. Then, we can use a tool like CyberChef to decode (and remove null bytes) the Base64-encoded powershell commands found in the result file.
The resulting code contains a modified version of a public UAC Bypass POC script, which leverages cmstp.exe and automates the process with the SendKeys function to bypass user prompts (as explained in the author’s blog post).
Left: a snippet of the public UAC bypass POC; Right: The decrypted Powershell code
The main differences in the code are:
- The commands to be run elevated : The POC serves as a template and calls for inserting custom commands that will be run elevated, bypassing UAC. The actors wrote the script contained in enc.hta in a way that the .inf file is constructed dynamically, appending each of the custom commands into the file during runtime.
- The installation automation mechanism used: In this campaign, the actors replaced the method suggested in the POC with user32.dll’s PostMessage function. This way, they could send an ‘Enter’ keypress with no user interaction, to automatically press ‘okay’ when a cmstp.exe prompt opens.
Going through the code, we spotted its main function, still slightly obfuscated:
The code starts with a function call- “qAY”. From now on we will call it the main function. It sets a variable to the temp directory path. Then, a call to another function contained in main takes place- “MmlTD”.
“MmlYD” Function: Crafting the .inf File and Automating 'Enter' Key Presses
The function sets the variable “$Zjie” with a script that imports the ‘PostMessage’ Windows API from user32.dll which we will soon touch on. It then defines another function that constructs the .inf file that will later be passed to cmstp.exe, naming the Connection Manager service profile “Notepad” to obscure its actual purpose. The constructed contents are saved to a file named CMSTP.inf inside the temp directory. The script within the variable “$Zjie” is then Encoded using Base64 and executed with Powershell, followed by a 1-second sleep. The following commands are defined to run elevated using this .inf file:
1. Setting a UAC bypass registry key2. Killing cmstp.exe (as instructed in the blog post linked above, to achieve elevation)
Back to the Main Code: Powershell Payload Execution
After the call to “MmlYD” which sets the .inf file and handles the automated ‘Enter’ keypresses, the code continues with what looks like another obfuscated code:
Decrypted Powershell - the end of “qAY” / main function
The previously set “$nlr” variable (recall from earlier- it contains the temp directory path) is concatenated with the file name ‘en.ps1’. Then, a check whether the file exists is performed. If it exists, it calls the function “KvY”, which we will soon analyze. If not, it calls another function, “NIo”, with the result of decoding an array of integers, followed by a call to “WYC”, and finally to “KvY”, with the same Powershell script passed as an argument. This flow gives us the hint that this function is responsible for executing the script.
Decrypted Powershell - the start of “KvY” function
“KvY” is very similar to the “MmlYD” function, handling the .inf file construction and the ‘Enter’ keypresses. It also sets the “Get-Hwnd” and “Set-WindowActive” functions inspired by the public POC we discussed before.
This time, the $CommandToExecute holds “powershell.exe -ExecutionPolicy unrestricted -WindowStyle hidden -File ' + $hTPDumn”, executing the file passed as a parameter to this function- the en.ps1 file that we saw before- while bypassing UAC:
If the .inf file already exists, it calls cmstp.exe (with a minimized window, to hide the activity from the user) with the /au parameter- which installs the Connection Manager service profile for all users.
Decrypted Powershell - the end of the “KvY” function - cmstp.exe execution
Automating the Installation of a Connection Manager Service Profile
The script waits for the cmstp.exe window to be active before pressing the ‘Enter’ key:
Cmstp.exe prompt for the “Notepad” connection profile installation
The script automates the setup of a Connection Manager service profile named "Notepad". It uses user32.dll’s PostMessage function:
PostMessage($handle,[WPIA.ConsoleUtils]::WM_CHAR,13,0)
where the value 13 corresponds to the character code for the "Enter" key. When the target window (cmstp.exe prompt) receives the WM_CHAR message with this value, it interprets it as if the "Enter" key was pressed. This allows installing the service profile without requiring user interaction.
Fetching the PowerShell Payload
Decrypted Powershell - the end of “qAY” / main function
Earlier, we saw that ‘en.ps1’ is executed while bypassing UAC if the file is found in the temp directory. If it isn’t, the script goes on to download it from a remote server using the “NIo” function:
Decoding the arrays found in the main function and in “NIo” is possible with the following python script (equivalent to “tJj”):
We now discovered that “NIo” is a downloader function, retrieving a file from a remote server - “https://facturacionmx[.]click/descargas/en.ps1” - using the Net.WebClient.DownloadData function.
The downloaded data is then passed to “WYC” which saves “en.ps1” to disk, followed by the execution of it using cmstp.exe.
Decrypted Powershell - WYC function- save the downloaded .ps1 payload to disk
Recapping the Main Objectives of enc.hta
1. Download the final stage of the attack
A final .ps1 file is downloaded from a remote server - https://facturacionmx[.]click/descargas/en.ps1 - using the WebClient.DownloadData method, and saved in the temp directory.
2. Execute the downloaded file with elevated rights, bypassing UAC
Decoding the Base64-encoded powershell commands reveals an interesting TTP leveraged by this actor: UAC Bypass using CMSTP. a .inf file is being dynamically formed and structured similarly to a public tool as discussed in the above section. Using this method, the attacker leverages an auto-elevated COM interface, CMSTPLUA, to run the final Powershell payload in a high integrity process, without requiring user interaction.
Final stage: Malicious Browser Extension Installer
The en.ps1 script requires administrative privileges, which makes sense since we now know it’s being run using a UAC bypass technique.
en.ps1 - execution starts here
The Run-Install function is responsible for the installation of a malicious browser extension, specifically targeting Microsoft Edge and Google Chrome:
en.ps1 - screenshot from the Run-Install function
It contains the string “# Reg2CI (c) 2022 by Roger Zander”, a tool for SCCM (System Center Configuration Manager) configuration item creation, probably to hide its malicious intent, tricking security analysts into thinking it’s a known tool. The way it checks whether browser extension related registry keys exist is also similar to the code found in the public tool referenced.
The script repeats the same extension settings for Microsoft Edge and Google Chrome for both 32-bit and 64-bit versions, each followed by “Write-Output ''” and “gpupdate /force /wait:0”.
It uses multiple registry keys for the purpose of the installation:
Edge Extensions Registry Keys:
- HKCU:\Software\Microsoft\Edge\Extensions\lfonlaedlgoccpplaidnhjakfkplaood
- HKCU:\Software\Wow6432Node\Microsoft\Edge\Extensions\lfonlaedlgoccpplaidnhjakfkplaood
Chrome Extensions Registry Keys:
- HKCU:\Software\Google\Chrome\Extensions\lfonlaedlgoccpplaidnhjakfkplaood
- HKCU:\Software\Wow6432Node\Google\Chrome\Extensions\lfonlaedlgoccpplaidnhjakfkplaood
Under each of the keys, it configures the following Registry Values for the “lfonlaedlgoccpplaidnhjakfkplaood” extension:
- install_sources: https://facturacionmx[.]click/descargas/csp.crx
- installation_mode: normal_installed
- toolbar_pin: force_pinned
- update_url: https://facturacionmx[.]click/descargas/index.xml
It also adds the extension to the extension allowlist and forcelist, and the remote server ('https://facturacionmx[.]click/*') to the extension install sources for each browser.
Edge Extension Policies Registry Keys:
- HKLM:\SOFTWARE\Policies\Microsoft\Edge
- HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallAllowlist
- HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallForcelist
- HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallSources
- HKLM:\SOFTWARE\WOW6432Node\Policies\Microsoft\Edge
- HKLM:\SOFTWARE\WOW6432Node\Policies\Microsoft\Edge\ExtensionInstallAllowlist
- HKLM:\SOFTWARE\WOW6432Node\Policies\Microsoft\Edge\ExtensionInstallForcelist
- HKLM:\SOFTWARE\WOW6432Node\Policies\Microsoft\Edge\ExtensionInstallSources
Chrome Extension Policies Registry Keys:
- HKLM:\SOFTWARE\Policies\Google\Chrome
- HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallAllowlist
- HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallForcelist
- HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallSources
- HKLM:\SOFTWARE\WOW6432Node\Policies\Google\Chrome
- HKLM:\SOFTWARE\WOW6432Node\Policies\Google\Chrome\ExtensionInstallAllowlist
- HKLM:\SOFTWARE\WOW6432Node\Policies\Google\Chrome\ExtensionInstallForcelist
- HKLM:\SOFTWARE\WOW6432Node\Policies\Google\Chrome\ExtensionInstallSources
The extension capabilities are believed to be similar to the ones detailed in another blog post, such as system information collection, redirection to phishing websites, and overriding email contents.
Wrapping Up
In this campaign investigation, we've traced a multi-stage malware infection from start to finish. Beginning with a malicious ZIP file hosted on a phishing website, we followed the trail through a series of evasive techniques involving the usage of WebDAV for payload retrieval, encoded PowerShell payloads, and a clever UAC bypass utilizing a legitimate Microsoft utility and an auto-elevated COM interface. The ultimate goal of the attack: to silently install a browser extension designed for unauthorized data collection, exfiltration, man-in-the-browser attacks, and covert communication with the command and control server.
In the final section of this blog, we will delve into practical hunting strategies targeting notable TTPs at various stages of the attack.
Hunt Like Team Axon
UAC BYPASS TECHNIQUES
UAC Bypass Via Auto-Approval Enabled COM Interface: CMSTPLUA
In the CMSTP UAC bypass technique we’ve seen in this campaign, the underlying mechanism that allows this is an auto-elevated COM interface that cmstp.exe leverages, CMSTPLUA (CLSID {3E5FC7F9–9A51–4367–9063-A120244FBEC7}), implemented in cmstplua.dll. This COM interface is run outside of the process that requested it, in the context of the COM Surrogate process, A.K.A Dllhost. This mechanism aims to prevent crashes of the whole code. In the case that the COM hosted code crashes, only Dllhost dies and not the calling process. This makes it challenging to identify the process initiating the elevated process, since they are spawned by Dllhost rather than the originating process. How can we overcome this?
- The Dllhost has the COM CLSID in its command line, allowing us to filter based on known auto-elevated COM interfaces. The command line is structured as follows:
"%\\WINDOWS\\system32\\DllHost.exe /Processid:{CLSID}" - The process that uses the COM interface to execute code, is the RPC client process of the relevant Dllhost instance hosting this code. That being said, if we have visibility into the RPC client process ID of Dllhost, we can leverage it as a strong correlation between the originating process initiating the UAC bypass (in our case- cmstp.exe with the malicious .inf file passed as an argument), and the target elevated processes that run as child processes of the same Dllhost. If we don’t have such visibility, we can also correlate the relevant Dllhost instances with processes that load the relevant DLL, cmstplua.dll, shortly before the elevated processes are spawned.
Hunting Query:
UAC Bypass Via ConsentPromptBehaviorAdmin Registry Key
Another UAC bypass mechanism observed is by setting the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ConsentPromptBehaviorAdmin registry key to 0 (=Elevate without prompting).
This can be detected using a registry value update event.
Hunting Query:
WEBDAV HOSTED PAYLOADS RETRIEVAL AND EXECUTION
WebDAV Payloads Retrieval
When a file is referenced via WebDAV, the Rundll is spawned by svchost.exe (hosting the WebClient service) with the following command line structure:
rundll32.exe C:\Windows\system32\davclnt.dll,DavSetCookie <remote_host> http://<remote_host>/<path>/<to>/<payload>
By extracting the remote host and filtering out internal or frequently accessed servers of the organization, we are able to tune the results and get leads worth looking at- outbound WebDAV connections to unfamiliar servers should raise our suspicion.
Additional Investigation context:
Even though the .jse file was executed remotely, we can still obtain the actual file hash and contents for triage. This is possible thanks to the fact that files referenced via WebDAV are copied locally in the WebDAV cache directory at:
%systemdrive%\windows\ServiceProfiles\LocalService\AppData\Local\Temp\TfsStore
This file creation can also be found in the logs, initiated by the same svchost.exe hosting the WebClient service and spawning the Rundll command lines discussed earlier. This information may aid in quick triage in case the hash is present in the log and can be searched in open source tools like Virus Total, as well as for obtaining the actual file for malware analysis.
Hunting Query:
Execution of a .jse File from a Remote WebDAV UNC Path
One notable command line in this campaign is of WScript.exe, being passed a .jse file (Encoded Jscript) as a UNC path with a port specification (‘@80’), enforcing Windows to execute it from a remote WebDav share. With Encoded Jscript being a legacy file type, such executions from external WebDav shares are considered highly suspicious:
WScript.exe \\<remote_server>@<port>\<path>\<to>\<payload>.jse
Hunting Query:
IOCs
5d824ef872dc86206134370e090825136624d972551d8c454677798ccfb7ba19 |
Cedula_588797.zip |
24b3d6372a9e880420879f920ab832360d31e32dea3e0ae89dd22b72497d0320 |
Cedula_200638.zip |
76e5b88757e2f4e7b935b557352bccf35f76e2e9f3fb284af7778a1005109c6e |
Cedula_362904.zip |
9489a2052c95fa1f90ece58a28d971fa977bdab756712939b99e368ca83b9cc9 |
RFC_55684.zip |
45c6427a6e8d81bd1b22271a92f0ddbf57be0aa20a2001ff73c8914ab9f769fd |
RFC_436159.zip |
c6ff9ac191a2cbe5696615b740b73838ec423d27e1af0609fb054288a4fd549b |
RFC_410101.zip |
499691170eb68986b401a0650464e4ac4e83ce8b4642f3437d825d8ce862c895 |
RFC_671618.zip |
cddc846f86445ec1fef1f165e53bf123b766d357e87df92c9b3080249d27e95b |
CURP_Conexion_Segura_v01.zip |
16b22b331ceea0eb2c0e769b0fe6ab373f8a42faffc17be1459623a03d5d4ee6 |
SAT_Instalar_Complemento.zip |
5a42769088b50823d2b9bf484b656919b8aa692feb0d962d1ba8a2a8e3520075 |
SAT_Instalar_Complemento.url |
453e525f0e9fdb065c2877aebf989ec61a5b43224ef554990a1fc5a4fc26db27 |
constancia.fiscal.url |
67bcdb858016ef742e1dd46fed9bbef6470cbc773c17d0828896de4c1f4be110 |
4496syeqhkejnurnlsaqhvjczyth.exe |
ebce8ec69d60d53e821b10c6a0a1edcf45cf30e928ef9080c491c54392ee4ba4 |
4496ubvwsqzwqtqqmwoqsphndqcu.exe |
487f11c0edc0c2e9450bc3c9b55394d697465c02a2c27baeddd9809f7e1775b4 |
4545OnINxWmOyPcAXfLWQfhEpjEA.jse |
c58ba0d80eca8c3ec0e08fb94e49f4c1de5a6fa8e0eef9209b331ba82fadce7a |
enc.hta |
situacionfiscal[.]online |
|
facturacionmx[.]click |
|
https://facturacionmx[.]click/descargas/enc.png |
|
https://facturacionmx[.]click/descargas/en.ps1 |
|
https://facturacionmx[.]click/descargas/index.xml |
|
https://facturacionmx[.]click/descargas/csp.crx |
|
srlxlpdfmxntetflx[.]com |
|
https://srlxlpdfmxntetflx[.]com/curp-complemento-de-seguridad-descarga/ |
|
172[.]86.68.194 |
References
- Episode V: Cybercartel strikes back - Metabase Q
- New BlackDog malware: Man-in-the-Browser malware campaign targeting Mexico - SCILabs
- Understanding UNC paths, SMB, and WebDAV - N00PY
- RESEARCH ON CMSTP.EXE - Oddvar Moe
To stay updated on threat hunting research, activities, and queries, follow Team Axon’s Twitter account (@team__axon).