In this blog post we’ll be going through a simple AppLocker bypass via registry key manipulation.

The goal is to run arbitrary code by leveraging any of the tools which are trusted by AppLocker’s default rules and are available on a default installation of Windows. We'll also exclude the usual suspects such as regsvr32, rundll32, InstallUtil, regsvsc, regasm and of course powershell, powershell_ise and cmd itself.

The Setup

The following shows the AppLocker rules set on the Windows 10 lab machine:

The diligent reader might notice that there are several ways of bypassing the rules listed above. For example one can use the 'ftp.exe' binary to execute arbitrary commands by preceding them with '!' or even copy any of the blocked executables to writable folders under 'C:\Windows' such as 'C:\Windows\Tasks\', which is writeable by the 'Authenticated Users' group by default. The defined rules are not meant to be impregnable by any other attack other than the one to be described in this blog post; their purpose is to ensure that the described attack does not make use of binaries which are already known to bypass AppLocker.

Additionally, although the rules listed above are Path Rule Conditions, the bypass described below will work for Publisher Rule Conditions and File Hash Rules Conditions as well.

The Technique

It started with what I thought would be a trivial bypass using CPLs. CPLs are essentially .dll files which export the CPIApplet callback function. These are used by Control Panel to collate the settings into one place.

I created a dll, changed the extension to .cpl and double clicked it. This is the same as running ‘control.exe ’ which executes anything in the MainDLL function. Unfortunately, in our lab setup, this triggers an AppLocker error on rundll32:

Yet, launching Control Panel (with its default CPLs) on its own with rundll32 being blacklisted still works! This immediately raises 2 questions:

How is Control Panel loading the default CPLs? and Where is it getting the list of CPLs from?

The first question is not essential to achieve our goal as we already know at this point that it’s not using rundll32 or any of the other blacklisted binaries to load the default CPLs. For those of you would like to dive deeper into this, the functions for the COpenControlPanel COM object (06622D85-6856-4460-8DE1-A81921B41C4B) can be found in shell32.dll:

Interestingly enough, looking at the strings of control.exe binary shows that a selected few CPLs, such as joy.cpl, are still launched via rundll32. This can be confirmed by clicking on ‘Set up USB game controllers’ in the Control Panel which displays the AppLocker error on rundll32 again.

Moving onto the more important question, where is Control Panel obtaining the list of CPLs from? With Procmon we obtain the answer pretty quickly

The contents of HKLM\Software\Microsoft\Windows\CurrentVersion\Control Panel\CPLs contains a list of CPLs which are loaded when Control Panel launches:

We also notice that the same path in HKCU is checked! By default each user has write permissions to their own hive. MSDN has an interesting article (https://msdn.microsoft.com/en-us/library/windows/desktop/hh127454%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396) on how to register dll control panel items. We’re only interested in loading our CPL so Step1 should suffice here.

We can write to our own registry in multiple ways:

With 'reg'

With'regedit' or 'regedt32'

With VBScript

With JScript

Both ‘reg’ and ‘regedit’ are Microsoft signed binaries, located in a trusted folder and allowed by AppLocker by default:

If these are blocked by Group Policy, JScript and VBScript should do the trick.

Conveniently there are also multiple ways of launching Control Panel

C:\windows\system32\control.exe

%APPDATA%\Microsoft\Windows\Start Menu\Programs\System Tools\Control Panel.lnk

Directly from the CLSID shell:::{5399E694-6CE5-4D6C-8FCE-1D8870FDCBA0} shell:::{26EE0668-A00A-44D7-9371-BEB064C98683} shell:::{ED7BA470-8E54-465E-825C-99712043E01C}

Using Junction Folders My Control Panel.{ED7BA470-8E54-465E-825C-99712043E01C}



We not have all the ingredients required for the AppLocker bypass. Firstly, create a DLL which, for example, launches command prompt; any payload will do but we'll keep it simple. Copy it to a writeable location such as the Desktop or the temp folder, rename it accordingly, chose one of the techniques described above to write the CPL path to HKCU and launch Control Panel using any of the methods listed above. This will load the DLL which in turn loads command prompt:

Conclusion

The technique described in this blog post might not be the cleanest or the most straight forward of the methods to bypassing AppLocker, nevertheless it demonstrates yet another vector attackers can utilise to load arbitrary libraries, and hence run arbitrary code on locked down machines.

For the defenders amongst you, this attack can be mitigated, at the cost of performance, by enabling the "DLL Rule Collection" under the "Advanced" tab:

Contact and Follow-Up

Francesco works in our Assurance team from our Basingstoke office. He maintains a personal blog at vulnerable.space, and has delivered Windows privilege escalation training/workshops at various conferences including DEFCON 24 and BruCon 2017. See the contact page for how to get in touch.