Really Least-Privilege Development: AppLocker and Visual Studio

AppLocker is a software execution policy tool in Windows 7 Enterprise and Ultimate and Windows Server 2008 R2. An AppLocker policy can be used to shift Windows from a  model where execution of code is permitted by default to a model where execution is denied by default. AppLocker is aware of binary exe, DLL/OCX, the scripting engines that ship with Windows and Windows Installer packages. The default rule sets for these categories will only allow code that is installed into the system or program files directories to execute. Once AppLocker is turned on, execution of code is denied by default and an unprivileged user cannot add executable code to the system.

If untrusted users can’t execute new code, then how can Visual Studio possibly work without making developers admin?

Grant Execute on Source/Build Tree: Fail

I thought this would be super simple and that all I would have to do was create Executable, DLL and Script path rules to grant execute on my source tree. At first, it seemed to work and I was off and running. Then I tried to build a big complicated project and the build failed all of a sudden. This solution had post-build rules but so what? I had script enabled for the build tree.

Build Actions Fail

Procmon shows that the pre- and post-build events are implemented as temporary batch scripts in %TEMP%. They are named <cryptic-number>.exec.cmd.

procmon-postbuild

Unfortunately %TEMP% is not a usable macro in AppLocker. You have to either create a generic Script rule to allow all *.exec.cmd scripts to execute or create rules for each Visual Studio user like C:\Users\<username>\AppData\Local\Temp\*.exec.cmd. Either way, post-build actions will start to work.

Web Apps Crash with Yellow Screen of Death

Another issue is that running Web apps with the built-in Visual Studio Development Web Server (aka Cassini) fails miserably. The obvious clue that this is AppLocker is “The program was blocked by group policy.”

webdev.webserver20-yellowdeath

The problem is that Cassini copies the DLLs and runs them from a subdirectory of %TEMP%\Temporary ASP.NET Files\.

webdev.webserver20-temp

 

In order for Cassini to work, you have to disable DLL rules or  create a DLL allow path rule for every developer in the form C:\Users\<username>\AppData\Local\Temp\Temporary ASP.NET Files\*.dll.

Visual Studio’s HelpLibAgent.exe Crashes

This one is a bit weirder and more surprising. Visual Studio 2010 has a new help system that operates as a local HTTP server. Invoking help with AppLocker DLL rules enabled generates a serious crash.

helplibagent-crash

I’m not sure why it does this but HelpLibAgent.exe generates a random string and then two .cs files based on that string and invokes the C# compiler to generate a DLL based on the random string which is dynamically loaded by HelpLibAgent. This seems weird on the face of it that and there’s nothing in that code that looks like it has to be generated on a per-user basis at all. Weird, weird, weird.

helplibagent-dll-compile

In order for this to work you have to allow any randomly named dll to load out of %TEMP% which means disabling DLL rules or modifying the rule that was necessary for Cassini:

C:\Users\<username>\AppData\Local\Temp\*.dll.

Summary

In order to run Visual Studio with AppLocker a user needs the following rules:

  • DLL, EXE and Script: Allow path on source tree / build directory structure
  • Script: Allow path on %TEMP%\*.cmd.exec
  • DLL: Allow path on %TEMP%\*.dll
  • Unfortunately %TEMP% is not available in AppLocker so a C:\Users\<username>\AppData\Local\Temp\* for every <username> needed has to exist. These are probably best implemented as local policies.
  • Optional: Allow script *.ps1. (This is pretty safe because PowerShell has its own tight script execution security model.)
  • It’s unfortunate that DLL rules have to be enabled for a well-known location like %TEMP% but that still doesn’t make the DLL rule useless.

    • OCX is still not permitted from %TEMP%
    • AppLocker DLL rules are complementary to CWDIllegalInDllSearch for mitigating DLL Hijacking because it provides a more granular options. This is particularly important if you need to use a global CWDIllegalInDllSearch setting of 1 or 2 for compatibility reasons.
    Once these rules are in place, the experience is seamless. The rules don’t get in the way of anything.
    Note that AppLocker script rules only apply to the scripting hosts that ship with Windows: CMD, Windows Scripting Host (.vbs and .js) and PowerShell). Perl, Python, Ruby, etc interpreters are not affected by AppLocker policy. Similarly, execution of Java jar files are not affected by AppLocker.
    It would be nice if DLL rules were a little smarter. For instance, I would like to be able to allow managed DLLs on some path but not native code.
Advertisements

One Response to Really Least-Privilege Development: AppLocker and Visual Studio

  1. Kevin Bishop says:

    You simply run your code from an approved folder that is allowed by applocker. Applocker isn’t there to make a user’s life hard, or to stop a work process. It’s primary purpose is to make your life safe and to prevent a disruption of work by a virus or malware and therefore a loss of money. All of the Microsoft Documentation points out that applocker deployment need to be a well thought out plan so everyone’s work process can be taken into account. Of course many times IT departments may just jump the gun and may shoot a few people in the foot while they are at it =) but we try our best..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: