A newly discovered hooking technique can go completely undetected by the current implementation of PatchGuard, CyberArk security researchers warn.
Called BoundHook, the method relies on causing an exception in a very specific location in a user-mode context, as well as on catching that exception to gain control over the thread execution. It can bypass PatchGuard, or Kernel Patch Protection, which was designed by Microsoft to prevent malicious code from running at kernel level on 64-bit versions of Windows.
Hooking is known to provide control over the operating system or applications, and both legitimate and malicious programs can leverage it. The newly discovered method can be used in post-exploitation scenarios where the attacker has already established control over the system.
BoundHook uses the BOUND instruction, which is part of Intel MPX (Memory Protection Extensions) and which was designed to increase software security by checking pointer references susceptible to malicious exploitation at runtime due to memory corruption vulnerabilities.
Because Intel designed it to generate a fault to allow examination of the bound check failure, the BOUND instruction “checks an array index against bounds and raises software interrupt 5 if the test fails,” CyberArk explains. When a bound fault occurs, registered bounds-exception callback routines are executed.
Kernel-mode drivers and shellcode payloads running in kernel-mode are able to register callback routines for bound faults. With no parameters, such a callback routine should return a BOUND_CALLBACK_STATUS.
The researchers also explain that, after the bound fault registration, the kernel-mode code gets a pointer to the user-mode DLL base address. Then it obtains the address of the function to hook, after which it attempts to start writing to that address.
To perform this operation as stealthily as possible and avoid triggering the COW (copy-on-write) protection, one could either manipulate the CR0 register or allocate their “own memory descriptor list (MDL) to describe the memory pages and adjust permissions on the MDL”. The latter method, CyberArk says, is stealthier and “completely invisible by design to the current PatchGuard implementation.”
The security researchers also explain that, writing directly to a DLL’s COW page allows them to hook every process on the system that uses the specific DLL. By setting the kernel-mode code performing the hooking to write the code to a function’s prologue, the researchers’ kernel-mode callback function could take control of the thread when user-mode thread called that function.
Because the hooked page will still be COW, the performed modifications won’t be visible to anti-malware solutions, especially with most anti-virus makers unaware of the new method. Furthermore, user-mode debuggers can’t catch the hook, because “BoundHook’s method traps the execution flow by the kernel bound faults handler.”
“This method is invisible to most PatchGuard (PG) protection mechanisms. The MDL approach to bypass the COW mechanism is not detectable by PG today by design. As for the CR0 modification approach, although the CR0 is protected by PG, since it is modified for a very short period of time, the chance of being caught by PG is minimal,” the security researchers argue.
CyberArk says that BoundHook does not meet Microsoft’s requirements to be considered a security vulnerability, given that machine administrator rights need to be obtained for this method to work.
The researchers were in a similar situation earlier this year, when they disclosed GhostHook, an attack targeting Windows 10’s PatchGuard and able to bypass it and hook a malicious kernel code (rootkit). At the time, Microsoft revealed that the issue, although not a security vulnerability, may be addressed in a future version of Windows.