This week started out good. While I was looking into the usefulness of Windows AppLocker Belgian security researcher Didier Steven posted a blog entry explaining that he found a way to load DLLs that are not permitted by AppLocker. An anonymous comment pointed out an even bigger issue: starting new processes (=programs) that are not permitted by AppLocker.
Before you think these are l33t hacks that will be fixed soon, read those blog entries. It is all by design. Apparently one challenge Microsoft faced when designing AppLocker was the installation of new software. The default AppLocker rules allow users to run Windows installer files. (I don’t quite get what the point of using a whitelist is when users are still allowed to install new programs.) This poses an potential deadlock. Installer (msi) files often contain executables and DLLs that are placed in a temporary location and then executed during the installation process. Adding the %TEMP% directory to the AppLocker whitelist would be insecure. So Microsoft designed 2 special API flags for this case: LOAD_IGNORE_CODE_AUTHZ_LEVEL for LoadLibraryEx() to load DLLs and SANDBOX_INERT for CreateRestrictedToken() to load executables. With these flags set, AppLocker will not block the DLLs and executables, ever.
The problem with this design is that not only windows installer files can set these flags. Every single process with access to the Windows API can. This includes whitelisted applications, shellcode injected into a running process by an exploit, or (whitelisted) scripting languages. While allowing Perl or Python on a locked down Windows system is probably not a good idea, Visual Basic for Applications is something most power users can’t do without. This means that from within Microsoft Office applications like Word and Excel, the AppLocker restrictions are easily bypassed.
I have written a proof of concept macro that allows you to select the full path to an executable which will be executed bypassing all AppLocker restrictions. The macro is just a translation to VB of the C code written by Didier Stevens, so all the credit goes to him. This was my first ever Visual Basic script which shows how easy it is to write this bypass with all the needed information already out in the open.
To test this code:
- In an MS Word document, type in the path to an executable that is not allowed by SRP/AppLocker. For example: C:\test.exe
- Select the text you just typed, in this example select “C:\test.exe” without the newline
- Press Alt+F11 (brings up VBA editor)
- Right mouse button on “Normal” -> Insert -> Module
- Paste the content of runexe.txt into the new module
- Place the cursor inside the Sub RunExe()
- Press F5 (runs macro)
I have submitted the code to Microsoft, asking them to fix this by adding a control mechanism for using the LOAD_IGNORE_CODE_AUTHZ_LEVEL and SANDBOX_INERT flags. A new registry key (disabling the use completely) or linking them to a specific AppLocker rule (only allowing the use when a certain AppLocker rule is matched) would do nicely.
Update: hotfix KB2532445 fixes this issue (MS internal fix was KB370118). Is was released on November 9th, 2011.