Bypassing Windows AppLocker

Microsoft offers several built-in solutions for application whitelisting.

Before the advent of Windows 7, Microsoft rolled out the Software Restriction Policies (SRP) 423 solution for whitelisting applications. Although SRP is still available, it has been largely replaced by AppLocker, introduced with Windows 7 and continuing in Windows 10. AppLocker comprises the kernel-mode driver APPID.SYS and the APPIDSVC user-mode service. The APPIDSVC service handles the whitelisting rules and identifies applications based on callback notifications from APPID.SYS.

Having covered the foundational concepts of application whitelisting software, we will now proceed to set up whitelisting rules for AppLocker, which is among the more frequently used solutions. It is important to note that AppLocker is exclusive to the Enterprise and Ultimate editions of Windows, and is not available in Windows Professional and other versions.

Configure and Enable Applocaker on Windows 2k19 DC at GP level:

Create Default Rules:

The other three categories have similar default rules. We’ll enable them to configure basic application whitelisting protection on our Windows 10 victim VM.

Now we will block a particular program .exe (cmd.exe) execution at Domain GP level:

Click on Create New Rule:

Once we have created all the default rules, we must close the Local Group Policy Editor, and run gpupdate /force from the admin command prompt to refresh the active group policies.

Now we can see that the application calc.exe has been blocked at GP level:

Now that AppLocker is configured and enabled, non-admin users should not be able to execute any executable or script outside C:\Program Files, C:\Program Files (x86) and C:\Windows.

Even if we copy any executable to any location, it won't allow us to execute the same outside the intended directories like C:\program files, (x86) and Windows folder.

In the below demonstration, we copied the cmd.exe from it's original location (C:\windows\system32) to the Desktop and Applocker prevented us from the execution:

accesschk.exe "Authenticated Users" c:\Windows -wus -accepteula

The output indicates the RX flag (associated with the NT AUTHORITY\Authenticated Users group) is set for C:\Windows\Tasks, meaning that any user on the system will have both read and execute permissions within the directory.

Based on the output of these tools, the Paul user will have both write and execute permissions within this directory.

To test this, we’ll start a command prompt as "Paul" in a non-admin context. We’ll copy the native calc.exe executable from C:\Windows\System32 into "c:\windows\tasks" and attempt to execute it:

The program runs, indicating that we have bypassed the default AppLocker application whitelisting rules.

We can also achieve the same by copying the files in to the writable "c:\windows\temp" directory:

In ConstrainedLanguage mode, scripts located in approved locations or following a whitelisting rule can run with full functionality. However, if a script breaks the rules or commands are directly entered in the command line, ConstrainedLanguage enforces several restrictions.

One of the most notable limitations is the exclusion of calls to the .NET framework, execution of C# code, and the use of reflection.

To illustrate this, we will open a PowerShell prompt as the "Paul" user and try to invoke the .NET framework, as demonstrated below:

As evidenced by the highlighted warning in the listing above, we cannot access the otherwise simple cosine function in the Math namespace of .NET. This warning is indicative of constrained language mode.

The language mode of the current PowerShell session or prompt is always stored in the $ExecutionContext.SessionState.LanguageMode variable which can be displayed as follows:

$ExecutionContext.SessionState.LanguageMode

In contrast, let’s open a second PowerShell prompt with administrative privileges in the context of the "Admin" user and dump the contents of the same variable:

$ExecutionContext.SessionState.LanguageMode
[Math]::Cos(1)

In ConstrainedLanguage mode, scripts located in approved locations or following a whitelisting rule can run with full functionality. However, if a script breaks the rules or commands are directly entered in the command line, ConstrainedLanguage enforces several restrictions.

Steps to bypass the PS Constrained Mode

Download the compiled binary:

Now we can execute this code which will generate the test.txt which shows which mode we can execute now:

AppLocker blocks our C# executable because we executed it from a non-whitelisted directory:

So let’s copy the executable into a whitelisted directory to verify our constrained language mode bypass:

Our PowerShell script ran without any limitations within the custom runspace, successfully accomplishing the intended objective. Excellent.

Last updated