Sonntag, 4. November 2012

Towards an Anti-Anti-Reversing Framework

Abstract -- TL;DR

  • too many diverse anti-anti-reversing tools (="pro-reversing")
  • idea: create open-source library of pro-reversing techniques
  • compile as DLL and inject it into process to be reversed

Motivation

I really like reversing and really dislike anti-reversing techniques -- unless my objective is to analyze them. So I've decided to think a bit about anti-anti reversing reversing techniques or, as I like to call them: pro-reversing techniques.

Again, I was motivated by my day job. A specimen of malware just did not want to run in a debugged environment. The culprit was a debugger detection code, which roughly looks like this:

call ds:HeapCreate
mov [ebp+hHeap], eax
 

...
 

mov edx, [ebp+hHeap]
mov [ebp+hHeap2], edx
mov eax, [ebp+hHeap2]
mov cl, [eax+8]
mov [ebp+heap_signature], cl
mov edx, [ebp+hHeap2]
mov al, [edx+0Ch]
mov [ebp+heap_flags], al
 

...
 

movzx ecx, [ebp+heap_signature]
cmp ecx, 0FFh
jnz short no_debugger
movzx edx, [ebp+heap_flags]
test edx, edx
jz short no_debugger
jmp debugger_detected
 

no_debugger:
 

; do initialization stuff
 

debugger_detected:
 

...

As you can see, a heap is created and after a bit of shuffling some fields are checked. A very in-depth information about the various heap flags and fields can be found here. In the current malware specimen the fields Signature (offset 0x8) and Flags (offset 0xC) are being checked.Usually, the fields Flags and ForceFlags (offsets 0xC and 0x10, respectively) are checked, as both can be used as debugger check. Probably, again a case of malware authors not properly checking their code ;-)

Too Many Tools, Too Many Plugins

Another thing that annoys me is needing 1,000 plugins for 1,000 tools. If you search for pro-reversing plugins for your favorite debugger, you will be presented lots of choices. Take, for example, OllyDbg. The number of options is overwhelming, you get

  • Anti Anti Hardware Breakpoint
  • Olly Advanced (which is my favorite choice BTW)
  • HideDebugger
  • IsDebuggerPresent
  • aadp4olly 
  • Anti-Anti
  • Robin
  • ...

The list is by far not exhaustive and each plugin may have its own raison d'être. However, the inner workings of most plugins is almost certainly the same, as there's only a couple of frequently used anti-reversing techniques. Hence, the wheel gets reinvented over and over again.

A Solution

So, why this article? The idea is simple: create an open library of pro-reversing techniques (naturally test-driven developed) and put the whole bunch of techniques into a DLL. This DLL can be injected into the process to be analyzed and we can continue using our favorite analysis tools. Hence, you won't need to sift the Internet for other pro-reversing techniques anymore ;-)

 But Why "Towards?"

The title of this article would not contain a "towards" if there was no catch, however. The current version of the framework contains code that is test-driven developed and has been tested under the following OS:
  • Windows XP 32 bit
  • Windows Vista 32 bit
  • Windows Vista 64 bit
  • Windows 7 32 bit
  • Windows 7 64 bit
I left Windows XP 64 bit out on purpose as it is rarely used. If anyone requests it, I might give it a try, though.

Furthermore, the framework contains three pro-reversing techniques working under all of the above environments:
  • PEB BeingDebugged
  • NtGlobalFlags
  • Heap Flags and ForceFlag

We all know (or should know) Peter Ferrie's extensive list of anti-debugging tricks, so implementation is straightforward. He explains everything needed for implementing a pro-reversing technique and I shouldn't be at all surprised if he already implemented each technique...
As my time is restricted, I want to start a small crowd-sourcing project: If you stumble upon code that has anti-reversing properties, you are invited to adding it to the framework yourself or send the sample to me and I will implement the pro-reversing technique. Hence, the framework will grow with each use.

Unit Testing of Pro-Reversing Techniques

As setting up a framework for testing debugger detection is far from trivial, I will present the basic concept in this section. BTW: that's the reason why this article took so long ;-)

First off the easy part: testing the pro-reversing techniques is very easy, as we are presented the testing code in the malware specimens we analyze. Namely, they are the anti-reversing techniques themselves. For example, checking if the BeingDebugged flag is set boils down to a call to the Windows API function IsDebuggerPresent().

Now, we have to implement a basic debugger, as we want to check if a) the anti-reversing technique and b) the pro-reversing technique are correctly working. Luckily, the Windows API makes it very easy to write your own debugger. 

Now that we have a debugger, we also need a "debuggee", a standalone process that executes the anti-reversing and pro-reversing techniques and checks if they succeeded. For that purpose, I created a TCP server that executes a debugger check upon request. During the unit tests, this server is then started under the following environments:
  • without debugger
  • with debugger, but no pro-reversing techniques are enabled
  • with debugger and pro-reversing techniques enabled
  • with debugger and pro-reversing techniques enabled, then disabled
The last test ensures the DLL can be unloaded without any side effects. 

In my repository you can already find the necessary tool to inject a DLL into a new or running process. Furthermore, it offers the opportunity to leave the process suspended after injection in order to facilitate reverse engineering.The ProReverse library can be downloaded here.

Usage

Using the ProReverse library is very easy. Taking the sample mentioned above, there are two opportunities to inject the DLL and debug the process:
  1. Start the process and inject the DLL at the beginning, then attach the debugger. Invoke

    DllInjector.exe --run malware.exe --dll c:\absolute\path\to\ProReverse.dll -s
    

    and then attach your favorite debugger and continue the process.

  2. Start the process in a debugger and inject the DLL afterwards. Start your debugger, load malware.exe and pause it anywhere you want. Then invoke

    DllInjector.exe --pid 1234 --dll c:\absolute\path\to\ProReverse.dll
    

    1234 is the PID of malware.exe. In OllyDbg, I noticed that the injection thread would not directly execute.
    In order to overcome this problem, I simply changed the instructions at EIP of the malware to an endless loop (in memory view, go to EIP and enter EB FE), then continued the process. Instantly, the DLL was being loaded and I could change the bytes to the original ones, continuing reverse engineering the malware.
    Maybe, I will write a DLL injection plugin just for OllyDbg ;-)
Note: The path of the DLL doesn't have necessarily to be absolute, but under normal circumstances the DLL will not be in the same working directory as the malware to be analyzed.