Thursday 9 December 2010

Pulling the digital rug out from under the malware's feet

Usermode processes are limited in terms of what they can do by the API platform provided by the OS and the non-privileged instructions that they can execute. This means they have to abide by certain rules and regulations put in place to protect system integrity and security. Usermode processes cannot directly communicate with the BIOS or peripheral hardware, nor kernel objects - they must talk to them via drivers and other kernel-mode code. The model of communication roughly looks like this:

Process <-> Service <-> Driver <-> Kernel

The service is not a traditional Windows service that runs as a process - it's a service representing the kernel mode driver (KMD) that sits in the kernel layer. The process communicates with the service using DeviceIoControl and other associated APIs. The service acts as a bridge between user- and kernel-space. The driver then interacts with system APIs, structures and mechanisms in order to perform its tasks. In the case of a hardware driver, the driver uses objects that are provided by the Hardware Abstraction Layer (HAL). The HAL acts as the bridge between software by providing software access to physical device memory. For example, the HAL might inform a KMD the address at which the memory for a graphics card's display buffer is mapped in virtual memory.

The model of isolated kernel- and user-mode is convenient because it alleviates the need for software developers to implement their own low level mechanisms such as spinlocks and memory isolation. It also allows the system much greater control over how everything is running and therefore massively improves stability and security. In a system that doesn't distinguish between user and kernel memory, a process could write over important kernel code or data. This could either be because the process is malicious, or it has a bug. In systems like that, a crashing process often crashes the whole system.

If you put all of this in the context of malware, it's like having a virtual machine running with the malware process in it. To put it bluntly: you can trash the crap out of user memory, but kernel memory remains intact. This means in the case of disaster (e.g. a critical system service such as lsass.exe dies) the kernel can finish important tasks before throwing a bugcheck and halting the system to prevent further damage.

What makes a great weapon in the fight against malware is a KMD-based anti-malware solution. The kernel can in fact hide critical anti-malware processes and hook important calls (e.g. VirtualProtectEx, WriteProcessMemory, etc) to make sure that the anti-malware processes stay intact. It can also access any user object (process, thread, memory, file, etc) regardless of its user-level protection. It's like having the ability to walk through walls. As the title of this post said, you can pull the digital rug out from under the malware's feet without it being able to stop you.

One important thing anti-malware solutions need to do is monitor the execution of processes. In a KMD it is possible to register a callback function that is called whenever a new process is created. This can be achieved in Windows with the PsSetCreateProcessNotifyRoutine system API. The same thing can be done for threads with PsSetCreateThreadNotifyRoutine. You simply pass it a pointer to a callback function and that function gets called whenever a new process is created. Of course it might be more prudent to hook an API responsible for loading executable binaries using the System Service Dispatch Table (SSDT) so that you can check the executable file for known malware before allowing the creation of the process to continue.

What we must remember is that whilst a malware KMD could technically be loaded and attack our kernel-mode code. Whilst this is somewhat unlikely, it is still a scenario that could occur. There's not much we can do about this. At the point when malware infects the kernel, the system can (pretty much) be considered irreparably comprimised.

For now this post is simply a conglomeration of my personal knowledge and a great deal of research. I am currently considering whether it would be feasible to introduce a KMD into my project.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.