Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1400802
  • 博文数量: 416
  • 博客积分: 13005
  • 博客等级: 上将
  • 技术积分: 3297
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 16:26
文章分类

全部博文(416)

文章存档

2014年(1)

2013年(4)

2012年(46)

2011年(64)

2010年(12)

2009年(4)

2008年(40)

2007年(187)

2006年(58)

分类: 网络与安全

2011-08-17 16:00:42

http://resources.infosecinstitute.com/zeroaccess-malware-part-3-the-device-driver-process-injection-rootkit/
ZeroAccess Malware Part 3: The Device Driver Process Injection Rootkit



Part 2: Reverse Engineering the Kernel-Mode Device Driver Stealth Rootkit
Part 3: the Kernel-Mode Device Driver Process Injection Rootkit

Let’s now take a look at the second driver dropped by the agent. This driver allows for ZeroAccess to inject arbitrary code into the process space of other processes. Here are the hashes of this driver:

  • FileSize: 8.00 KB (8192 bytes)
  • MD5: 799CFC0F0F028789201A0B86F06DE38F
  • SHA-1: 1023B17201063E72D41746EFF8D9447ECF109736
  • No VersionInfo Available.
  • No Resources Available.

As with the first driver, in this case we see the presence of debugging symbols upon disassembly, here is a view of the call graph:

DriverEntry() essentially installs a callback. This causes the graph to misrepresent the true code execution flow, due to the fact that a NotifyRoutine represenst an indirect calling system. Keep in mind that we have a piece of code actually present that’s not visible. Lets disassemble the first code block:

PsSetLoadImageNotifyRoutine registers a driver-supplied callback that is subsequently notified whenever an image is loaded for execution.

NTSTATUS PsSetLoadImageNotifyRoutine( IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine );

Parameters

NotifyRoutine

Specifies the entry point of the caller-supplied load-image callback.

After such a driver’s callback has been registered, the system calls its load-image notify routine whenever an executable image is mapped into virtual memory. This occurs whether in kernel space or user space, and before the execution of the image begins.

To be able to correctly analyze this callback we need to know the prototype of a generic NotifyRoutine:

VOID

(*PLOAD_IMAGE_NOTIFY_ROUTINE) (

IN PUNICODE_STRING FullImageName,

IN HANDLE ProcessId, // where image is mapped

IN PIMAGE_INFO ImageInfo

);

The_IMAGE_INFO struct contains information about the loaded image.

This is an interesting piece of code, here we have an APC (Asynchronous Procedure Call) routine. An APC found in a rootkit is usually used to inject malicious code into victim processes.

The APC allows user programs and system components to execute code in the context of a particular thread and, therefore, within the address space of a particular process. We have two possible cases of APC usage: user-mode based (which will work if thread is placed in alertable status) and kernel-mode ones that can be of two types, regular or special.

In our case, since we are in a device driver, the APC is managed by using KeInitializeApc() and KeInsertQueueApc() functions.

NTKERNELAPI

VOID

KeInitializeApc (

IN PRKAPC Apc,

IN PKTHREAD Thread,

IN KAPC_ENVIRONMENT Environment,

IN PKKERNEL_ROUTINE KernelRoutine,

IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,

IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,

IN KPROCESSOR_MODE ApcMode,

IN PVOID NormalContext

);

And

BOOLEAN
KeInsertQueueApc(
PKAPC Apc,
PVOID SystemArgument1,
PVOID SystemArgument2,

UCHAR mode);

The APC mechanism is poorly documented and kernel APIs to use them are not public (no prototype presence in the DDK) so here we will give some more in depth explaination to well clarify how APC works.

KeInitializeApc: As the name suggests, this function is used to initialize an APC Object, from function parameters you can see that we have a KAPC struct easly uncoverable by using the method seen at beginning of the post:

kd> dt nt!_KAPC

+0×000 Type : UChar

+0×001 SpareByte0 : UChar

+0×002 Size : UChar

+0×003 SpareByte1 : UChar

+0×004 SpareLong0 : Uint4B

+0×008 Thread : Ptr32 _KTHREAD

+0x00c ApcListEntry : _LIST_ENTRY

+0×014 KernelRoutine : Ptr32

+0×018 RundownRoutine : Ptr32

+0x01c NormalRoutine : Ptr32

+0×020 NormalContext : Ptr32 Void

+0×024 SystemArgument1 : Ptr32 Void

+0×028 SystemArgument2 : Ptr32 Void

+0x02c ApcStateIndex : Char

+0x02d ApcMode : Char

+0x02e Inserted : Uchar

By watching successive function parameters you can see that the essential scope of this function is to initialize KAPC struct.

Calling KeInitializeApc does not schedule the APC yet: it just fills the members of the _KAPC, sets the Type field to a constant value (0×12) which identifies this structure as a _KAPC and the Size field to 0×30. Take a look into the ZeroAccess rootkit code ExAllocatePool, it is exactly 0×30, and is the first parameter.The KernelRoutine parameter is a pointer to a routine that will be called once APC is dispatched. NormalRoutine considered in combination with ApcMode will tell us what kind of APC is requested, so let’s take a look to rootkit code:

100010E1 mov eax, [ebp+ImageInfo]
100010E7 push dword ptr [eax+4]

This means that NormalRoutine is non-zero in combination with ApcMode which is 1. We can correctly say that this is a user mode APC, which will therefore call the NormalRoutine in user mode.
Rundown Routine: This routine must reside in kernel memory and is only called when the system needs to discard the contents of the APC queues, such as when the thread exits.

Once the APC object is completely initialized, device drivers call KeInsertQueueApc to place the APC Object in the target thread’s corresponding APC Queue.

Further details about APC Internals can be found

Now let’s study what happens in KernelRoutine:

Initially we have an IRQL Synchronization. KeGetCurrentIrql returns a KIRQL that contains the actual IRQL in which is running the current thread. Next via KfLowerIrql, we see a move to the new IRQL.ZwAllocateVirtualMemory commits and reserves a region of pages within user-mode virtual address space of the specified process. Let’s take a look at the next code block:

If allocation fails, execution jumps to IRQL Restore Routine ( via KfRaiseIrql ) and then exits. Otherwise we have a memcpy that copies 0×180 bytes from sub_10001338 to allocated memory. Note that space is allocated with PAGE_EXECUTE_READWRITE protection, meaning that the call copied by memcpy can be executed.

Due to the fact that this memory commit has EXECUTE rights we need to analyze the block of data as if it were a block of code, because it will be executed once placed into the address space of another process. Once reached via xRefs we have to force conversion from data to code. Moving forward:

Our assumptions were correct, as you can see this is a piece of executable code. We also at 1000134E a subtle trick to prevent reverse engineering and static analysis, more opcode scission.

Now let’s move our point of view from code to hex dump:

As you can see from hex dump, after the starting code (in green) we have a a string marked by red rectangle, we have already seen this string, behavior is now clear. This device driver injects the malicious DLL max++.00.x86 into victim process address space.

Next step is logically to discover what this dll does.

__The Weakness__

While this driver is made to be very stealthy, we can apply some forensic techniques to discover a weakness in the stealth technology employed by this driver. The main weakness of this driver is given by PsSetLoadImageNotifyRoutine. It essentially registers a Callback via ExAllocateCallBack, a mechanism that is very transparent and easy to find. Existing callbacks can be reveled by scanning all slots that hosts PEX_CALLBACK_FUNCTION type. To inspect these Slots we can use again KernelDetective.

ImageLoad registered Callback of an Unknown Module as should be clear, is really suspect, this is a strong evidence of rootkit infection.

Next up, in part 4 we can

Incoming search terms:
Share and Enjoy:
  • Twitter
  • Digg
  • del.icio.us
  • Facebook
  • Print
Comments (7)
  1. [...] Articles by giuseppeZeroAccess Malware Part 3: The Device Driver Process Injection RootkitStep-by-Step Reverse Engineering Malware: ZeroAccess / Max++ / Smiscer Crimeware [...]

  2. said on November 15, 2010

    [...] Articles by giuseppeZeroAccess Malware Part 3: The Device Driver Process Injection RootkitZeroAccess Malware Part 2: The Kernel-Mode Device Driver Stealth [...]

  3. said on November 15, 2010

    [...] Articles by giuseppeZeroAccess Malware Part 3: The Device Driver Process Injection RootkitZeroAccess Malware Part 2: The Kernel-Mode Device Driver Stealth RootkitStep-by-Step Reverse [...]

  4. said on November 16, 2010

    Please don’t post this message because I am not a tech person and this may sound stupid. I am just a girl with a very sick Mac that has gotten no help from Apple but fighting what may be something like what you have here. Honestly though I don’t understand 90% of it, I just see the patterns. If I am right then maybe this will help, if I am way off just ignore me (I am starting to wonder if I may just be crazy) When reinstalling my laptop 2 days ago I was having some issues which made me look around a bit with the system disk tools after the disk was erased. I don’t remember the name but it is the little program that tells you about the system and what drivers are on it preinstalled. Under one of the lower left hand links there were 3 logs/files that I think one of them may hold all of the (Stacks?) commands it is a large file (around 400 mb I think). I don’t remember which one, but I wrote down all 3(sorry they are hand written so I am not sure if they should have Caps or extra spaces), usr/bin/pmset -glog usr/sbin/ioreg -lxw400 & usr/sbin/NVRAM -xp

    Hope you can look at the file names and know if this is a false alarm from someone without a real clue (prior analyst – data not computers) I may just be seeing things.

  5. said on November 22, 2010

    @C
    Don’t stress – the root kit in this article only affects Windoof *not* OSX.
    The command you posted is an innocuous power-management and non-volatile RAM setting. You’re not seeing things – just misinterpreting :-)

  6. [...] I was recently asked a question in relation to this article http://resources.infosecinstitute.com/zeroaccess-malware-part-3-the-device-driver-process-injection-... [...]

  7. said on January 17, 2011

    Significantly, the article is de facto the freshest on this worthy topic. I agree with your conclusions and undoubtedly will thirstily stay up for your forthcoming updates. Saying thanks will certainly not merely be sufficient, for the large lucidity in your writing. I can straight grab your rss feed to stay privy of any type of updates. Pleasant work and far success in your enterprise endeavors!

Leave a Reply

XHTML: You can use these tags:

Name (required)

Mail (will not be published) (required)

Website


阅读(2296) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~