By Shelly Raban, Threat Hunting Expert at Team Axon
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.
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.
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.
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.
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.
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.
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.
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:
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:
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).
The main differences in the code are:
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”.
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 key 2. Killing cmstp.exe (as instructed in the blog post linked above, to achieve elevation)
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:
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.
“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.
The script waits for the cmstp.exe window to be active before pressing the ‘Enter’ key:
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.
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.
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.
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.
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:
Chrome Extensions Registry Keys:
Under each of the keys, it configures the following Registry Values for the “lfonlaedlgoccpplaidnhjakfkplaood” extension:
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:
Chrome Extension Policies Registry Keys:
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.
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.
UAC BYPASS TECHNIQUES
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?
Hunting Query:
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
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:
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:
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 |
To stay updated on threat hunting research, activities, and queries, follow Team Axon’s Twitter account (@team__axon).