3S Labs Banner

Showing posts with label win32. Show all posts
Showing posts with label win32. Show all posts

Thursday, June 13, 2013

HiDump: Tracing and Extraction of Runtime Injected Code

Malware analysis is Fun!

It is particularly satisfactory if the analyst manages to identify and somehow extract the hidden core logic/component of a given malware which is crypted and protected in order to hinder analysis efforts.

In reality, most malware we have encountered are either packed partially or uses in-memory injection of decoded/unpacked core logic at runtime to evade Anti Viruses. It is usually trivial to unpack such malware using a Debugger or IDA with Debugger plugin. We have rarely, but indeed, experienced malware protected with advanced engines like Themida, VMProtect etc. which are non-trivial to analyse due to extensive code obfuscation or virtualised instructions and multiple anti-debugger techniques.

RunPE


Perhaps the most commonly used crypter technique is RunPE. The original executable is encoded/encrypted and somehow embedded inside a Stub Executable either in a PE section or as EOF data or as a Resource. The Stub Executable in turn decodes/decrypts the original executable in-memory at runtime and uses RunPE engine to load and execute it.

The RunPE technique consists of the following steps:
  • Execute a host process (HP) (say notepad.exe) with CREATE_SUSPENDED flag set.
  • Identify the ImageBaseAddress of the original executable (OE) to be loaded from its PE Header.
  • Attempt to allocate memory for OE in HP's address space at OE's expected based address.
  • If OE's expected base address not available, unmap HP's original mappings and allocate memory.
  • Write OE's PE sections into the address space of HP using WriteProcessMemory(..) API.
  • Change the ImageBase in HP's PEB if required.
  • Resume execution of main thread in HP.
The crux of the technique lies in OS's support for the CREATE_SUSPENDED flag in CreateProcess(..) API. This flag tells the kernel to suspend the main thread of the newly created process immediately after the PE is loaded and the sections are mapped. At this point, another thread must call ResumeThread(..) API on the main thread before control is transferred to NTDLL's LdrInitialize(..) and the process is loaded in the usual manner (Import Resolution, Base Relocation etc.)

The RunPE technique involves replacing the original program image from the address space of the newly created process with that of the program it intends to execute. In memory execution of a program will involve doing everything which the OS's Program Loader does. In order to avoid doing everything by itself, the RunPE technique lets the OS do everything, just that it replaces the original program content with its own payload in time ie. after the target program is mapped into the address space of the newly created process but before the PE Loading process is initiated.

Extracting executables protected with RunPE like crypters are usual trivial as it involves setting break points in memory allocation and memory write routes and dumping decoded/decrypted content using a debugger. However things get a little tricky with a bit of obfuscation and anti-debug ...


The VMProtect Story


In the past, we had come across a malware (stage1 really) which simply does the following:

  • Fetch an encrypted DLL (stage-2) over the Internet via. HTTP
  • Decrypt the DLL in-memory
  • Inject it into explorer.exe address space.

Essentially the core logic of the malware resided in Stage-2 DLL however due to custom compression & encryption, it was not possible to obtain the DLL for further analysis just from a pcap dump. Usually the next approach would be to use a Debugger to trace the Stage-1 executable, set appropriate breakpoints and obtain a dump of the decrypted DLL before it is being injected into explorer.exe.

However it turned out that the Stage-1 was protected with VMProtect with Debugger detection turned on. It was not possible to use a debugger to trace Stage-1 as it was detecting a debugger presence (we did not try a kernel debugger that time) and halting execution.

At that time, we solved the issue using a Pin Tool. Since PIN does not use Windows Debugging API for injection or management of PIN Tool, it was possible to trace execution of Stage-1 using a PIN Tool. We could hook WriteProcessMemory(..) and extract the decrypted DLL from Stage-1 for further analysis.


HiDump


The idea for HiDump was conceived based on our experience with analysing protected malware with anti-debugging capability. Our objective was to devise a generic technique for extraction of data/code written using WriteProcessMemory(..)  Our implementation will attempt to avoid using Windows Debug API in order to play nice with Anti-Debugger checks.

Implementation:

The system consists of 2 core components:
  • Loader: Execute target executable with 'Monitor' injected into it.
  • Monitor: A DLL that hooks Windows API for monitoring and data extraction.
Loader:
  1. Start Target exe with CREATE_SUSPENDED Flag
  2. Inject Monitor DLL in the address space of Target exe
  3. Resume Main Thread of Target exe (continue execution)
Monitor:
  • Hook OpenProcess, VirtualAllocEx, WriteProcessMemory, CloseHandle, CreateRemoteThread
  • Build State Machine for Data/Code Capture as per Hook Trigger Events
  • On End-State, dump data to disk
The Monitor is implemented using Microsoft Detour library for API Hooking. Essentially the monitor hooks following Windows API:


The Monitor internally maintains a State-Machine that starts with OpenProcess(..) and usually ends with CreateRemoteThread(..). The reason for maintaing a State-Machine is to record all memory write in the same order and offset in which a given block of data is written in the address space of the target process. When an event occurs that is marked as an End-State such as a call to CreateRemoteThread(..) the monitor attempts to dump all data recorded for that corresponding context (consisting of Process Handle, Allocated and Written Memory).

This technique however lacks the capability to identify and extract code injections using SetWindowsHookEx(..) or QueueUserAPC(..) APIs. However we believe the tool can be extended to consider those cases as well.

Proof of Concept Implementation:

A proof of concept implementation is available in Github.

Sample Execution against VMP Protected Executable

Monitor logs captured using syelogd.exe

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


Friday, September 7, 2012

Unpacking ASPack-2.29 using Dynamic Analysis

ASPack is a Win32 executable file compressor which also protects the executable against basic Reverse Engineering. Although there are automated tools like IDA Pro's Universal Malware Unpacker or can probably be unpacked using techniques defined in BitBlaze Renovo, we analyzed ASPack protected executables using Dynamic Analysis particularly as an exercise for our upcoming training on Reverse Engineering and Malware Analysis at Nullcon 2012 Delhi.

Following analysis is based on Free version of ASPack 2.29.

ASPack-2.29 Generated Executable Overview

ASPack compresses each section of the input executable along with adding two of its own section: .aspack and .asdata - the former containing the decoder and loader code however it is currently not clear about the purpose of the later as it seem to be empty (SizeOfRawData = 0).

Section List for Original Executable

Section List for Packed Executable

Comparing the Section Listing of the original and packed executable above, following assumptions can be made:

  • ASPack keeps the original sections intact including the section RVA however it sets the section mapping permission to RWX instead of the original R_X.
  • ASPack adds two news sections - .aspack and .adata among which the purpose of .adata is unknown as it is empty.
  • As understandable, the original entry-point is redirected to point somewhere within .aspack section.

Analysis Approach

The approach was conventional - start with Static Analysis to have a basic idea of the decoder logic and look for possible anti-debug or anti-diassambly technique and acquire enough knowledge to proceed with Dynamic Analysis. We needed to identify important code blocks like decoder loop, section mapping, control transfer to Original Entry Point (OEP) etc before we can proceed with automated unpacking.

Static Analysis


The entry point code in .aspack section in the packed executable uses a bunch of fake long and short jump op-codes (0xe9, 0xeb) to break the disassembler (Note: IDA 6.3 can detect such obfuscation technique and disassemble correctly without manual intervention). After little manual fix-up the code can be analyzed and IDA 5.0 (free) can build the Flow Graph correctly as shown below.



Three APIs as shown below in the disassembly were found to be resolved early in the loader code. Based on this logic, we made an assumption that those APIs will be used in order to decode and map sections and hence are perfect analysis points during Dynamic Analysis.


Dynamic Analysis

Phase1

We needed to verify that the decoded code is executed from its original location (as mapped by the PE Loader). Since our test executable was a GUI application (calc.exe) which inevitably calls GetMessageW, we set a breakpoint on the API and on breakpoint hit we could verify that the original code was decoded and execute from its original location only.

Phase2

Once it is verified that ASPack decoder decodes and execute original code in-place, we wanted to discover the decoder code block. For this we set a break-on-write (ba w4 addr-range in WinDBG) at the base address of the mapping containing the packed code.

Phase3

During Phase1 we noticed that the memory mapping of the decoded .text section is changed to R_X before execution from its original RWX permission as seen in the packed executable. From this we inferred that VirtualProtect must have been used before control is transferred to OEP.

Using this logic we were able to determine the exact point where ASPack loader transfers control to the OEP in the decoded .text section as shown below:




Little trial and error proved that ASPack loader does not seem to have any random or metamorphic component and hence this particular code above is always at an offset 0x420 from the base of .aspack section. The 0x00 above is patched with the computed OEP address at runtime.

Workflow for Automatic Unpacking

  • Set breakpoint on entry point
  • On breakpoint hit
    • Set breakpoint on OEP Caller address (push)
    • On breakpoint-hit
      • Dump the PE
      • Update entry point in PE Optional Header
      • TODO: Re-construct IAT

The Tool

The tool is written using the wonderful Metasm Framework, without it a LOT of work would have been required. The core logic is as below:


The full code is available here.

Closing Note: ASPack is not really meant for executable protection as such, it is more of a compression system similar to UPX. For serious requirement, appropriate tools like ASProtect, Themida, VMProtect etc. should be considered.

Advertising:

We will be conducting a 2-days workshop on Reverse Engineering and Malware Analysis at Nullcon 2012 Delhi which includes topic as described above along with other interesting topics like Dynamic Binary Instrumentation, Binary Patch Analysis etc. If you are new to Reverse Engineering, we will try our best to equip you with the basics of x86 ASM and Win32 platform components so that you can benefit from open information available on the internet. Do check out if you are interested.



Reference

http://www.aspack.com/
http://metasm.cr0.org/
http://bitblaze.cs.berkeley.edu/

Wednesday, August 8, 2012

Remote DLL Loader

Sometimes it is required to somehow force a remote process to load an arbitrary DLL via LoadLibrary. The loaded DLL once executed from within the address space of the target process can then perform a wide variety of operation. This can be achieved using AppInit_DLLs registry option for applications which are linked with user32.dll.

However we want a bit more generic solution and that too without modifying anything in the system. The idea is quite simple and perhaps widely used:
  • Find or execute the target process and obtain its handle
  • Allocate memory in the target process using VirtualAllocEx
  • Write a shellcode that performs LoadLibrary("C:\\Our.dll") using WriteProcessMemory
  • Execute the shellcode using CreateRemoteThread

Thanks to the excellent Metasm library, building and testing the tool was a matter of less than an hour. The tool can be found here.

Note: The loader shellcode will look for exported function named Init in the DLL and will call it if found after LoadLibrary(..) This allows performing operations which otherwise should not be performed from the DllMain.

The usage is pretty simple: