Recently, the SonicWall Capture Labs threat research team observed a new campaign spreading Violet RAT using a multistage Python-based APC injection technique. The campaign employs a multi-stage delivery chain that involves archives, batch scripts, and a Python loader to deploy the final payload via shellcode injection. The complete infection chain can be visualized in the following figure 1.
Figure 1: Infection Chain
The initial infection vector is an archive file delivered by email. This archive file contains a heavily obfuscated batch file.
BATCH FILE:
The batch file begins with the bytes 0xFF 0xFE, indicating UTF-16LE encoding. When opened in Notepad, the file is rendered as garbled characters due to an encoding mismatch, making it unreadable to the victim.
Figure 2: Unicode batch file
The batch file initially runs a hidden PowerShell to open 'google.com'. This website opens in the victim's default browser. The malware proceeds to download did.zip from a cloud file hosting service into the /Contacts/dad subdirectory within the %USERPROFILE% directory. Subsequently, a batch file named start.bat is downloaded to the path %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\.
Figure 3: Batch file
Next, inside the %USERPROFILE%/Contacts/dad directory, it executes the python script stry.py with the parameters mentioned in the image. The start.bat also has the same code, which runs a hidden PowerShell and executes the stry.py. In the event of a failure to retrieve keys from a.txt in the extracted directory, the loader downloads a.txt or b.txt from the same hosting service to obtain the decryption keys for the shellcode.
PYTHON SCRIPT:
The extracted zip has multiple contents as shown below:
Figure 4: Did.zip files
Stry.py: Python script to decode and inject the shellcode
Nou.bin: encrypted shellcode
a.txt: set of keys required to decrypt the shellcode.
It also has multiple supporting Python libraries, which are required to carry out the execution smoothly. The Python script obfuscates datatypes, API names, function prototypes and parameters by masquerading them under different names using its own defined structures and variable assignments. The script calls itself “Advanced Payload Executor”. We can see the parameters and descriptions in the image below.
Figure 5: Python script
As discussed previously, the shellcode and key file names were provided in a batch file. The target process for injection can be provided in the command line; it is by default explorer.exe. The keys from a.txt are concatenated in the transformations array. This is further used by the transform_data function to decrypt the shellcode. The key is reversed and then XORed to retrieve the compressed shellcode blob from encrypted data. This blob is decompressed using zlib.decompress() function.
Figure 6: Process Injection
Payload execution is then triggered using ResumeThread() and WaitForSingleObject() APIs. With this, the shellcode blob starts executing under explorer.exe.
SHELLCODE EXECUTION
Below are the initial bytes of the shellcode blob.
Figure 7: Shellcode blob
Initially, it resolves a few Ntdll.dll and kernel32.dll APIs dynamically using API resolution via address traversal. The data at address 0x230 of the shellcode is again decrypted using custom ARX cypher [ADD(0x4,0x8,0xC), ROL(0x5,0x8,0x10,0xD,0x7), XOR()]. The 16-byte key stored at the start of the shellcode at address 0x19 is used to decrypt the data.
Figure 8: LoadLibrary mscoree.dll
Further, from decrypted data, it loads oleaut32.dll, mscoree.dll, wininet.dll, ole32.dll and api-ms-win-core-com-l1-1-0.dll using LoadLibraryA. Most of these APIs include memory APIs, Internet APIs and CLR hosting APIs. The malware loads AMSI.dll at runtime and resolves AmsiInitialize, AmsiScanBuffer, and AmsiScanString using GetProcAddress. It subsequently overwrites the in-memory implementations of AmsiScanBuffer and AmsiScanString with a shellcode stub that forces successful return values, effectively disabling AMSI scanning.
Figure 9: AMSI patching
The patched shellcode will return output in such a way that the malicious file scan result will always be clean. This patches AMSIScanbuffer using inline patching.
The patch explicitly sets the scan result to 0x00000000, indicating benign content, and returns S_OK, thereby bypassing AMSI inspection. This way, AMSI is neutralised by hooking both the scanning APIs. Next, the malware loads API WldpQueryDynamicCodeTrust() from WLDP.dll, which checks if the specified in-memory or on-disk .NET CRL dynamic code is trusted for execution by device guard policy.
CLR HOSTING
Furthermore, it uses Native CLR hosting to execute the native assembly stealer code. You may read more about the analysis of native process CLR hosting in our old article. CLR hosting is when a native/unmanaged process explicitly loads and controls the .NET runtime (CLR) to execute managed code inside its own process.
Figure 10: CLRCreateInstance
Using CLRMetaHost:GetRuntime, it loads the .NET Framework compilation version, which is “v4.0.30319” here.
Figure 11: GetRuntime
Following that, a new AppDomain with the name “3HXW4YRM” is created using CorHost::CreateDomain. The PE file to be injected is copied into the single-dimensional SafeArray of size 0xA987F8. The final transition to managed execution occurs via GenericComCallStub, an internal and largely undocumented CLR interop stub.
Figure 12: GenericComCallStub
This pointer resolves to AppDomain.ExecuteAssembly, which subsequently invokes InvokeStub() to handle the native-to-managed execution transition and argument marshalling.
Payload
The injected Malware is Violet RAT. This RAT is a malware-as-a-service (MaaS), discovered last year. The image shows a few of the data it retrieves from the victims’ systems:
Figure 13: VIOLET NEW.exe Strings
Data collected by VioletRAT from the victim system is transmitted to the command-and-control (C2) server at 176.65.132[.]10:7000, which is referenced in a Pastebin URL -hxxps://pastebin[.]com/raw/5TDDMvmC.
Figure 14: Violet RAT Webpage
The VioletRAT web panel highlights an extensive feature set, including device and system control, auxiliary tools, Windows Defender tampering, and networking capabilities. Our analysis shows that this campaign employs a multi-stage loader that dynamically resolves APIs, hosts the CLR to execute managed payloads in memory, and actively bypasses security controls such as AMSI and WDAC. Overall, this represents a relatively new loader implementation observed in recent VioletRAT campaigns and reflects a growing level of sophistication in the malware’s delivery and execution chain. This threat is detected by SonicWall Capture ATP w/RTDMI.
Jayesh specializes in reverse engineering various types of malware, decoding infection chains and implementing measures to protect users. He is very passionate about his work and is an experienced technical content creator and security researcher.