
A new process injection method called Waiting Thread Hijacking (WTH) can be used by attackers to stealthily inject and execute code in a target process, circumventing traditional Endpoint Detection and Response (EDR) systems.Â
Process injection is a widely used technique in malware development, primarily for defense evasion and privilege escalation. Classic options like APC injection or thread execution hijacking have been used extensively but are increasingly monitored by EDRs.
Check Point Research has unveiled that WTH builds on these concepts, taking a more inventive approach that combines thread pool manipulation with targeted memory overwrites.
Instead of using APIs that trigger common EDR alerts, the WTH method exploits waiting threads within a target’s thread pool.Â
Dormant threads can be hijacked without the need for suspension or manual context modification. By overwriting the return address in the thread’s call stack, attackers can seamlessly redirect execution to malicious code.
WTH offers distinct advantages over older methods of thread hijacking, including the avoidance of detection triggers, stable execution, and simplicity and effectiveness.
It eliminates the need for API calls commonly flagged by EDR systems (e.g., SetThreadContext) and reduces reliance on suspicious thread-suspending flags.
The malware maintains application stability by leveraging threads that naturally return to active states post-injection and uses widely available APIs that are ubiquitous in benign processes, making detection via static analysis harder.
Using the NtQuerySystemInformation API, attackers enumerate threads within the target process to locate those in a waiting state. Threads waiting on kernel objects or completion status queues, identified by the WrQueue state, are prime candidates.
Malicious payloads are injected into the target process using standard memory allocation and writing functions. This step avoids APIs flagged for execution, relying solely on write operations.
The final step involves replacing the return address on the thread's call stack with the address of the malicious payload. Once the thread resumes naturally, it executes the malicious code as if part of the application’s workflow.
After execution, the original return address is restored, allowing the thread to return to normal operations and minimizing any disruption to the target application.