CVE-2020-14418: madCodeHook Library Local Privilege Escalation

Nettitude discovered a vulnerability in the ‘madCodeHook’ third party library which caused a number of security products, including Cisco AMP and Morphisec Unified Threat Prevention Platform, to contain a local privilege escalation vulnerability. Since the vulnerability originated in a third party library, it is likely to affect other software using that library. The madCodeHook author states that at least 15 security vendors use the library.

Following a coordinated disclosure process driven by Nettitude, the latest versions of Cisco AMP and Morphisec Unified Threat Prevention Platform are no longer vulnerable to this issue. Other software that uses madCodeHook may still be vulnerable.

Products Affected

All software using the madCodeHook library has a kernel mode DLL injection vulnerability in versions prior to v4.1.3. This includes, but is likely not limited to, the following software:

  • Cisco AMP prior to v7.2.13:
    • ExPrevDriver.sys
  • Morphisec Unified Threat Prevention Platform v4.x earlier than v4.1.2, v3.5.9:
    • MorphiDriver.sys


There is a design flaw inside the kernel mode component of a DLL injection library called madCodeHook, developed by Systemsoftware Mathias Rauen, that is used by several security and other vendors as part of their exploit prevention capabilities, amongst other things.

madCodeHook is a framework of function hooking and code injection techniques that can be used to monitor specific processes for abnormal behaviour or any other situation where API hooking might be required. This works by defining a list of process names to inject a specific DLL module that can also be used for hooking purposes.

The DLL injection takes place from kernel mode in order to achieve early injection into the processes of interest during their initialization stages. The library itself offers the ability to check for specific digital signatures before injecting a module into a process. It also blocks any shared write access to the module to be injected.

These two methods aim to prevent arbitrary DLL injection and/or modification of the defined module after it has passed the signature checks. However, we found a design flaw that can be abused, which allows an attacker to achieve arbitrary DLL injection into privileged processes and execute malicious code in the security context of SYSTEM user account.

According to the author of this library, there are at least 15 security vendors using this library, but they were not able give us further details on this in order to protect their customers.

Based on our investigation, “MalwareBytes” and “EMSISOFT” are also using this library, but since they were notified of this vulnerability by the author of the library, we didn’t have the time to test our exploit against their products.

During this article we will be examining this issue through the Cisco AMP product which uses a driver developed by Morphisec, which in turn uses the aforementioned kernel mode code library, which can be used for hooking purposes.

The Vulnerability

The ExPrevDriver.sys module, formally known as MorphiDriver32.sys and originally developed by Morphisec, is used to inject the Protector64.dll and Protector32.dll modules into selected user mode processes for extra “monitoring” purposes.

By sending the appropriate IOCTL we can define a path to a module to inject and also process names to protect and/or exclude from the DLL injection on runtime as they start.

Even though the driver will verify that the module is digitally signed by a specific trusted certificate, and blocks any modifications to the module after that by only allowing read access to user mode processes, it doesn’t protect from path redirection attack vectors.

In addition, the driver verifies the digital signature of the module to be injected only during this stage.

This type of vulnerability is described as time-of-check-time-of-use (TOCTOU).


In order to exploit this vulnerability, we need to send the appropriate IOCTL using an input buffer where the data has a specific structure. In addition to that, to be able to reach the dispatcher function, we must first solve a custom crypto-challenge that was applied by the author of madCodeHook library, presumably to block pre-analysis fuzzing and/or make the analysis more difficult.

This stage makes use of the RIPEMD-160 hashing algorithm along with two custom “encryption” routines, where all of them are bound together in a specific order for the purpose of validating and blocking arbitrary input.

The input validation scheme is designed as follows:

  1. Prepare a structurally valid input data buffer.
  2. Encrypt the data using a custom encryption routine.
  3. Hash the encrypted data.
  4. Re-encrypt the encrypted data with another custom encryption routine using the hash as a key.
  5. Prepend the hash generated in step 3 and send the IOCTL.

The driver will go through the reverse steps to decrypt and validate the structure of the input data. Note, this is an overview of the input validation design; we will leave the rest of the details as an exercise for the reader.

This screenshot shows part of this request to the driver.

IOCTL Input Data

IOCTL Input Data

This is a legitimate request performed by the driver during initialization. We can see the full path to the 32-bit module to be injected, and a partial list of target process names. A similar request using the path to the 64-bit module will be used as well to protect 64-bit processes. So, when the driver is loaded it will set a list of process names to monitor for and inject the appropriate module as defined above once a process that matches one of those names is started.

A local attacker can create a directory junction to the original protector module and include this in the path to send via the IOCTL. The driver will verify that we point to the expected module and will accept this request.

The vulnerability exists because instead of the driver storing the real path to the module that we defined via the IOCTL (in other words normalize the provided path), it actually stores the path as we define it. However, the attacker can now delete the junction and create a directory instead, and place an arbitrary DLL with the same name, which will cause the driver to inject the malicious DLL to the selected process defined in the IOCTL when the process starts.

In this way we can trick the driver to successfully validate our request and store the module path as we submit it. We can then inject into arbitrary processes, defined by us via IOCTL, our own DLL that contains the payload.

Finally, we can ‘force’ the driver to load our DLL in a service process running as SYSTEM and obtain full access in the affected host.

Summary of exploitation steps

Here is a summary of the exploitations steps.

  • Create directory junction pointing to the legit module directory (“mklink /J C:\users\<username>\Desktop\exprev C:\Program Files\Cisco\AMP\exprev”)
  • Send IOCTL using path “C:\users\<username>\Desktop\exprev\Protector64.dll”
  • Delete directory junction and create a normal full path “C:\users\<username>\Desktop\exprev\Protector64.dll” where the DLL is now your own DLL of choice.
  • Start a process that you chose to protect through the IOCTL request.
  • You should see your DLL loaded into that process.

Avoiding this type of vulnerability

Drivers should normalize the received module path instead of storing the path as it is received from userland, which may contain junctions in-between, and lead to security issues such as the one reported here.

Additionally, the signature validation routine could be used each time just before a module is injected into a process. In that way, we can ensure that unsigned and/or self-signed binaries cannot be injected into arbitrary processes by abusing design flaws in similar driver functionality.

Finally, drivers shouldn’t (in general) allow low privileged processes to send IOCTL requests. This can be achieved by enforcing the correct ACL to the named device object that is exposed to the user mode processes.

Disclosure Timeline

The madCodeHook author rapidly patched the library. We also chose to work with Morphisec, an affected vendor, during the disclosure process. Both entities were speedy and effective in their responses.

  • Discovery: 6 July 2020
  • Library author notified: 6 July 2020
  • Patch issued by library author: 16 July 2020
  • Nettitude disclosure: 1 December 2020


CVE-2020-27708: Electronic Arts (EA) Origin – Local Privilege Escalation

We recently assessed the security posture of Electronic Arts Origin Client and discovered a privilege escalation issue that would allow a low privilege attacker to elevate privileges to NT AUTHORTY\SYSTEM.  This has been recorded as CVE-2020-27708.

Origin is a digital distribution platform, by Electronic Arts, who own the brand EA Games.  They acquired the trademark Origin when it purchased Origin Systems in 1992. The platform allows some reported 39 million [1] users to download and install games by Electronic Arts.

An initial look with procmon

First, we used the free SysInternals Process Monitor tool (procmon) [2] to look for any low-hanging fruit.  Something immediately stood out; two system services looking for the directory C:\platforms, which they were not able to locate.


In Microsoft Windows, any user is by default able to create a directory in the root of the C drive. So, we proceeded to do just this.

We followed this with a second run of procmon.


As can be seen in the second procmon output, a directory listing takes place on the C:\platforms directory, which is interesting and something we made a note of.

A closer look with ProcessHacker

Our next course of action was to have a look at one of the service processes OriginWebHelperService.exe process using another free tool called ProcessHacker [3]. Something immediately stood out to us, which can be seen in the image below; OriginWebHelperService.exe is loading a DLL qwindows.dll from the directory C:\Program Files (x86)\Origin\platforms\.

Because of the similar names, C:\platforms and C:\Program Files (x86)\Origin\platforms\, we decided to copy the contents of the C:\Program Files (x86)\Origin\platforms\ directory into the C:\platforms directory.


We then ran ProcessHacker again to view the loaded modules within OriginWebHelperService.exe.

Surprisingly, this DLL was loaded directly into the OriginWebHelperService.exe process.

A bump in the road

The next step was to replace qwindows.dll with our own malicious DLL that would open a command prompt on behalf of a low level user. This is where we hit a slight bump in the road. We could see in a procmon log that our DLL was being read, however it was then closed and the original qwindows.dll was read from the Program Files path.

Using another free tool CFF Explorer [4] we took a look at qwindows.dll.


qwindows.dll has only two exported functions, qt_plugin_instance and qt_plugin_query_metadata.


Looking at the sections within the qwindows.dll there are two that stood out to us, .qtmetad and .gfids. What if the Origin Client executables are scanning the DLL’s in the C:\platforms directory and looking for these sections before loading the DLL?

We decided to find out and proceeded to copy the data from these two sections, adding the data to our own malicious DLL into sections with identical names.


Successful privilege escalation

The result was immediate; our DLL was loaded into the OriginWebHelperService.

The OriginWebHelperService runs as Local Service, which is a low privilege account and requires some further effort in order to gain full NT AUTHORITY\SYSTEM privileges.

A recent paper by Antonio Cocomazzi [7] details several ways to break out of Local Service accounts by abusing the SeImpersonatePrivilege.  We could have attempted to use the “Chimichurri Reloaded” technique, for example [8].

However there is another service included with Origin, “Origin Client Service” which runs under the account NT AUTHORITY\SYSTEM and shares the same DLL hijacking vulnerability as the OriginWebHelperService.

At this point we changed our focus to “Origin Client Service”.

Using the sdshow command of sc.exe, the Windows Service Control tool, it was possible to view the security permissions of the Origin Client Service:


The Security Descriptor Definition Language (SDDL) output from the sc sdshow command allows us to view the Security Descriptor, which suspiciously has an ACL for the well known SID string [5] “BU” is used which represents the BUILTIN\Users group.

More detail can be obtained using a PowerShell script [6]:

This allowed us to determine that any user is able to start and stop the OriginClientService.exe service process. This is an added bonus; we now don’t have to wait for reboot in order to execute our malicious payload; we can simply start the service and get as many elevated command prompts as we want:

While both the OriginWebHelperService and the OriginClientService were vulnerable to the issue, the path of least resistance was to exploit the OriginClientService gaining system privileges directly.

CVE-2020-16091 for EA Games Origin Client

We were initially issued CVE-2020-16091 by MITRE, which exclusively describes the vulnerability in this post.  Electronic Arts subsequently became a CNA and have issued a new CVE number, CVE-2020-27708, which merges a lower impact incarnation of this vulnerability with our original finding.  We have opted to lead with CVE-2020-27708, with a reference to CVE-2020-16091 noted here to avoid confusion.


  • 27 July 2020 – Initial discovery
  • 28 July 2020 – CVE-2020-16091 issued by MITRE
  • 8 September 2020 – Electronic Arts informed of vulnerability
  • 19 September 2020 – Electronic Arts granted CNA status
  • 28 October 2020 – Electronic Arts issued CVE-2020-27708
  • 29 October 2020 – Electronic Arts released patch
  • 3 November 2020 – Nettitude release vulnerability analysis


It takes a relatively low effort to audit for DLL path hijacks.  Tools such as process monitor are freely available and should be leveraged as part of a products testing cycle.

Developers should also assess if they really need a service to run as NT AUTHORITY\SYSTEM. For most practical purposes, running a service under the Local Service account is just as effective and more secure; the Local Service account has various privilege restrictions, although is not immune to further privilege escalation itself [7] [8].

We identified this vulnerability in Electronic Arts Origin Windows client, version – 763270.  The vendor has patched this vulnerability in version of the client.


    1. Origin has 39 million users –
    2. Process Monitor –
    3. ProcessHacker –
    4. CFF Explorer –
    5. Well known SID strings –
    6. Using PowerShell to view service ACL’s –
    7. Windows Privilege Escalations: Still abusing Service Accounts to get SYSTEM privileges
    8. Chimichurri Reloaded

CVE-2019-12750: Symantec Endpoint Protection Local Privilege Escalation – Part 2

In this post we will walk you through a more sophisticated method of exploiting CVE-2019-12750.  This is a local privilege escalation vulnerability that affects Symantec Endpoint Protection.  The method of exploitation described in this post works, at the time of writing, on all versions of Windows. Read more

CVE-2019-12750: Symantec Endpoint Protection Local Privilege Escalation – Part 1

A malicious application can take advantage of a vulnerability in Symantec Endpoint Protection to leak privileged information and/or execute code with higher privileges, thus taking full control over the affected host. Read more