This post is also available in: 日本語 (Japanese)
Executive Summary
Unit 42 researchers recently discovered a Guloader variant that contains a shellcode payload protected by anti-analysis techniques, which are meant to slow human analysts and sandboxes processing this sample. To help speed analysis for this sample and others like it, we are providing a complete Python script to deobfuscate the Guloader sample that is available on GitHub.
In early September 2022, we discovered a Guloader variant with low VirusTotal detection. Guloader (also known as CloudEye) is a malware downloader first discovered in December 2019.
We analyzed the control flow obfuscation technique used by this Guloader sample to create the IDA Processor module extension script so researchers can deobfuscate the sample automatically. The script can be applied to other malware families like Dridex, which utilize similar anti-analysis techniques.
Palo Alto Networks customers receive protections from malware families using similar anti-analysis techniques with Cortex XDR or the Next-Generation Firewall with cloud-delivered security services, including WildFire and Advanced Threat Prevention.
Related Unit 42 Topics | Malware, anti-analysis |
Guloader Control Flow Obfuscation Technique
The Guloader sample in question uses the control flow obfuscation technique to hide its functionalities and evade detection. This technique impedes both static and dynamic analysis.
First, let’s look at how this threat hampers static analysis. In short, it uses CPU instructions that trigger exceptions, resulting in unintelligible code during static analysis.
After peeling away the packer layer of our Guloader sample, we see that its code is obfuscated. Using static analysis tools such as IDA Pro, we observe many 0xCC bytes (or int3 instructions) littered throughout the sample, as shown in Figure 1.
Following the 0xCC bytes are junk instructions. These added bytes disrupt the static analysis tool’s disassembly process, resulting in the wrong disassembly listing.
0xCC bytes are CPU instructions that trigger an exception EXCEPTION_BREAKPOINT (0x80000003), which pauses the execution of a process. The CPU will pass the code flow to the handler function before the execution continues. The handler function is responsible for moving the instruction pointer to the correct address.
The presence of these same 0xCC bytes make it so that using a debugger during dynamic analysis would crash the Guloader sample. Debuggers insert 0xCC bytes as software breakpoints to halt the execution of the sample. The debugger handles the exception instead of the handler function.
Before understanding what happens in the handler function, we first have to locate its address.
Guloader uses the AddVectoredExceptionHandler function to register the handler function, as shown in Figure 2. The second argument of the AddVectoredExceptionHandler function points to the address of the handler function.
Using a debugger as shown in Figure 3, we locate the address of the handler function registered by the Guloader sample. With the address information, we can examine its code. Notably, this ExceptionHandler is registered with the order of 1, meaning it is the first handler to be invoked.
Analyzing the Vectored Exception Handler Function
The first step of analyzing the handler function is to apply its type information, as shown in Figure 4.
Next, we apply the type information for three Windows data structures (shown in Figure 5) used by the handler function.
With the type information applied, we can examine how the function handled the exceptions caused by the 0xCC bytes. Figure 6 shows the decompiled handler function (Func_VectoredExceptionHandler) annotated with comments.
The handler function begins with anti-debugging checks. It will terminate execution when hardware or software breakpoints are found. Next, the offset value is computed by XOR decoding the byte after the 0xCC byte with 0xA9. Finally, the offset value is added to the instruction pointer before the code execution resumes. Code execution continues at the address pointed to by the updated instruction pointer.
After understanding how the obfuscation is carried out, we can identify the legitimate instructions and discard the unwanted ones, as shown in Figure 7.
To completely deobfuscate the Guloader sample, we need to replace all the 0xCC bytes with a JMP short instruction (0xEB) and the following byte with the decoded offset value.
Because doing all this manually is time consuming, in the next section we will show you how to write an IDA Processor module extension to automate the deobfuscation process.
Writing an IDA Processor Module Extension
IDA Processor module extensions allow us to influence the disassembler logic in IDA Pro. These extensions are written using Python to enable us to filter and manipulate how IDA Pro disassembles the instructions in the sample.
The Python script extends the ev_ana_insn method in the IDP_Hooks class. It starts by checking if the current instruction is the 0xCC byte. Next, the 0xCC byte is replaced with the JMP short instruction (0xEB). Finally, the following byte is replaced with the decoded offset value.
Figure 8 shows the function in the Python script where this deobfuscation is implemented.
After applying the Python script, IDA Pro can deobfuscate the Guloader sample automatically, as shown in Figure 9.
Conclusion: Malware Analysts vs. Malware Authors
Malware authors often include obfuscation techniques, hoping that they will increase the time and resources required for malware analysts to process their creations. Using the steps above, you can reduce the time needed to analyze these malware samples from Guloader, as well as those of other families using similar techniques.
Palo Alto Networks customers receive protections from malware families using similar anti-analysis techniques with Cortex XDR or the Next-Generation Firewall with cloud-delivered security services, including WildFire and Advanced Threat Prevention.
Indicators of Compromise
SQ21002728.IMG:
SHA256: fb8e52ec2e9d21a30d7b4dee8721d890a4fbec48103a021e9c04dfb897b71060
SQ21002764
SQ21002728.vbs:
SHA256: 56cdfaa44070c2ad164bd1e7f26744a2ffe54487c2d53d3ae318d842c6f56178
SQ21002764
Additional Resources
- The complete Python script to deobfuscate the Guloader sample is available on GitHub.
- Defeating BazarLoader Anti-Analysis Techniques
- Evade Sandboxes With a Single Bit – the Trap Flag