3S Labs Banner

Friday, January 25, 2013

Scanning Process Memory for Injected Code

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.

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:


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


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.

Limitation of our Approach


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.

Methodology


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.

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


6 comments:

  1. Really Interesting.. I gotta try this out! Are you having many false positives?

    ReplyDelete
  2. So far I had false positive only for Java. I believe there will be false positive for any VM like application that generates JIT native code at runtime.

    ReplyDelete
  3. Not reliable if cannot bypass false positives within pe packers.

    ReplyDelete
  4. Code cave methods where ResumeThread , SetThreadContext are used for injection may not be catched by your approach !!!!

    -Gowtham

    ReplyDelete
  5. I agree, will check what I do about it.

    ReplyDelete
  6. I wrote a tool very similar to this in C#/PowerShell reflection that works on x86, x64, and IA64. Seems to work pretty well for me. https://github.com/secabstraction/PowerWalker

    ReplyDelete