KOrUPt

January 15, 2009

Bypassing custom exception handlers

Filed under: Malware analysis, Tips and Tricks — Tags: , , , , , — KOrUPt @ 04:17

There are quite a few reasons as to why we may need to restore the default Structured Exception Handler(which resides within Kernel32). Such a need arises when we may want to stall a foreign process via using an INT3(Breakpoint) instruction so we can attach to the process with our JIT debugger… For more information regarding that subject, see my article here:

If a custom exception handler is in place the default Windows Error Reporting dialog will not be triggered and we wont have the chance to attach to our process using the JIT debugger… This is not what we want.

So, how do we go about restoring the default exception handler?

The default exception handler is always the last handler within the exception chain. A custom exception handler is set up like follows:

push NewHandler  ; address of our new exception handler
mov  eax, FS:[0] ;
push eax         ; address of previous exception handler
mov  FS:[0], ESP ; write the new handler

Assuming this is the first custom exception handler within our chain, the previous handler is in fact the default Kernel32 exception handler. We’ll need the address of this handler should we want to restore it. Note that the address of this handler is version specific.

if we check [EAX + 4] in OllyDbg’s dump window we’ll see the following:

0012FFE0 A8 9A 83 7C

Intel’s x86 architecture uses little endian, so we end up with an address of:

  • 0×7C839AA8

This is the address of our default exception handler. So how do we go about overwriting the custom exception handler?

This task is rather trivial, the following code can do this for us:

mov  eax, fs:[0]
mov  [eax + 4], 0x7C839AA8
int 3 ; throw that exception!

No longer do we have to worry about custom exception handlers wreaking havoc.

It’s worth pointing out that there are various other methods we can use to stall a process, polymorphic breakpoints and the typical JMP -2 tactics are often useful should for some reason a typical INT 3 instruction turn out to be sub-standard.

We’ll, as always I look forward to reading your comments and such. I hope you enjoyed the read.

KOrUPt.

January 14, 2009

Debugging child processes and injectors

Filed under: Malware analysis, Reversing, Tips and Tricks — Tags: , , , , , — KOrUPt @ 14:02

A question I get asked quite often is how to go about debugging a child process or a DLL injector. For a Malware analyst knowing these techniques has become a necessity, given most common day Malware uses the aforementioned methods to aid in achieving their goal and sometimes static analysis just isn’t good enough.

For those curios as to what a DLL file is, I shall refer you to the article on Wikipedia:

  • http://en.wikipedia.org/wiki/Dynamic-link_library

I’m sure at least a few readers have come across Malware that has utilized DLL injection in one way or another, but for those who haven’t, I’ll briefly cover some of the various reasons Malware may use these nefarious techniques… Some use the technique in an attempt to bypass firewalls by executing their own code from within a trusted process and others attempt to subvert certain applications that may be used to detect their presence… The list goes on.

Injecting a DLL into a foreign process has become a rather trivial task these days, even more so given the amount of code laying around the internet.

Most commonly you’ll see an injector using the CreateRemoteThread() API, but it’s worth pointing out that there are some less known methods, such as using the undocumented NtQueueApcThread() routine.

In order for a DLL injector to do its work, it has to know whereabouts the target DLL file is located on the system. You can usually find the path to this DLL by setting a breakpoint on the WriteProcessMemory() API, as this API is typically used to write the location of the DLL into the foreign process’s memory.

IDA is mostly used for static analysis and given we’ll be debugging, I’ll be using OllyDbg, of course you can still use your preferred debugger(WinDbg for instance).

Once we have the path of our DLL, we can open it inside our debugger, you’ll typically see the CRT initialization routines, disassembly of a DLL compiled within MSVC6 using optimizations would look similar to this(main routine):

PUSH    EBP
MOV     EBP, ESP
CMP     [ARG.2], 1
JNZ L011
PUSH    0
PUSH    0
PUSH    0
PUSH    DLL.003F105E
PUSH    0
PUSH    0
CALL CreateThread
L011:
MOV     EAX, 1
POP     EBP
RETN    0C

A new thread is created so the process that has been injected with the DLL doesn’t hang. The first comparison is checking the 2nd parameter of DLLMain() is DLL_PROCESS_ATTACH, which is defined as 1.

Upon checking the threads code, we see the following:

PUSH    EBP
MOV     EBP, ESP
SUB     ESP, 0C
PUSH    DLL.003F505C
PUSH    0
CALL FindWindowA
MOV     [LOCAL.1], EAX
MOV     EAX, [LOCAL.1]
PUSH    EAX
CALL GetMenu
MOV     [LOCAL.2], EAX
CALL CreateMenu
MOV     [LOCAL.3], EAX
PUSH    DLL.003F5070
MOV     ECX, [LOCAL.3]
PUSH    ECX
PUSH    10
MOV     EDX, [LOCAL.2]
PUSH    EDX
CALL AppendMenuA
...

Basically, the DLL is obtaining a handle the process’s window and adding a menu, along with subclassing the window procedure(not visible in the above code). The DLL was injected using the traditional CreateRemoteThread() API.

The Just-In-Time debugger comes in handy here, I’ve configured my JIT debugger to be OllyDbg(which can be done via the options menu of OllyDbg), the idea is to cause the injected process to crash, then attach to the process using the JIT debugger.

We can cause the injected process to crash by throwing an exception, we can cause an exception to be thrown simply by overwriting the function prolog/epilog with an INT3(breakpoint) instruction. For those who don’t know what I mean by prolog, I’m referring to the instructions that set up the functions local stack, those being:

PUSH    EBP
MOV     EBP, ESP
SUB     ESP, 0C

We can overwrite the PUSH EBP instruction with an INT3 instruction and restore the overwritten bytes once attached to the process.

Overwrite the instruction, save the changes and run the DLL injector/Sample, once the DLL has been injected, the target process will hopefully crash and the MS Error Reporting dialog will appear, upon clicking clicking the “Debug” button OllyDbg will launch and attach to the process.

If you’re not currently paused at the INT3 instruction press Alt + F9(pass exception) until you reach it. We can then restore the original instruction, that being “PUSH EBP” and step through the code as normal.

I feel the need to point out that the above steps should only be used within a controlled environment, as some Malware sample’s can be crafty…

For instance, a custom SEH(Structured Exception Handler) may be setup to catch exceptions which means the MS Error Reporting dialog will not appear and the process may execute a fall back routine. We can circumvent custom SEH but I’ll be saving that for another article. For those eager, it mainly involves overwriting the current exception handler with the one used within kernel32.

We can use the same technique described above to debug child process’s.

For Linux users, GDB offers a few useful functionalities to follow child process’s, it can be configured to follow fork()’s and such by issuing the following commands:

  • set follow-fork-mode child
  • set detach-on-fork     on

It can be useful to follow a child process sometimes, as most of the time a certain possibly important routine is only carried out inside the child process.

As for debugging sample’s that use DCI(Direct Code Injection), we can again breakpoint the WriteProcessMemory() API and modify the buffer of instructions that is being written into the target process so it contains an INT3 instruction, after which we can proceed as mentioned previously…

And on that note, I think that just about covers this article.

I look forward to reading any questions and or comments you may have. Let me know of any experiences you have have had whilst debugging such Malware sample’s.

I hope you enjoyed the read.

KOrUPt.

December 21, 2008

Signature Generation

Filed under: Malware analysis, Reversing — Tags: , , , , , , , , — KOrUPt @ 20:47

Note to experienced readers: You may be able to skip the first history lesson and scroll straight to the “Off to work” part of this post.

Firstly, you may ask “What do you mean by ‘Signature Generation’?”. Have you ever wondered how Anti-Virus software does its job when heuristics are turned off? It searches the file in question and looks for references to certain unique sequences of assembly instructions(opcodes). If it finds the designated sequence of bytes(opcodes) it may trigger an alert accordingly.

Secondly, “Why would I want to bother creating a signature?”. There are many reasons why you may want to, if you’re reading this chances are you’ve already got that reason, but I’m going to list a few just for the sake of completeness.

  1. You need to identify a sample that currently has no existing signatures.
  2. You’re passionate about what you do and want to further your knowledge.

Now that Isn’t  a lot of reasons, but keep in mind that reason 1 covers a very wide spectrum, in my case I needed to remove an infection(A Windows PE infecter) that had no existing signatures publicly available. I wanted to automate the disinfection process and thus I needed to identify the sample before I attempted to disinfect an uninfected file…

I hope you can now grasp why(if you didn’t already) understanding the basics of Signature creation can be useful.

Locating packer/protector signatures in malware is usually not a problem when you’ve got such tools as PEiD and RDG Packer Detector along with their corresponding databases lying around your hard-drive… But at times they won’t find anything, the same applies to Anti-Virus software.

Off to work… We need to know where in the file to look for signatures… There are 2 commonly used methods, they are as follows:

  1. With a Windows PE file we may be able to start searching from the executable’s entrypoint.
  2. We can also consider searching from the start of the file(offset 0).

Clearly option 1 should be preferred, as when you’re scanning a file for potentially thousands of signatures, scanning the entire files contents can take quite a while even on fast systems.

My usual path is to start at the entrypoint of the file and look for any static or constant code, it’s a good idea to search around core initialization routines, as if they are changed too much the executable may no longer function.

You can also generate MD5 hashes of common compiler generated entrypoints, you could then consider scanning some of your sample’s to check which  ones have known entrypoints, if you don’t get a match you can bet your executable is packed or protected, should this packer be unknown you can start looking for signatures. If you’ve got a load undetected sample’s lying around it can help to have this process automated for you.

There are various ways to find signatures in PE files, common places and things to check are as follows:

  1. Similarity’s in section names.
  2. Section offsets and sizes.
  3. Bytes around the entrypoint.
  4. Start and end of sections.
  5. Around the Import Table.

Once you have a signature, you can take a collection of infected sample’s, scan them all and hopefully all will match, if so, you can safely say you’ve got a signature that should hopefully be unique to this strain.

Once this is done you should consider adapting the signature so it is compatible with PEiD’s database and such, consider sharing it with the world to save others time in the future… Of course you should make sure you have updated signature files, otherwise you may find you’re working on an already detected sample…

I’ve covered the basic idea behind generating signatures and such, I may provide a case study in the future but I don’t have time at the moment, at 623+ words I think this post is long enough without me going into depth with case studies.

If you have any questions, please leave a comment.

KOrUPt.

Powered by WordPress