Breaking Down Builder-encrypted RAT
The emerging trend of Fully Undetectable (FUD) malware builders is not new to our research team. However, in light of the wide variety of techniques that the malware authors keep developing, it’s obvious that we will always encounter malicious code execution tricks that successfully bypass traditional anti-malware solutions.
This blog post is actually a case study, where we describe our investigation of an interesting malware sample that was detected at one of our customer’s sites and that has been active for more than a year, on an up-to-date secured host.
To learn more about the threat hunting process that lead to the discovery of this malware sample, read our blog post Threat Hunting with TPS to Reveal Undetected Malicious Activities
After we detected the sample, we decided to fully analyze it, in order to gain additional insights. This led to the discovery of a unique approach to packing a commodity Remote Access Tool (RAT), utilizing tailored AutoIt crypter and shellcode. AutoIt crypters are known to be popular with FUD builders, mainly because of their capability to easily implement evasion techniques.
Here is the description of the evasion tricks and techniques we discovered in this unique malware sample.
In a nutshell, the malware execution flow consists of the following:
- Autoit PE is executed from the user`s Roaming folder via auto-run registry key along with a compiled script as a command-line parameter
- The AutoIt PE as itself, which is a legitimate PE
- The compiled script – consists of AutoIt tokenized compiled script with additional binary data
- The script is responsible for 3 main actions:
- Decrypting the binary data to get configuration, shellcode and encrypted PE
- Basic installation for maintaining persistency
- Loading the shellcode + encrypted PE and executing the shellcode
- The shellcode, which is also used as a stager, is responsible for:
- Resolving addresses of API functions that are used for process hollowing
- Decrypting the PE within the memory
- Utilizing process-hollowing for executing the malicious PE under the context of a legitimate Windows process
- The malicious PE – Cybergate RAT
The AutoIt script
AutoIt, currently version 3, is a scripting language for automating Windows tasks. Its key characteristics – such as digitally-signed small self-contained executable as interpreter, process manipulations and direct calls to the Windows API — make it a free, powerful and easy tool for malware authors.
In our initial investigation, we examined the AutoIt executable, named Firewall.exe, which was executed from the user’s roaming directory via auto-run registry key along with a compiled script, named Firewall (1/56 VT detection at the time of writing), as a command-line parameter.
The compiled script is obfuscated and password-protected. Protecting AutoIt scripts is a topic in itself, and for our purpose we used an automated tool named “myaut2exe” for the process, which also provides great documentation regarding the compiled script file format. Another interesting attribute is the script’s file size – 288KB – an odd size for a compiled script, since scripts are usually much smaller (lines of code) and it also contains additional binary data, while the compiled script itself is only 4,315 bytes.
The binary data within the script is split by a static string into 8 elements: RC4 key, RC4 shellcode, configurations and RC4 encrypted data. In our case:
Local $SPCFG = StringSplit($SR, "$h..la?A.AhDr2.?..h.", 1) ; Splitting the binary data from the script Local $PASSRC = $SPCFG ; RC4 key = IQQtCM $OPCODE = $SPCFG ; Global variable for RC4 function = RC4 shellcode Local $SERCFG = BinaryToString(_RC4($SPCFG, $PASSRC)) ; Configuration for persistence installation Local $SP = $SPCFG ; SLEEP before script execution in seconds = 120 Local $INGETCTTO = BinaryToString(_RC4($SPCFG, $PASSRC)) ; Function name that retrieves the path for the process to be hollowed = .net server (regsvcs.exe) Local $SERVEBIN = _RC4($SPCFG, $PASSRC) ; 1st decryption of the RAT binary Local $SELFDELETE = $SPCFG ; Self delete flag= 0, might change in runtime under some circumstances $SHELLCODE = BinaryToString(_RC4($SPCFG, $PASSRC)); Shellcode which will be executed at the end of the script _GETSERVERCFG variables
Some of you might raise an eyebrow when stumbling upon ‘RC4 shellcode’ ($OPCODE). It’s actually a machine-code implementation of the RC4 algorithm (the variable’s content is hex encoded) that is executed using a known technique within scripts, for executing shellcode. This is done by calling the Windows API function CallWindowProc along with pointers to the shellcode, encrypted data structs, encrypted data length and the key string as parameters. Needless to say, an RC4 implementation in the AutoIt scripting language could be written in a much simpler way, without using any machine code, so why not do that (the exact same implementation is used within the shellcode)?
Func _RC4($DATA, $KEY) ; Creating and loading the data in the memory for using in DllCall Local $CODEBUFFER = DllStructCreate("byte[" & BinaryLen($OPCODE) & "]") DllStructSetData($CODEBUFFER, 1, $OPCODE) Local $BUFFER = DllStructCreate("byte[" & BinaryLen($DATA) & "]") DllStructSetData($BUFFER, 1, $DATA) ; Executing the RC4 shellcode DllCall("user32.dll", "none", "CallWindowProc", "ptr", DllStructGetPtr($CODEBUFFER), "ptr", DllStructGetPtr($BUFFER), "int", BinaryLen($DATA), "str", $KEY, "int", 0) Local $RET = DllStructGetData($BUFFER, 1) $BUFFER = 0 $CODEBUFFER = 0 Return $RET
AutoIt RC4 function
Read about the threat hunting process that lead to the discovery of this malware sample here.
RC4 shellcode ($OPCODE) in IDA
After decrypting and parsing the binary data, the script installs persistence mechanisms, which are defined by an array of 16 configuration elements that include parameters such as the location and folder name for installation, executable and script file names and execution flags, for functions that maintain the automatic execution of the malware.
In our analysis, the script maintains persistence by:
• Copying the executable and script named Firewall.exe and Firewall respectively, under a folder named Javaxa within the Application Data directory
• Setting registry RUN keys under both user’s and machine’s hives
• Creating a shortcut named Win32.lnk within the Startup directory
In order to hollow (and inject) a legitimate process using the shellcode, the script returns the PE path based on the configuration, which can be one of the following:
• .Net Server – path to RegSvcs.exe, which is part of the .NET framework installation
• Default browser – as opposed to the .NET, this one utilizes a failover mechanism in the following order: default browser within the registry, default location for iexplore\chrome\firefox, cmd.exe
• svchost.exe or its own process (AutoIt process)
To execute the shellcode, the script creates a struct that contains the shellcode and the encrypted RAT server PE binary ($SERVEBIN in figure 1), followed by a direct function call to the shellcode memory address pointer, along with the pointer to the encrypted PE and the path to the process to be hollowed.
From the malware author perspective, using AutoIt as the 1st stage wrapper for the RAT, is a great way to bypass known AV techniques for detecting malware, since its main objectives are loading binary data to memory, which for AV vendors is more challenging to prevent, and installing persistence mechanisms that are also common for software. The method of decoding the configuration and the RAT within the script file, makes it adaptable for modifications in order to evade detection based on IOCs – those all are ‘FUD’ builders main functionality.
Shellcode, in a cybersecurity context, refers to a position-independent machine code payload that is usually used in exploits and malware for executing malicious code directly from the memory. In our case, the shellcode’s purpose is to decrypt the RAT PE within memory and inject it into the hollowed process.
Shellcode functions graph in IDA
Since the shellcode is not loaded by the Windows PE loader, it must first resolve pointers to the Windows API export functions it wishes to use. In our case these will be used for the Process Hollowing technique:
• LoadLibraryA, ZwUnmapViewOfSection, CreateProcessW, ReadProcessMemory, WriteProcessMemory, GetThreadContext, SetThreadContext, ResumeThread, VirualAllocEx, VirtualAlloc, VirtualFree, TerminateProcess
This is usually done by using a well-documented technique that consists of:
• Finding the DLL image base address of kernel32.dll (findKernelBase in the above graph)
• Iterating through the DLL functions, hashing each function name using ROR13 and comparing them with a precomputed value within the shellcode (findFunctionAddress in the above graph)
Except that in our case it’s a bit different with 2 noticeable characteristics. The first one is that the shellcode also needs to find the ntdll.dll base address for resolving the ZwUnmapViewOfSection pointer. The second is that instead of storing the precomputed ROR13 function names within the shellcode, it stores the ASCII function names and hashes them in run-time, making it odd, since it misses the advantages of the hashing technique. The fact that the author appears to have left some redundant information (ASCII function names) looks sloppy. From the attacker’s perspective it would have been smarter to remove the function names since these only aid in detecting the malicious nature of this code.
Resolving exported functions in IDA
Once the shellcode resolved all the functions, it will execute the second decryption routine, that is the exact same machine-code RC4 implementation we encountered in the previous stage, this time with a memory pointer to the RAT PE, along with its size and a pointer to the key (The key is in hexadecimal: 6C D5 D9 A0 C4 01 D4.).
And now for our final action within the shellcode: The Process Hollowing technique (AKA process replacement / RunPE). This is a very popular and well-documented technique that basically allows the malware to execute under a legitimate process context. In our case, the malware executes and hollows RegSvcs.exe and injects it with the fully decrypted RAT PE from our AutoIt executable (Firewall.exe) memory space.
Calling the process injection function in IDA
Commodity RATs are used by all kinds of threat actors. They usually provide a preconfigured framework for both client and server, with a set of powerful features that make them easy to use, but also easy to detect once all obfuscation methods are removed. Our PE RAT was easily detected by string-based analysis from the memory, and was found to be Cybergate 1.18, one of the popular Delphi-RATs, similar to XtremeRAT and Spy-Net.
The RAT string references from memory using x64dbg
For commodity RATs, there are usually scripts available that decode and extract the RAT’s configuration based on the release. We retrieved the configuration using Cybergate decoder (by extracting it from the resource section and decoded it using XOR):
Key: Activate Keylogger Value: TRUE Key: Domain Value: majika.gotdns.ch|parfuis.no-ip.biz|maskou.gotdns.ch| # Domains for resolving IPs Key: Install Flag Value: FALSE Key: Keylogger Enable FTP Value: FALSE Key: Mutex Value: 6GJW1B6O667L61 Key: Persistance Value: FALSE Key: Password Value: 123456 # Password for client-server authentication Key: Port Value: 97|288|1177 # Ports for establishing reverse TCP shell Key: Process Injection Value: Disabled Domains resolving to attacker IPs
Now it’s easy to see that the RAT configuration reflects with its previous stages: the AutoIt script is responsible for the persistence mechanisms and the shellcode for the process injection, so the RAT doesn’t perform any installation or injection, as its sole purpose is to reside within the memory.
Additionally, the MFT records of Firewall.exe and Firewall were tampered, the $STANDART_INFORMATION attribute was modified to earlier dates in order to frustrate forensic analysis (AKA timestomping, an anti-forensics technique). This method was easily detected as the adversary didn’t take further measures to also modify the $FILE_NAME attribute.
Firewall MFT record in Autopsy
|Autoit Script MD5||70399E8D40708031256AB36CAC9C4CFB|
|Cybergate PE MD5||138D30984573FC27FF1DC616DF10B6D3|