Threat Research Blog

How Advanced Malware Bypasses Process Monitoring

One of the primary aims of an anti-virus (AV) engine is to monitor all process activity—while malware, on the other hand, wants to avoid detection by AV. The philosophy of most rootkits is to run silent and deep, which also aligns with the goals of advanced malware as it evades detection by most enterprise class host-based security solutions (HBSS) and AV.

So how does malware evade detection when starting new rogue processes? Easy—it directly attacks the operating system’s kernel. Microsoft provides the kernel routine PsSetCreateProcessNotifyRoutine to allow security software to monitor process creation and termination events in the Windows kernel, and security software calls the PsSetCreateProcessNotifyRoutine in order to be notified by the kernel when these events occur. These security solutions will then act on process creation and termination events in order to track system activity and protect critical resources.

The Windows OS internally maintains an array of callback objects with the starting address of PspCreateProcessNotifyRoutine. A maximum of eight callbacks may be registered on Windows XP SP2. Unfortunately for developers outside of Redmond, this internal pointer of the initial routine is not exported, and there is no publicly disclosed method for third-party applications to easily register for these notifications.

Unsurprisingly, we have discovered malware that uses this implementation by accessing the PspCreateProcessNotifyRoutine (internal pointer) in order to remove all registered callbacks. Once the malware has removed the AV security suite callbacks, it is free to create and terminate processes at will without any pesky security software interference. Let’s take a closer look at how this works.

Bypassing Procses Monitoring

Figure 1. PsSetCreateProcessNotifyRoutine ntoskrnl.exe

The first step is to find the internal pointer PspCreateProcessNotifyRoutine. A quick review of the implementation of PsSetCreateProcessNotifyRoutine in the Windows ntoskrnl.exe with IDA Pro reveals that the offset is contained within the x86 assembly of this routine (see Figure 1 above). Figure 2 below shows the reverse-engineered malware sample and demonstrates how its authors have reverse-engineered the implementation of PsSetCreateProcessNotifyRoutine in the Windows ntoskrnl.exe, using this knowledge to then craft an attack.


Figure 2. Retrieval of the Psp CreateProcessNotifyRoutine

The actual implementation of this attack is simple (see Figure 2). First, the malware must determine the Windows build number, which is the exported value NtBuildNumber. For XP, the build number is 2600 (0a28 in hexadecimal). The next step is to get the runtime address to the PsSetCreateProcessNotifyRoutine routine.

The jmp__PsSetCreateProcessNotifyRoutine assembly code fragment has a jmp to the external PsSetCreateProcessNotifyRoutine routine. As shown in Figure 3, the jmp op-code is 2-byte. Thus, the jmp__PsSetCreateProcessNotifyRoutine+2 value will get us the address to the PsSetCreateProcessNotifyRoutine routine in memory.

The op-code 0xBF is ‘mov edi,’ and the op-code 0x57 is the ‘push edi’ on NtBuildNumber 2600. Now, all we need to do is linearly scan the machine code for 0xBF followed by 0x57 five bytes later. Immediately following the op-code 0xBF in memory is the PspCreateProcessNotifyRoutine address. And that’s it. The rest of this exploit is trivial. Just walk the PspCreateProcessNotifyRoutine pointer and NULL out all callback objects.


Figure 3. jmp__PsSetCreateProcessNotifyRoutine

Bottom line: Any enterprise or consumer security suite that uses this technique for monitoring process activity can be easily circumvented—a big win for the malware authors. Fortunately, all FireEye products are not vulnerable to this tactic, as malware process activity will still be tracked and identified correctly, even after this tactic is used.

This post was written by Michael Vincent and Abhishek Singh.