This post presents a simple yet effective approach to quickly scan running processes for runtime code injections, something we always felt is required during analysis of a possibly infected system.
There are a bunch of techniques available for generic injection of custom code into the address space of a remote process in Windows platform, some of which are documented here and here. In most cases, a call to CreateRemoteThread(..) is made to start execution of injected code under the context of the remote process.
A rough workflow for injecting and running code within the address space of a remote process can be summarised as below:
DLL Injection done using SetWindowsHookEx API does not involve a call to CreateRemoteThread(..). However detecting injection of malicious DLL using SetWindowsHookEx is usually trivial - One just needs to list all the loaded modules in the target process and look for possibly non-standard path.
We aim to devise a more or less generic approach for detecting injected code in the address space of a given process in a non-intrusive manner.
Our approach is tested against some of commonly used tools and trojans that employ process injection techniques such as Metasploit's Meterpreter and common process injecting trojans like PoisonIvy, Cyber Gate etc.
Our approach involves False Negative if a DLL is injected into the address space of remote process using SetWindowsHookEx API.
False Positives were encountered while testing applications that generate valid code at runtime such as Java JIT Compiled code. False Positives may also be encountered for packed executables that perform in-memory unpacking.
We employ a simple yet effective methodology for scanning multiple processes at runtime for injected code. Our approach is simple and easy to implemented without too much of performance hit.
The crux of our approach lies in the fact: In almost all cases of code injection in remote process memory, the foreign code that is being introduced in the address space of the target process for execution does not belong to any of the executable sections of the PE files(s) (exe, dll etc.) loaded within the context of the target process.
Our methodology involves scanning each thread context and its corresponding stack frames in the target process for possible Instruction Pointer address that does not belong to an executable section of any of the PE modules loaded in the target process.
The full implementation of the above methodology is available Here. The implementation involves the following core steps:
Implementation Note: Stack Walking is a non-trivial process due to that fact that stack may look very different for different executables due to difference in compiler settings and optimization. Stack Walking process may be different for different platforms as well. StackWalk64 is a documented and portable method for enumerating stack frames of a given Thread however appropriate care must be taken else obtained results may be incoherent.
This is a proof of concept pre-alpha release only. Feedback and bug reports will be greatly helpful.
Code Injection Techniques
There are a bunch of techniques available for generic injection of custom code into the address space of a remote process in Windows platform, some of which are documented here and here. In most cases, a call to CreateRemoteThread(..) is made to start execution of injected code under the context of the remote process.
A rough workflow for injecting and running code within the address space of a remote process can be summarised as below:
- Obtain a HANDLE to the target process with appropriate privileges using OpenProcess(..)
- Allocate memory for code to be injected using VirtualAllocEx(..)
- Write code in the allocated memory using WriteProcessMemory(..)
- Finally, execute the injected code under the context of the target process using CreateRemoteThread(..)
DLL Injection done using SetWindowsHookEx API does not involve a call to CreateRemoteThread(..). However detecting injection of malicious DLL using SetWindowsHookEx is usually trivial - One just needs to list all the loaded modules in the target process and look for possibly non-standard path.
Scope of our Approach
Our approach is tested against some of commonly used tools and trojans that employ process injection techniques such as Metasploit's Meterpreter and common process injecting trojans like PoisonIvy, Cyber Gate etc.
Limitation of our Approach
False Positives were encountered while testing applications that generate valid code at runtime such as Java JIT Compiled code. False Positives may also be encountered for packed executables that perform in-memory unpacking.
Methodology
The crux of our approach lies in the fact: In almost all cases of code injection in remote process memory, the foreign code that is being introduced in the address space of the target process for execution does not belong to any of the executable sections of the PE files(s) (exe, dll etc.) loaded within the context of the target process.
Our methodology involves scanning each thread context and its corresponding stack frames in the target process for possible Instruction Pointer address that does not belong to an executable section of any of the PE modules loaded in the target process.
Implementation
The full implementation of the above methodology is available Here. The implementation involves the following core steps:
- Enumerate each Thread in the target process.
- For each Thread, obtain the stack trace of the Thread using StackWalk64 API.
- For each Stack Frame, check if Instruction Pointer (AddrPC) points to any address outside executable sections of the loaded PE modules (exe, dll etc.)
Implementation Note: Stack Walking is a non-trivial process due to that fact that stack may look very different for different executables due to difference in compiler settings and optimization. Stack Walking process may be different for different platforms as well. StackWalk64 is a documented and portable method for enumerating stack frames of a given Thread however appropriate care must be taken else obtained results may be incoherent.
Field Testing
- Meterpreter (Reflective) DLL Injection
- Poison Ivy (Browser Process Injection)
- Cyber Gate (Browser Process Injection)
Meterpreter migrated to Notepad.exe Address Space |
PoisonIvy running inside default browser |
This is a proof of concept pre-alpha release only. Feedback and bug reports will be greatly helpful.
References
http://support.microsoft.com/kb/2458544
https://github.com/abhisek/RandomCode/tree/master/Malware/Process
http://metasm.cr0.org/
http://en.wikipedia.org/wiki/DLL_injection
http://www.codeproject.com/Articles/42450/Remote-Code-Process-Injection-and-Relocation
http://msdn.microsoft.com/en-us/magazine/cc301805.aspx
http://www.codeproject.com/Articles/11777/InjLib-A-Library-that-implements-remote-code-injec