Friday, March 2, 2012

Malware Analysis Tutorial 19: Anatomy of Infected Driver

Learning Goals:
  1. Perform binary comparison of files
  2. Practice debugging techniques
  3. Understand executable file header format
Applicable to:
  1. Operating Systems
  2. Assembly Language
  3. Operating System Security
1. Introduction
We now continue our analysis presented in Tutorials 17 and 18. This time, we are interested in looking at the infected driver and compare it with the clean state of the same driver. For this purpose, we need to perform some "surgery" to the malware and the operating system to retrieve the two versions of the driver. Recall that, the malware infects a driver randomly, and we have to be cautious during the process.

We will intercept the running of Max++ at two critical points:
(1) right after Max++ randomly picks up the driver name. At this point, we will copy the clean version of the driver from the system.
(2) right before Max++ calls zwLoadDriver() to load the infected driver. We will copy the infected version of the driver from the OS.

Then we could easily do a binary comparison of the two versions of the drivers. We will use a handy tool called WinDiff. Please follow the lab configuration below to take out the two drivers.

2. Lab Configuration (Retrieve BIN files of Drivers)
(*) Download WinDiff and have it installed.

(0) Start WinXP image in DEBUGGED mode. Now in your host system, start a windows command window and CD to "c:\Program Files\Debugging Tools for Windows (x86)" (where WinDBG is installed). Type "windbg -b -k com:pipe,port=\\.\pipe\com_12" (check the com port number in your VBox instance set up). When WinDbg initiates, types "g" (go) twice to let it continue.

(1) Now launch IMM in the WinXP instance, clear all breakpoints and hardware breakpoints in IMM (see View->Breakpoints and View->Hardware Breakpoints).

(2) Go to 0x4012DC and set a hardware breakpoint there. (why not software bp? Because that region will be self-extracted and overwritten and the software BP will be lost). Pay special attention that once you go to 0x4012DC, directly right click on the line to set hardware BP (currently it's gibberish code).

(3) PressF9 several times run to 0x4012DC. You will encounter several breakpoints before 0x4012DC. If you pay attention, they are actually caused by the int 2d tricks (explained in Tutorial 3 and 4, and 5). Simply ignore them and continue (using F9) until you hit 0x4012DC.

Figure 1 shows the code that you should be able to see. As you can see, this is right before the call of RtlAddVectoredException, where hardware BP is set to break the LdrLoadDll call (see Tutorial 11 for details).
Figure 1: code at 0x4012DC
(4) Now scroll down about 2 pages and set a SOFTWARE BREAKPOINT at 0x401417. This is right after the call of LdrLoadDll("lz32.dll"), where Max++ finishes the loading of lz32.dll. Then hit SHIFT+F9 several times until you reach 0x401417 (you will hit 0x7C90D500 twice, this is somwhere inside ntdll.zwMapViewSection which is being called by LdrLoadDll).



Figure 2: code at 0x401407

(6) Now we will set a breakpoint at 0x3C1E77  .  Goto 0x3C1E77  and set a SOFTWARE BREAKPOINT. SHIFT+F9 there. Press SHIFT+F9 to run to 0x3C1E77  . (You may see a warning that this is out range of the code segment, simply ignore the warning).

(Figure 3 shows the code that you should be able to see at 0x3C1E77  . This is right after the loop for randomly picking up a system module to infect. As shown in the image, this time, the driver to infect is "afd.sys".

*** Now copy afd.sys from c:\Windows\System32\Drivers to your desktop and rename it as afd_v1.sys

Figure 3. Randomly Pick File Name

(7) Now we will set a breakpoint at 0x3C1B3E. (as shown in Figure 4) This is right before the zwLoadDriver is called to cause the harm to the system.

*** Now go to c:\Windows\System32\Drivers again and copy afd.sys out as afd_v2.sys. Up to now, our job of retrieving files is done. We can terminate the IMM debugger.
Figure 4. Take out Infected Driver

 3. Comparison of the Clean and Infected File
Figure 5 shows the comparison of the clean and infected driver file using WinDiff. Let's take a look. On the left side of the image, you might notice two color bars, one corresponding to afd_v1.sys and the other corresponding to afd_v2.sys. The first fact you might notice is that afd_v2.sys is a bit larger.

The first difference between the two files is line 1 (this is because the number of bytes and total blocks of the file has to be changed when Max++ injects additional logic),
Figure 5: WinDiff of Clean and Infected Driver
The second difference is the part (note region 2) from line 2 to line 28. Max++ injects (actually inserts) a lot of information. The red bar corresponds to the original content and the yellow bar corresponds to the new and inserted code. If you take a look at the highlighted region 4 (on the right of Figure 5) you might find a lot of interesting information:
(1) There is a HTTP request for /install/setup.php
(2) There is a string "C2CAD972#4079..." - this is the name of the hidden disk drive

The rest of the two files is interesting. If you notice the rest of the two bars, the contents are exactly the same (note the highlighted region #2 on the left). This shows that Max++ did a good job at retaining the original logic of afd.sys. What it does is to insert the additional logic at the beginning and properly rewires the control flow so that after its malicoius actions are performed, the driver will perform its original functionality.

In Figure 7, we display the disassembly of afd_v2.sys. You can see that it is performing some actions related to HTTP request and hidden disk drive. Notice that if you try to load afd_v2.sys using the Immunity Debugger directly, the IMM would simply crash. You need to actually debug IMM and overwrite some of its machine instructions to make it work when memory segmentation fault occurs.

In fact, since we are about to get to kernel debugging (for drivers), IMM is not quite appropriate for such cases. In the next tutorial, we will show you how to use WinDbg to perform the analysis.

Figure 7. Disassembly of afd_v2.sys


Challenge of the Day: 
(1) what is the size of the injected code?
(2) Can you identify where does starts and where it ends inside Max++, right before it is written to the drier file?

No comments:

Post a Comment