Posted on by Vulnerability Mitigationin
Application whitelisting is a useful defense against users running unapproved applications. Whether you're dealing with a malicious executable file that slips through email defenses, or you have a user that is attempting to run an application that your organization has not approved for use, application whitelisting can help prevent those activities from succeeding.
Some enterprises may deploy application whitelisting with the idea that it prevents malicious code from executing. But not all malicious code arrives in the form of a single executable application file. Many configurations of application whitelisting do not prevent malicious code from executing, though. In this blog post I explain how this is possible.
Application whitelisting tools, such as Microsoft AppLocker, provide enterprises with the ability to specify applications that are approved for use. Applications that are not on the approved list will simply not execute. In the case of AppLocker, the approved list is based on three primary rule conditions:
Let's consider the case where somebody is using the AppLocker Automatically Generate Rules wizard, which analyzes programs in the Program Files directory. Using this wizard results in rules that allow Microsoft-signed applications to be run, regardless of their location. The importance of the fact that the applications are allowed to be executed from any location will become clear.
Eight years ago, I published a blog post called Carpet Bombing and Directory Poisoning. In that post, I described how executing an application from an untrusted directory (such as Downloads) can have disastrous consequences. When a trusted application is executed from an untrusted directory, Windows can cause untrusted code to be executed due to the way that it locates and loads libraries. The same concept can allow an attacker to bypass application whitelisting.
Let's start out with a fully-patched 64-bit Windows system. We place a copy of c:\windows\system32\notepad.exe into a new directory called c:\asdf\. You can choose any target directory name, but we use "asdf" to make it clear when the directory is being accessed.
Now that our sample application is in place, we run Sysinternals Process Monitor and filter the results to only display when notepad.exe accesses the c:\asdf\ directory.
When we run notepad.exe from that directory, we now see what files notepad.exe is looking for.
Any file that it attempts to access in the c:\asdf\ directory that results in a NAME NOT FOUND result is a candidate for DLL hijacking. If an attacker can place a copy of a malicious library that has the same name that an application is looking for, this can cause the malicious code to execute.
In our case, we're not using malicious code, but rather a library called SENTINEL.DLL by Stefan Kanthak. When certain exported functions are executed, this library displays a dialog that indicates the vulnerable behavior. Versions of this DLL are available for several architectures in the SENTINEL.CAB file provided by Stefan. As with any untrusted code, this testing should take place only in an isolated environment, such as a standalone virtual machine.
We save a copy of the AMD64 version of SENTINEL.DLL as c:\asdf\bcryptPrimitives.dll. (On other platforms, the library may need to be named differently. For example, on a 32-bit Windows 7 system, the i386 version of SENTINEL.DLL should be saved as c:\asdf\CRYPTBASE.dll.)
Now we run notepad.exe:
It's very clear here that we've run an executable file (notepad.exe), which is signed by Microsoft, but the code that executed was definitely not the expected notepad.exe code!
AppLocker also provides the ability to perform DLL whitelisting, which can help prevent the type of DLL hijacking attack outlined above. However, this feature is disabled by default, presumably because it degrades performance and requires rigorous testing, as outlined in the AppLocker Design Guide [pdf].
The following utilities can also be exploited by attackers and should be avoided or used with caution.
Even if we configured our application whitelisting to be more locked down, by restricting application execution to paths not writable by normal user accounts, it still doesn't protect us against exploitation. The utility rundll32.exe comes with Microsoft Windows and is designed to load and run code in DLLs.
The utility regsvr32.exe comes with Microsoft Windows and is used to register and unregister OLE controls in the Windows registry. As it turns out, regsvr32.exe can also be used to download and execute arbitrary code!
PowerShell is a utility that comes with Microsoft Windows and can be used for system administration or just about anything else that somebody would want to do on a Windows system. You might be thinking that eliminating powershell.exe from the whitelist might help fix this loophole. But actually, PowerShell functionality can still be leveraged without powershell.exe by using something like PowerShell Empire.
Application whitelisting is a useful capability that can help prevent users and attackers from running unexpected applications. Application whitelisting should not, however, be treated as a feature that prevents malicious code from executing. Microsoft admits that "AppLocker is not a security feature and was never designed as a security boundary." Other vendors may not be as forthcoming about what their application whitelisting products can and cannot practically achieve.
The above list of application whitelisting bypasses is in no way meant to be exhaustive. It is prudent to assume that there are other ways to achieve code execution in an environment that uses application whitelisting. For example, if Microsoft Office macros aren't disabled, the attacker just needs to use an Office document with a macro. Microsoft Office is whitelisted after all, right?