As of recent advancements, malware authors are leveraging artificial intelligence (AI) and machine learning (ML) to dynamically alter their evasion techniques. This means that malware can now adapt in real-time to changes in security environments, such as modifications in antivirus software or intrusion detection systems, making traditional static signature-based defences increasingly ineffective. This evolution highlights the growing arms race between cybersecurity defences and malware creators, with each side continuously adapting to outmanoeuvre the other.
The EarlyBird technique has recently gained prominence in the realm of malware evasion by exploiting advanced methods to circumvent detection systems. This sophisticated strategy builds upon the traditional APC Injection method, creating a child process in a suspended state and injecting shellcode that is later executed via asynchronous procedure calls (APCs). This nuanced approach allows the malware to evade conventional antivirus (AV) and endpoint detection and response (EDR) systems, which are typically tuned to recognize more straightforward shellcode patterns. This article delves into the EarlyBird technique’s mechanisms and its implications for modern cybersecurity defenses.
Traditional shellcode loaders typically operate by following a straightforward sequence:
While this approach is effective, it has become heavily signatured, making it easily recognizable to modern antivirus (AV) and endpoint detection and response (EDR) systems.
The EarlyBird technique, however, deviates from this conventional method, enabling it to evade the signatures associated with basic shellcode loaders. By employing a more advanced execution strategy, EarlyBird successfully bypasses many detection mechanisms that would otherwise flag more traditional approaches.
The EarlyBird technique is a “Twist” on the classic APC Injection technique.
Before we dive into EarlyBird, a little background on APC Injection:
Asynchronous Procedure Calls are a Windows operating system mechanism that enables programs to execute tasks asynchronously while continuing to run other tasks. APCs are implemented as kernel-mode routines that are executed in the context of a specific thread. Malware can leverage APCs to queue a payload and then have it execute when scheduled.
Note: Not all threads are able to run APC functions, only threads in alertable state can do so. An alertable state thread is a thread that is in a wait state. When a thread enters an alertable state it is placed in a queue of alertable threads, allowing it to run queued APC functions.
Back to EarlyBird technique.
Now that we understand the classic APC Injection, understanding EarlyBird should be much easier :)
The EarlyBird technique starts by creating a new process (child process) in debug mode or suspended state.
The function that creates the child process returns the process ID, a handle to the process and a handle to the main thread of the newly created process.
In the “CreateSuspendedProcess” function, we need to supply a process name that we want to create, in this context we are using GetEnvironmentVariableA API to get the “C:\Windows” environment variable.
After that we concatenate the variable that holds “C:\Windows” with “\System32\lpProcessName”, In this case it will be “C:\Windows\System32\notepad.exe”
The next function is responsible for injecting the shellcode to the remote process and return the base address of the shellcode in the child process.
The flow is as follows:
When the “InjectShellcodeToRemoteProcess” function finishes executing, it returns the remote address where the shellcode is located within the child process.
Moving onto the main function(){}
We start by defining the process_name as “notepad.exe”, and initialize variables that will hold the returned output from our functions
Once we created the process and injected our shellcode into that process, We pass the returned address of the shellcode in the child process into “QueueUserAPC” function along with the process’s main thread.
The child process is still in suspended mode, which means it won’t run immediately, our APC call is queued to the main thread, and once resumed with “ResumeThread”, will execute.
The same could be achieved with a debugged process, however in order to execute we will need to resume the thread using “DebugActiveProcessStop” instead of “ResumeThread”.
In the following image we can see that the program created notepad.exe, Injected the shellcode into notepad and executed our shellcode with QueueUserAPC.
And we got a beacon! :)
Digging a little deeper with x64dbg, we can see the shellcode address inside notepad.exe:
In today's ever-evolving threat landscape, traditional security measures like antivirus (AV) and endpoint detection and response (EDR) often fall short. Even the most sophisticated defenses can be circumvented through clever techniques and vulnerabilities.
Imagine malware that can slip past multiple security vendors with relative ease. Our method represents a glimpse into the complex world of evasive malware development. While a single technique might not always be enough, combining various approaches can significantly enhance a malware's ability to evade detection.
This example demonstrates the fundamental principles involved in creating evasive malware. By understanding these techniques, you can better anticipate and defend against advanced threats.
Don't let your organization become the next victim. Upgrade your security strategy with our innovative solutions.
More techniques to combine with this shellcode loader are recommended as follows:
• Shellcode obfuscation/Encryption
• IAT Obfuscation
• Function encryptions and decryptions during runtime
• Signing the binary
• Adding metadata to the binary
• Sandbox detection
Until the next one! (:
Liav Mizrahi
Liked it? Share it!