Книга: Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software
Назад: Lab 10-1 Solutions
Дальше: Lab 10-3 Solutions

. This is probably another file of malicious code that Lab10-02.exe will use.

Next, we run the program and find that it creates a file and a service. Using procmon, we see that the program creates a file in C:\Windows\System32, and that it creates a service that uses that file as the executable. That file contains the kernel code that will be loaded by the OS.

We should next find the file that the program creates in order to analyze it and determine what the kernel code is doing. However, when we look in .

.

.

that the function being called is NtQueryDirectoryFile. However, if we single-step over the call function, we see that it goes to another section of the file that jumps to NtQueryDirectoryFile. In IDA Pro, this call would have been labeled NtQueryDirectoryFile, but the disassembler included in WinDbg is much less sophisticated. Ideally, we would have the file to view in IDA Pro while we are debugging, but we can’t find this file because it’s hidden.

The PatchFunction checks the eighth parameter, FileInformationClass, and if it is any value other than 3, it returns NtQueryDirectoryFile’s original return value. It also checks the return value from NtQueryDirectoryFile and the value of the ninth parameter, ReturnSingleEntry. PatchFunction is looking for certain parameters. If the parameters don’t meet the criteria, then the functionality is exactly the same as the original NtQueryDirectoryFile. If the parameters do meet the criteria, PatchFunction will change the return value, which is what we’re interested in. To examine what happens during a call to PatchFunction with the correct parameters, we set a breakpoint on PatchFunction.

If we set a breakpoint on PatchFunction, it will break every time the function is called, but we’re interested in only some of the function calls. This is the perfect time to use a conditional breakpoint so that the breakpoint is hit only when the parameters to PatchFunction match our criteria. We set a breakpoint on PatchFunction, but the breakpoint will be hit only if the value of ReturnSingleEntry is 0, as follows:

shows the call to RtlCompareMemory at .

, the first parameter to RtlCompareMemory is eax, which stores the offset at esi+5eh at , which is the offset to a filename. Earlier in our disassembly, we saw that esi was FileInformation, which contains the information filled in by NtQueryDirectoryFile. Examining the documentation for NtQueryDirectoryFile, we see that this is a FILE_BOTH_DIR_INFORMATION structure, and that an offset of 0x5E is where the filename is stored as a wide character string. (We could also use WinDbg to tell us what is stored there.)

To see what is stored at location esi+5eh, we use the db command, as shown in . This reveals that the filename is Installer.h.

shows that the second parameter to RtlCompareMemory stores the letters Mlwx, which reminds us of the driver Mlwx486.sys.

, PatchFunction manipulates this field to hide certain files from the directory listing by moving the shows what the return value of NtQueryDirectoryFile looks like for a directory that contains three files. There is one FILE_BOTH_DIR_INFORMATION structure for each file. Normally, the first structure would point to the second, and the second would point to the third, but the rootkit has modified the structure so that the first structure points to the third, thereby hiding the middle structure. This trick ensures that any files that begin with Mlwx are skipped and hidden from directory listings.

Having identified the program that is hiding files, we can try to obtain the original file used by the driver in order to perform additional analysis. There are several ways to do this:

All of these options are simple enough, but the first is the best because it disables the driver. With the driver disabled, you should first search your system for files beginning with Mlwx in case there are other files being hidden by the Mlwx486.sys driver. (There are none in this case.)

Opening Mlwx486.sys in IDA Pro, we see that it is very small, so we should analyze all of it to make sure that the driver isn’t doing anything else that we’re not aware of. We see that the DriverEntry routine calls RtlInitUnicodeString with KeServiceDescriptorTable and NtQueryDirectoryFile, and then calls MmGetSystemRoutineAddress to find the offsets for those two addresses. It next looks for the entry in the SSDT for NtQueryDirectoryFile and overwrites that entry with the address of the PatchFunction. It doesn’t create a device, and it doesn’t add any function handlers to the driver object.

sss
sss

© RuTLib.com 2015-2018