Avecto Defendpoint is an endpoint protection product which, according to the Avecto website, will:

“Prevent breaches without hindering productivity. Avecto combines best-in-class privilege management and application control, making admin rights removal simple and scalable across desktops and servers to ensure security and compliance.”

This post focuses on the “application control” aspect of Avecto. Last year I discovered two vulnerabilities in the way that application control is implemented, leading to the possibility of a breakout from the application control policy.

Both vulnerabilities were trivial to find and exploit. An exploit could easily be written into a Microsoft Word or Excel macro, for example.

Discovery and analysis

An initial investigation was carried out using Process Hacker. Examining any process running on a machine with Avecto installed, it could be seen that a DLL PGHook.dll had been injected into every process on the machine.

C:\Users\coakley\Desktop\labs.nettitude.com\Blogs\2018\Avecto\Pictures\Avecto_PGHOOK_ProcessHacker.png
The name PGHook.dll gives away that this DLL might be a user mode hooking library. The next step was to load PGHook.dll into IDA pro and have a poke around.

PGHook.dll applies hooks to several Windows API calls. The hooks are used to communicate with an Avecto system service, which then applies Avecto Group Policy settings.

Looking at the entrypoint of the DLL in IDA pro, an issue was immediately apparent:

C:\Users\coakley\Desktop\labs.nettitude.com\Blogs\2018\Avecto\Pictures\IDA_Mutex.PNG
A global mutex is created “Global\PGHOOK<pid>” where <pid> is the current process id. If this mutex already exists, then the rest of the entrypoint code is skipped and PGHook.dll does not install any hooks!

From here, it is easy to exploit this. If an attacker can create a lot of mutexes in the Global namespace for a whole bunch of process id’s, then they can force hooking to be disabled for new processes with those id’s. This method of mutex “squatting” is exactly how CVE-2017-16245 can be exploited. After finding this, it was time for me to poke around a little further.

When executing a process that is not permitted in the security policy, a dialog box is displayed to the user; in this case wscript.exe was blocked:

C:\Users\coakley\Desktop\labs.nettitude.com\Blogs\2018\Avecto\Pictures\Avecto_Block.png
However, using ProcMon to monitor process creation, we can see that the blocked process wscript.exe does actually execute, and then exits:

C:\Users\coakley\Desktop\labs.nettitude.com\Blogs\2018\Avecto\Pictures\Avecto_WscriptBlocked_A.png
This is quite interesting; if the process is being executed and then terminates, can we block the process termination?

In Process Hacker, examining any running process again, we can see that there is a named pipe handle to \\.\pipe\PGMessagePipe being created and destroyed, quite regularly in each process.

Monitoring this pipe using API Monitor shows that it is used to communicate with a listening SYSTEM process, using the Windows API function TransactNamedPipe:

C:\Users\coakley\Desktop\labs.nettitude.com\Blogs\2018\Avecto\Pictures\Avecto_TransactNamedPipe.png
In the API monitor output, we can see the content of these messages:

<MSG ID=”2″ PID=”184 ” TID=”568″ ParentPID=”2880″ SessionID=”2″ CmdLine=”&quot;C:\Windows\system32\wscript.exe&quot;” CurrentDir=”C:\temp” InheritHandles=”1″ StartSuspended=”1″ MessageTime=”131771712686951286″ />

<MSG DisplayedMsg=”1″ Block=”1″ Status=”0″ />

You will also notice that there is a call to TerminateProcess in the API monitor output. I initially thought this may be the source of the process termination. I verified that this is not the case, by patching the TerminateProcess function with a two byte infinite loop 0xEB 0xFE (jmp -2). The process was still terminated, so this could not be the culprit.

So, each process that attempts to spawn a child process not only creates the actual child, but also tips off the SYSTEM service to the existence of the new process; this is how the new child process is terminated.

The next thing I tried was to prohibit comms with the SYSTEM service over the named pipe, which I achieved by editing the memory of PGHook.DLL in ProcessHacker on a running process.

It turned out that if comms are down, then any child process runs as normal, as it doesn’t get terminated. That is the basis for CVE-2017-16245. There are many other ways to prohibit the named pipe comms from within a process; the example source code provided below (note: will be published in the coming weeks) simply changes the name of the pipe in the process data section.

Proof of concept video

In the following video, the two CVE executables have been white-listed in the Avecto application control policy.

This is an unrealistic scenario; in an ideal world the System Administrator will have locked down the endpoints so that only a curated list of applications are allowed to execute.

The CVE’s are, however, so trivial to exploit, that is it’s not difficult to imagine an attacker or inside threat using a Word macro, browser exploit or other code execution method in combination with these vulnerabilities in order to breakout of the application control policy.

It can be seen that while the two vulnerabilities are quite powerful in their own right, combining them provides a complete break-out solution.

Proof of concept source code

We have opted to keep sample exploit code out of this blog for now.  Once we’re confident that enough time has elapsed for a significant majority of affected users to have patched, we may opt to release sample code as an educational resource.

Conclusion

These two vulnerabilities really illustrate why user mode hooking is not a particularly good method of controlling process creation on Microsoft Windows. If you want to modify process permissions or deny process execution, then a kernel module is the way to go. Several kernel mode callbacks are available that allow you to intercept process creation.

Malicious code will always run with the same privileges as user mode hooks and, given enough time and access to the security product for reverse engineering, they can be bypassed.

CVE numbers

The following CVE’s have been issued by MITRE:

  • CVE-2017-16245
  • CVE-2017-16246

Affected versions

All versions up to and including 4.4 are affected.

Disclosure timeline

  • Vulnerability discovered –  November 2017
  • Vendor notified – November 2017
  • Vendor acknowledged issues – November 2017
  • Vendor fixed issues – February 2018
  • Vendor notified that advisory is now public – 27 July 2018