• Aucun résultat trouvé

Technique: Filter/Layered Drivers

Dans le document Michael A. Davis (Page 179-183)

Klog installs a keyboard filter driver to intercept keyboard IRPs as keys are pressed.

Whenever a key is pressed, a scan code is sent from the keyboard to the operating system port driver, i8042prt.sys, and then to the class driver, kbdclass.sys. A rootkit could install a port filter driver just above i8042prt.sys or a higher-level filter driver above kbdclass.

sys. Klog chooses to use the latter.

Now we must elaborate on the life of a typical IRP in this device stack. You may be asking, How does the operating system know when a key is pressed? The process begins with the I/O Manager sending an empty IRP to the lowest-level driver, where it is queued until a key is pressed. When this happens, that driver fills the IRP with all the necessary parameters to inform the drivers in the keyboard device stack of the operation—including the IRP major function code and the scan code data.

Recall from the discussion in “Kernel-Mode Driver Architecture” that the purpose of an IRP is defined inside the major function field of the data structure. These functions include create, cleanup, read, and write. Thus, other IRPs are sent during the entire process. Because you are logging keystrokes, however, all you’re interested in is “read”

IRPs, because these correspond to a scan code being read (from which you can derive a keypress). All other IRPs must be simply passed on to the next driver in the device chain.

When the empty IRPs are being passed down the device stack, you “label” the ones you care about by defining which type of IRP you want a specific routine to handle when the IRP is being sent back up the device chain (after a key is pressed). This function is called a completion routine. Since you only care about “read” IRPs, you’ll provide the address of the function you want to be called when the IRP has been populated and sent back up the device chain.

Now that we’ve covered how Klog positions itself in the operating system to intercept keystrokes, let’s see it in action. First it’s worth noting that Klog is a proof-of-concept rootkit that does not attempt to load or hide itself. For this reason, many other rootkits in the wild have simply used the freely available Klog source code as a basis for a more advanced rootkit.

To load the Klog rootkit driver, klog.sys, we’ll use a small graphical utility called InstDrv. This free utility loads/unloads drivers by starting or stopping a temporary service created by the Service Control Manager (SCM). Figure 4-3 demonstrates using this utility to create a service for the Klog driver and loading it into kernel mode using the SCM.

Klog writes a log file containing the captured keystrokes to C:\Klog.txt. Figure 4-4 shows this log file growing to 1KB after a few words are typed into the Notepad application.

If you want to see the contents of the log file, you have to first stop the Klog service using InstDrv. Otherwise, Windows will alert you that the file is currently in use by another process. This process is actually a kernel-mode system worker thread that Klog initialized to handle the actual logging. By stopping the service and unloading the klog.

sys driver, the driver’s Unload() routine gets called, which as you can see in the source code, terminates this worker thread.

An interesting problem arises when you try to unload the driver using InstDrv. When you click the Stop button in InstDrv, the utility asks the SCM to stop the Klog service and

Figure 4-3 Loading the Klog rootkit driver using InstDrv

unload the driver. There is a problem, though, and it’s directly related to the “life of an IRP” discussion earlier in this section.

Recall that an empty IRP is created to wait for keypresses, and that IRP was labeled so the I/O Manager would send the IRP when it’s been filled with a scan code. This means the IRP is in a pendingstatus until the user has pressed a key. A critical rule in the kernel driver world is a driver cannot be unloaded if it is registered to process IRPs that are still pending. If the driver unloads anyway, the system will blue screen. This is a safety mechanism implemented by the OS, because the pointer to the read completion routine that is contained in the pending IRP has now become invalid. When a key is pressed and

Figure 4-4 Klog log fi le size grows as keystrokes are captured.

the IRP is sent up the device stack, it will encounter the address to the function, which is invalid, causing an access violation. Thus, the chain is broken.

So, what happens when you click the Stop button in InstDrv? Luckily, the SCM will realize the situation and mark the service as pending unload, while it waits for the IRP to complete. You will notice the system becomes sluggish; however, as soon as a key is pressed, the system returns to normal and the driver is unloaded. This is because the IRP went from pendingto active, our function processed the resulting IRP, and then the SCM terminated the Klog service and unloaded the driver.

This peculiarity is something to keep in mind when considering the side effects that kernel-mode rootkits can exhibit: frequent and unexplained blue screens may indicate a faulty rootkit.

Using OSR’s DeviceTree utility, you can see that the rootkit device is hooked into the device chain for kbdclass.sys, the operating system’s keyboard class driver. In Figure 4-5,

Figure 4-5 DeviceTree shows the rootkit attached to the keyboard class driver.

Klog’s device that is attached to the keyboard device stack for KeyboardClass0 is highlighted in green. KeyboardClass0 is the name of the device exposed by kbdclass.

sys, and this device is what all higher-level keyboard drivers will attach their own device object to (Klog’s device object is named \Driver\klog).

Again, this rootkit makes no attempt to hide itself. A stealthy rootkit would either attach in a different manner (such as hooking a keyboard driver’s IRP-handling function) or hide the artifacts that allow you to detect its actions. These artifacts include registry entries, driver-specific structures in memory (such as DRIVER_OBJECT and DEVICE_

OBJECT), and the named device object \Driver\klog.

Dans le document Michael A. Davis (Page 179-183)

Documents relatifs