Full Report
Carrie Roberts // PowerShell’s Constrained Language (CLM) mode limits the functionality available to users to reduce the attack surface. It is meant to be used in conjunction with application control […] The post Constrained Language Mode Bypass When __PSLockDownPolicy Is Used appeared first on Black Hills Information Security, Inc..
Analysis Summary
# Vulnerability: PowerShell Constrained Language Mode Bypass via File Path Convention
## CVE Details
- CVE ID: N/A (This appears to be a configuration/implementation weakness rather than a discrete software vulnerability with a public CVE at the time of the article)
- CVSS Score: N/A
- CWE: CWE-587: Improper Neutralization of Special Elements Used in an Operation System Command ('OS Command Injection') or CWE-23: Path Traversal (Contextually related to improper path handling)
## Affected Systems
- Products: PowerShell (when Constrained Language Mode (CLM) is intended to be enforced)
- Versions: Applicable to environments deploying PowerShell CLM, particularly when relying on the `__PSLockDownPolicy` environment variable for enforcement.
- Configurations: Environments where CLM is enabled (e.g., via `__PSLockDownPolicy` or Application Control solutions) but where file path integrity checks are insufficient or not the primary enforcement mechanism.
## Vulnerability Description
PowerShell's Constrained Language Mode (CLM) is intended to restrict dangerous PowerShell capabilities. Enforcement can inadvertently be bypassed by an attacker exploiting undocumented file naming conventions. Specifically, if a PowerShell script's path contains the string "System32", PowerShell will automatically execute the script in **Full Language Mode**, effectively bypassing the CLM restrictions, even if the `__PSLockDownPolicy` environment variable is set to enforce CLM. This bypass is possible without requiring administrative privileges if the attacker can place or execute a script from such a path.
## Exploitation
- Status: PoC available (The article details the successful demonstration and source code reference for the path bypass.)
- Complexity: Low (Requires placing a script in a path containing "System32" and executing it.)
- Attack Vector: Local (Requires the ability to execute a script locally on the target machine.)
## Impact
- Confidentiality: High (Bypassing CLM allows access to potentially restricted cmdlets and functionality for data exfiltration.)
- Integrity: High (Bypassing CLM allows modification or execution of arbitrary code.)
- Availability: Medium to High (Ability to execute disruptive commands.)
## Remediation
### Patches
- The ultimate patch relies on Microsoft addressing the underlying logic in PowerShell that checks for "System32" in the file path to switch language modes. (No specific patch version provided in the article.)
### Workarounds
1. **Avoid Relying Solely on `__PSLockDownPolicy`:** Do not rely on setting the `__PSLockDownPolicy` environment variable as the sole enforcement mechanism for CLM, as it is explicitly designed for debugging and easily removable by administrators or bypassed by non-admin users via path manipulation.
2. **Application Control Enforcement:** Ensure that robust Application Control solutions (like Windows Defender Application Control/Device Guard User Mode Code Integrity) are properly configured and used as the primary means of enforcing CLM or script execution restrictions, rather than relying on the PowerShell language mode policy alone.
3. **Scan for Execution Paths:** Monitor execution environments for scripts being run from paths containing "System32" when CLM is expected to be active, as this may indicate an attempted bypass.
## Detection
- Indicators of compromise: Execution of unauthorized PowerShell scripts following the establishment of CLM enforcement, especially if the script executes commands normally restricted in CLM.
- Detection methods and tools: Monitor PowerShell logging (Script Block Logging, Module Logging, Transcription) for scripts running in "Full Language Mode" when the host process context suggests CLM should be active. Look for process executions where the script path contains `\System32\` preceding invocation.
## References
- Vendor Advisory (Reference provided in article): hxxps://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/
- Source Code Reference: hxxps://github.com/PowerShell/PowerShell/blob/3d4e294262d2f2d7472ebd5d849b1b68fd6ef524/src/System.Management.Automation/security/wldpNativeMethods.cs