Captain Hook
Pirating AVs to Bypass
Exploit Mitigations
By
e n S i l o R e s e a r c h Te a mAugust 2016www.ensilo.com

RESEARCH

TA B L E O F C O N T E N T S
Hooking in a Nutshell

3

Under-the-Hood of Inline User-Mode Hooking

4

Injecting the Hook Engine

10

The Security Issues of Hooking

13

3rd party hooking engines

20

Summary

23

About enSilo

25

PAPER

RESEARCH

PAPER

User-mode hooks are used by most of the end-point security vendors today, specifically Anti-Virus (AV)products, and Anti-Exploitation products such as EMET. Beyond their usage in security, hooks are usedin other invasive applications such as Application Performance Management (APM) technologies totrack performance bottlenecks.
Hooking itself is a very intrusive coding
operation where function calls (mainly operating
system functions) are intercepted in order to

Our findings werealter or augment their behavior.

depressing– we revealed
six different security

Given the sensitivity of hooking
implementations, we sought to find theirproblems androbustness. For our research, we investigatedvulnerabilities stemming

about a dozen popular security products. Ourfrom this practice.

findings were depressing – we revealed six
different security problems and vulnerabilities
stemming from this practice.

HOOKING IN A NUTSHELL
The use of hooks allows intrusive software to intercept and monitor sensitive API calls. In particular,
security products use hooking to detect malicious activity. For example, most Anti-Exploitation solutions
monitor memory allocation functions, such as VirtualAlloc and VirtualProtect, in an attempt to detect
vulnerability exploitation.

On the other side of the security spectrum, hooks are also used extensively by malware for various
nefarious purposes, the most popular being Man-In-The-Browser (MITM) attacks.
The most common form of hooking in real-life products, especially security products, is inline hooking.
Inline hooking is performed by overwriting the first few instructions in the hooked function andredirecting it to the hooking function. Although there are other forms of hooking, such as Import
Address Table (IAT)-hooking, this research focuses only on inline hooks.

3/25

RESEARCH

PAPER

Hooking in user-mode is usually implemented within a DLL which is loaded into a process address
space. We refer to this DLL as the “Hooking Engine”.
In this paper we dive into inline user-mode hooking. We also take a deep look into injection techniques,
specifically kernel-to-user injections, since these are usually used to load the hooking engine into theprocess address space. Kernel-to-user injections are not trivial to implement and accordingly, some of
the most severe issues that we found were not in the hooking engine itself but rather in theimplementation of the kernel-to-user injection.

UNDER-THE-HOOD OF INLINE
USER-MODE HOOKING
Although hooking is quite common and there are several common hooking libraries out there, such as
Microsoft Detours, it seems that most security vendors develop their own hooking engines. That said,
apart from a few exceptions, most of these in-house inline hooking implementations are pretty muchsimilar.

INLINE HOOKING ON 32-BIT PROCESSES
Hooking 32-bit functions is straight forward most of the time. The hooking engine disassembles the firstfew instructions of the target function in order to replace it with a 5 byte jmp instruction. After at least 5
bytes of disassembled instructions are found, the hooking engine copies the instructions to a

dynamically allocated code stub and follows with a jmp which returns the code to the original function.
At that stage, the hooking engine overwrites the instructions with a jmp to the actual hooking function.
For example, let's see how a hook on InternetConnectW looks in a windbg:

Figure 1: InternetConnectW before the hook is set (Marked in red are the instructions that will be replaced)

4/25

RESEARCH

Figure 2: After the hook is set

We can see that the jmp instruction leads to 0x178940, which is the hooking function itself.
Disassembling the code at 0x178940 provides:

Figure 3: Disassembled code at 0x178940
This code calls the original InternetConnectW function, leading to:

Figure 4: Original instructions of the function followed by a jmp

As shown, the original instructions of the function are followed by a jmp to the original function.

5/25

PAPER

RESEARCHPAPER

OTHER TECHNIQUESThere are also other ways to achieve function hooking:•

One Byte Patching – This technique is most used by malware. The idea is simple, hooking is
performed by patching the first byte with an illegal instruction (or with an instruction that generates
an exception) and installing an exception handler. Whenever the code executes, an exception will
occur whereas the exception handler will handle it and act as the hooking function.

•

Microsoft Hot-Patching – Hot-Patching was developed by Microsoft to enable patching without theneed to reboot. The patching itself is done through the inline-hooking of the relevant function. To
make things easy, Microsoft decided to keep a 5-bytes’ space between functions and change the first
instruction to a 2-byte NOP, specifically mov edi, edi instructions.

Figure 5: Prior to hot-patching
The patch is done by replacing the 2-byte NOP with a short jmp instruction and replacing the 5-byte gap

with a long jmp. This way the hooking code doesn't need to copy any of the original instructions.

Figure 6: After hot-patching

Hooking Function

6/25

RESEARCHPAPER

P O S S I B L E CO M P L I C AT I O N S
In other 32-bit hooking scenarios, hooking is not that straight forward. For example:•

Relative instructions - If one of the instructions is a relative call/jmp it must be fixed before being
copied.

•Very short functions – If a function is less than 5 bytes it might be hard to patch without overriding
adjacent function.

•

Jmp/Jxx to function's start – If some instruction in the function jumps back to the start of thefunction, the instruction will jump to the middle of the jmp instruction, resulting in a crash. This
scenario is very difficult to solve without the full disassembly of the target function (or through one

byte patch). However, this scenario is extremely rare.
A nice read on possible hooking issues can be found in Binary Hooking Problems by Gil Dabah.

INLINE HOOKING ON 64-BIT PROCESSES
Hooking on 64-bit processes is a bit more difficult than on 32-bit because the address space is muchlarger. This means that 5 bytes jmp instruction might not be enough in order to install a x64 hook since
it is limited to a 2GB range from the its location.
There are several solutions to this problem, some of them are described in Trampolines in X64 by Gil
Dabah.
The most common solution to this issue is to allocate code stub within 2GB range from the hookedfunction and use the following code template:

MOV RAX, <Hooking Function>
JMP RAXFor example, let's take a look at a hook on the 64-bit version of InternetConnectA.

7/25

RESEARCH

Figure 7: The original InternetConnectA function

Figure 8: The function after the hook is set.

As shown, the function jumps to 0x7fefe1ff000.

Figure 9: Disassembling the code in address0x7fefe1ff000

If we follow the hooking function like we did in the 32-bit version we get to the following code stubwhich redirects the execution back to the original function:

Figure 10: 64-bit code stub

8/25

PAPER

RESEARCHPAPER

OTHER TECHNIQUESThere are also other ways to achieve function hooking:•

6-Byte Patching – It is possible to avoid using trampolines by patching 6-bytes instead of 5 bytes,
and making sure that the target is in a 32-bit address space. The idea is simply to use a push-ret
instructions to do the jmp. This is how it looks like:

Figure 11: 6-byte patching•

Double Push (Nikolay Igotti) – One of the problem of the classic techniques is that it trashes therax register. One way to avoid it while still being able to jump anywhere in the address space is bypushing the lower 4-byte of the address into the stack and then copying the high 4-bytes of theaddress into the stack and then returning to that address.

Figure 12: Double-push patching

P O S S I B L E CO M P L I C AT I O N S
Complications in 64-bit hooking are similar to those in 32-bit hooking. However, since 64-bit code

supports an instruction-pointer relative instructions there is a greater chance that the hooking engine
will need to fix Instruction-pointer relative code. For example:

MOV RAX, QWORD [RIP+0x15020]

9/25

RESEARCHPAPERINJECTING THE HOOK ENGINE
Regardless of the way the hooking engine is implemented, a prerequisite for it to do its job is to inject it
into the target process. Most vendors use kernel-to-user DLL injections to perform this. In this section
we cover the most common methods used by security vendors.

Import Injection
This method is quite common and is relatively clean as it doesn’t require any code modifications. As far
as we know this injection technique was never used by malware.

It works by adding an import to the main image. These are the steps for import injection:
1. Register load image callback using

PsSetLoadImageNotifyRoutine andwait for main module to load.
2. After the main module is loaded,
the import table is copied to adifferent location and a new row
that imports the hook engine is
added to the beginning of the table.
The RVA of the import table ismodified to point to the new table.
This is how it looks like in Internet
Explorer:

Figure 13: Internet Explorer patched import table

10/25

RESEARCH

PAPER

This is the new import table:

Figure 14: The new import table

3. When the module completes loading, the RVA of the original import table is restored.

E N T R Y P O I N T PATC H I N G
To the best of our knowledge, this kind of injection method was first used by the infamous Duqumalware and is well documented. It is also used by security vendors.
These are the steps for entrypoint patching:
1. Register load image callback using PsSetLoadImageNotifyRoutine and wait for main module
to load.
2. Read the instructions from the entrypoint and allocate a payload to load the hook engine.
Patch the entry point with a jmp to the payload. This is how entry point patching looks like in Internet

Explorer:

Figure 15: Internet Explorer patched entrypoint

11/25

RESEARCH

PAPER

3. When the payload executes, it first loads the hooking engine and then restores the bytes thatwere copied from the original image.

Figure 16: Restoring the bytes from the original image

User-APC
Kernel-to-user DLL injection using User Mode APC (Asynchronous Procedure Call) is probably the mostdocumented and common method. This method was also extensively used by malware, TDL and ZeroAccess for example.
For detailed information on this injection method we refer the reader to:•

http://www.opening-windows.com/techart_windows_vista_apc_internals2.htm•

http://rsdn.ru/article/baseserv/InjectDll.xml

12/25

RESEARCH

PAPER

This is how it works:
1. Register load image callback using PsSetLoadImageNotifyRoutine and wait for the target
module to load.
2. Once the module is loaded, a payload for loading the hook engine is injected into theprocess and a function that will be called during the startup of the process is patched with a
jmp or push/ret to the payload. On user32.dll the patched function is used is usually
UserClientDllInitialize. On ntdll.dll the patched function is usually LdrLoadDLL. In this case,the push/ret sequence is used to divert execution to the injected payload.

Figure 17: LdrLoadDLL is used for injection
3. Once the payload executes it loads the hook engine and restores the original code in thepatched function.

THE SECURITY ISSUES OF HOOKING
As stated above hooking has many benefits and is extensively used by many security vendors. However,hooking is also a very intrusive operation and implementing it correctly is not a simple matter.
Our research of more than a dozen security products revealed six separate security issues stemmingfrom hooking-related implementations.

1. UNSAFE INJECTION
Severity: Very High
Affected Underlying Systems: All Windows versions
Description: This issue is a result of a bad DLL injection implementation. We have seen two cases ofthis issue which although had the same effect, differed in their technical details.

13/25

RESEARCH

PAPER

Description: This issue is a result of a bad DLL injection implementation. We have seen two cases ofthis issue which although had the same effect, differed in their technical details.
•

LoadLibrary from relative path: In this case, the implementation uses the entrypoint
patching injection method to load its hooking engine. The problem is that the DLL isn’t
loaded using a full path, making injected processes vulnerable to DLL hijacking vulnerability.
An attacker also uses this as a persistence mechanism by placing a malicious DLL in thefolder of the target process.

•Unprotected injected DLL file: In this case, the vendor loads the DLL using a full path but
the DLL is placed in the %appdata%\..\Local\Vendor folder. The problem is that an attacker

could replace the DLL with a malicious DLL thus causing the vendor to load the malicious DLL
into every injected process.
Impact: In both cases, the attacker could use the affected implementation as a way to inject into mostprocesses in system. This is a very convenient way to achieve persistency on the target system.
Exploitability: In both cases, exploitation of this issue is very simple. Although we believe that most
attackers will not use vendor specific persistency mechanisms, security vendors should not weaken the
integrity of the operating system.

2 . P R E D I C TA B L E R W X CO D E S T U B S ( U N I V E R S A L )Severity: Very High
Affected Underlying Systems: All Windows versions
Description: In this case, the implementation uses a constant address - both for 32-bit and 64-bit
processes, to allocate its injection code stub and leaves it as RWX. We have seen this issue only with one
vendor. We decided not to show the exact code stub of the vendor to avoid exploitation of the issue.
Impact: An attacker can leverage this issue as part of the exploitation process by overwriting the codeof the injection code stub with malicious code. Since the code stub also contains addresses of system
functions it also causes the following issues:

14/25

RESEARCH

•

PAPER

Bypassing ASLR: Most of these code stubs contain addresses of important system functions,such as LdrLoadDll, NtProtectVirtualMemory and more. These functions can be very useful aspart of an exploitation process. In the cases we researched, it was also possible to leak theaddress of ntdll.dll.

•

Bypassing Hooks: In cases where the hooks code stubs are allocated at a constant address it
is possible to easily bypass the hook by calling directly to the function prolog. Note that in all
the cases we saw the offsets of the code stubs were at a constant offset.

•

Code Reuse: An attacker can also use the code in these code stubs as part of a code reuseattack. For example, an attacker can build a ROP chain that uses the part of the code which isused for loading the hook engine DLL. Attackers can manipulate the arguments in a way that
their own DLL will be loaded.
All these issues make it possible to easily exploit vulnerabilities that will be otherwise very hard to
exploit.
Exploitability: Past research of ours showed that these kind of issues are significant by weaponizing an
old vulnerability in Adobe Acrobat Reader v.9.3 CVE-2010-0188.
Later that year, on September 22, Tavis Ormandy from ProjectZero wrote a very interesting post,“Kaspersky: Mo Unpackers, Mo Problems.“ about a vulnerability he discovered in Kaspersky that showedthat these threats are real. To exploit the vulnerability he found, Tavis used a second flaw in Kaspersky
which allocated RWX memory in a predictable address. To quote from Tavis’s blog “Kaspersky haveenabled /DYNAMICBASE for all of their modules which should make exploitation unreliable.
Unfortunately, a few implementation flaws prevented it from working properly.”

3 . P R E D I C TA B L E R X CO D E S T U B S ( U N I V E R S A L )Severity: High
Affected Underlying Systems: All Windows versions
Description: This issue usually occurs when the implementation uses a constant address to allocate its
injection code stub. One vendor we researched also uses a constant address to allocate the code stubs
for its hooks.
Impact: Depending on the exact implementation, an attacker can leverage this to bypass ASLR, bypass
Hooks or for code reuse as described in the previous issue (Predictable RWX Code Stubs - System
independent).
15/25

RESEARCH

PAPER

Exploitability: This issue is very simple to exploit. All an attacker has to do is use the information in the
hardcoded address. Moreover, in all the cases that we have seen, the address was constant for both 32bit and 64-bit processes. In most cases, it is also possible to use these code stubs to inject DLL into thetarget process using methods similar to the ones described in a former research of ours, Injection On
Steroids.
Technical Breakdown
Let's see how it looks in a vulnerable hooking engine. In this case, the hooks are set in Internet-Explorer
and always at a constant address. An attacker can simply call 0xXXXX01f8 in order to call

ShellExecuteExW.

4 . P R E D I C TA B L E R W X CO D E S T U B S(ON WINDOWS 7 AND BELOW)
Severity: High
Affected Underlying Systems: Windows 7 and below
Description: This issue is very common and was described thoroughly in our blog post “Vulnerability
Patching: Learning from AVG on Doing it Right”, as well as in a follow-up blog post 6 months later“Sedating the Watchdog: Abusing Security Products to Bypass Mitigations”. In all the cases we haveseen, the issue was caused by the kernel-to-user dll injection and not by the hooking engine itself.
Impact: Similar to the above “Predictable RX Code Stubs (System independent)” issue.
The impact severity is lower here, since not all version of the operating system are affected.
Exploitability: Similar to the above “Predictable RX Code Stubs (System independent)” issue.

16/25

RESEARCH

PAPER

5. RWX HOOK CODE STUBS
Severity: Medium
Affected Underlying Systems: All Windows versions
Description: This is the most common issue in the hooking engines we researched. Most hooking
engines leave their hook code stubs as RWX. We assume that the main reason for this is to avoid
changing the code stub page protection whenever a new hook is set.
Impact: This can potentially be used by an attacker as part of exploitation process by overwriting thecode stubs with malicious code. Overwriting such stubs can make it much easier for an attacker tobypass exploit mitigations such as Windows 10 Control-Flow-Guard (CFG) or Anti-Exploitation hooks.
For example, an attacker that achieved arbitrary read/write in the target process may find the hook stubby following the hook’s code and overwriting it. At that stage, the attacker only needs to trigger the
execution of the hooked function (or even directly call the hook stub) in order to achieve code
execution, effectively bypassing CFG mitigation.
Exploitability: We believe that an attacker that achieved arbitrary read/write will whatever find a way tocomplete the exploit without taking advantage of such an issue. Thus, it is unlikely that an attacker will
actually exploit this issue in a real-life scenario. That said, we believe that security vendors should dotheir best not to weaken system's protections.
Technical Breakdown
Let's see how it looks in a vulnerable hooking engine. In this case, the hook is set on LdrLoadDLL
function:

Figure 18: The hooking engine in windbg

17/25

RESEARCH

PAPER

If we check the permissions on the jmp target we will see that its permissions are RWX:

Figure 19: Permissions on the jmp target

6. RWX HOOKED MODULES:
Severity: Medium
Affected Underlying Systems: All Windows versions
Description: Some hooking engines leave the code of the hooked modules as RWX. This happens bothas part of the initial dll injection code and in the hooking engine code. This issue is not very commonand frankly, the appearance of this issue took us by surprise since we didn’t even look for it given that

we couldn’t think of any good reason for a hooking engine to be implemented this way.
Impact: An attacker can leverage this issue as part of the exploitation process by overwriting the codeof the hooked modules with malicious code, thus simplifying the bypassing of Windows’ mitigations
such as Windows 10 Control-Flow-Guard.
For example, an attacker that achieved arbitrary read/write in the target process may then find thehooked code and overwrite those permissions. At that stage, the attacker only needs to trigger the
execution of the hooked function in order to achieve code execution, effectively bypassing CFG
mitigation.
Exploitability: We believe that an attacker that achieved arbitrary read/write will whatever find a way tocomplete the exploit without taking advantage of such an issue. Thus, it is unlikely that an attacker will
actually exploit this issue in a real-life scenario. That said, we believe that security vendors should dotheir best not to weaken system's protections.

18/25

RESEARCH

PAPER

Technical Breakdown
As an example, we show how the issue appears as part for kernel-to-user mode DLL injection. Here, the
LdrLoadDll is used to inject the hooking engine.

Figure 20: Hooking engine injection using LdrLoadDll in a windbg
As shown, the LdrLoadDLL was patched with a push-ret sequence in order to jump to the code stubwhich is located at 0x78919413. If we let windbg run we can see that the original code was restored:

Figure 21: the original code is restored

However, when we check the permissions we can see that the code is still RWX:

Figure 22: Code permissions were not restored

19/25

WHITEPAPER

3 RD PA R T Y H O O K I N G E N G I N E S
As we showed, implementing a robust hooking engine is not a simple task. For this reason many
vendors choose to buy a commercial hooking engine or just use an open-source engine. Doing so saves
the vendor a lot of development and QA time. It's also clear that the implications of security issues in awide-spread hooking engine are much more serious for the following reasons:•Affects Multiple Vendors – every vendor using the vulnerable engine will also be potentiallyvulnerable.

•

Hard to Patch – Each vendor which uses the affected hooking engine will need to update its
product.

When we started the research we didn’t even look into mature hooking engines since we assumed thatgiven their wide-spread use and massive amount of QA such engines are probably safe. We were
wrong.

EASY-HOOK OPEN-SOURCE HOOKING-ENGINE
EasyHook is as its name suggests, is a simple to use hooking engine with advanced hooking featuresthat supports 32-bit and 64-bit platforms. To mention a few:•

Kernel Hooking support•"Thread Deadlock Barrier" – deals with problems related to hooking of unknown APIs.

•

RIP-relative address relocation for 64-bit•…

However is has two drawbacks when it comes to security:
1. RWX Hooked Modules – EasyHook doesn’t restore the page-protection after the hook is set

on hooked modules.
2. RWX Code Stubs – EasyHook leaves its code stub as RWX. Moreover, when compiled inrelease it uses non-executable heap for its code-stub allocations. In order to make its

20/25

WHITEPAPER

allocations executable, it uses VirtualProtect. The problem with this approach is that the heap
doesn’t guarantee that the code stub will be page-aligned which means that it may inadvertently
convert data to code.

DEVIARE2 OPEN-SOURCE HOOKING-ENGINE
Deviare2 is an open-source hooking engine with a dual-license, GPL for open-source and Commercial
for closed-source, that supports both 32-bit and 64-bit platforms. Like EasyHook it has an extensive listof features:•

Defer Hook – Set a hook only when and if a module is loaded•.NET Function hooking•

Interface for many languages: (C++, VB, Python, C#,…)•…

In Deviare2 we found only a single security issue – RWX Code Stubs. Deviare2 allocates its code using
VirtualAlloc function with PAGE_EXECUTE_READWRITE and leaves it as such. Deviare2 has released apatch with a couple of days from notification.

MADCODEHOOK – COMMERCIAL HOOKING ENGINE
madCodeHook hooking engine a powerful commercial hooking engine by Mathias Rauen that supports
both 32-bit and 64-bit platforms and even support windows 95. It used by many vendors – about 75% of
which are security-related products, for instance, used by Emsisoft anti-virus. To list some of its
features:•

Injection Driver – Used to perform kernel-injection into processes•

IPC API – Used to easily communicate with some main process•

IAT Hooking•…

In madCodeHook engine we also found a single security issue - RWX Code Stubs.

21/25

WHITEPAPER

MICROSOFT DETOURS
Microsoft Detours is the most popular and probably the most mature hooking engine in the world, fromMicrosoft's web site:“Under commercial release for over 10 years, Detours islicensed by over 100 ISVs and used within nearly every
product team at Microsoft.”

As far as we know, its also the only major hooking engine out there that supports ARM processors. It isalso used by many Microsoft own applications, for example Microsoft's Application Virtualization
Technology.
Since a patch was not yet released for Detours, we will not disclose the specifics of the vulnerability. An
updated version of this paper is expected to be released on 15.8.2016.
However, these are the implications:•

Potentially affects millions of users•

Introduces security issues into numerous products, including security products•

Hard to patch since it involved recompilation of affected products

22/25

WHITEPAPER

SUMMARY
Our research encompassed more than a dozen security products. As findings unveiled, we worked
closely with all affected vendors in order to fix the issues we found as fast as possible. Most vendors
responded professionally and in a timely manner.
As shown, some vendors implement their own proprietary hooking code, while others integrate a thirdparty vendor for hooking. Given these third party hooking engines, these issues have become
widespread, affecting security and non-security products.
This pie chart shows a breakdown of the disclosed issues per the number of vendors suffering from theissue:

Figure 23: Breakdown of issue type per number of affected vendor

23/25

RESEARCH

PAPER

Figure 24: Breakdown of issue type per number of affected vendor

Unfortunately, our scope of research was limited given the endless number of products (security andnon-security) that integrate hooking into their technologies. We urge consumers of intrusive products toturn to their vendors, requesting a double check of their hooking engines to ensure that they are awareof these issues and make sure they are addressed.

We urge consumers of intrusive products to turn to theirvendors, requesting a double check of their hooking engines toensure that they are aware of these issues and make sure they
are addressed.

24/25

RESEARCHPAPER

HOW ENSILO WORKS
enSilo prevents the consequences of cyber -performed by an external threat actor, whileattacks, stopping data from being alteredallowing business to go on as usual. As soon as(encrypted), wiped or stolen, while enabling

the platform blocks a malicious communication

legitimate operations to continue

attempt, it sends an alert that contains theunaffected. The solution hones in on and shuts

detailed information that the security team will

down any malicious or unauthorized activity

need for their breach remediation process.

ENSILO BENEFITS

enSilo buys organizations the time and peace of mind they need toprotect and remediate their sensitive information.

www.ensilo.com

company/enSilo

contact@ensilo.com@enSiloSec