PowerShell Detections
System-wide transcription
When System-wide transcription is enabled, all the activity for every PowerShell host (powershell.exe, powershell_ise.exe, System.Management.Automation.dll or other custom host) is logged to the specified directory or the user's "My Documents" directory if none is specified. With proper implementation, that is, forwarding logs to secure storage and correlation, system-wide transcription could be very effective in detecting PowerShell attacks.
PowerShell Detections
Powershell has 4 types of detection which are the following:
1. System-wide Transcription
System-wide transcription is a logging mechanism in PowerShell that records all executed commands and their output. It helps administrators and security teams track activities within PowerShell for auditing and forensic analysis. The logs include both interactive and script-based commands.
Detection Logic:
When PowerShell is started, system-wide transcription begins if it’s enabled via Group Policy. Every executed command, its arguments, and the resulting output are logged in a text file. This applies globally across all users and sessions.
Use Case:
Scenario: An attacker uses PowerShell to enumerate local users via Get-LocalUser.
Detection: If transcription is enabled, this command and its output will be recorded in the transcription log file. Security teams can review the log file to identify the executed command and its potential malicious intent.
2. Script Block Logging
Script block logging captures the full content of executed PowerShell script blocks, even if they are obfuscated or executed dynamically at runtime. This feature helps detect and analyze potentially malicious scripts by logging their full content before execution.
Detection Logic:
PowerShell script blocks (i.e., pieces of code or commands) are logged when executed. If logging is configured, PowerShell sends the script block content to the Windows Event Log (Microsoft-Windows-PowerShell/Operational).
Use Case:
Scenario: An attacker uses an obfuscated script like Invoke-Mimikatz to dump credentials.
Detection: Script block logging captures the full deobfuscated code of the script, making it visible in the event logs, even if the attacker tries to bypass traditional logging mechanisms.
3. AntiMalware Scanning Interface (AMSI)
AMSI is an interface in Windows that allows PowerShell scripts and other executables to be scanned by antimalware solutions in real-time. AMSI detects and blocks malicious scripts by passing the script content to the installed antivirus or antimalware tool for analysis. AMSI was designed by Microsoft to analyze scripts executed directly in memory. This allows it to detect and mitigate malicious activities even if the script never touches the disk. AMSI integrates with various Windows components, such as Windows Defender, to provide better protection against in-memory attacks and malicious script execution.
Detection Logic:
AMSI scans each script or script block before it executes. It operates in real-time and works at both the pre-execution and runtime phases. If the content is flagged as malicious, it can be blocked before execution.
Use Case:
Scenario: An attacker downloads a PowerShell payload from a remote server and executes it using Invoke-Expression.
Detection: AMSI scans the payload in memory before execution. If the script matches known malware signatures or patterns, the antimalware solution will block it, potentially preventing the attack.
4. Constrained Language Mode (CLM)
Constrained Language Mode restricts the capabilities of PowerShell to prevent the execution of advanced scripts and commands, reducing the attack surface. CLM is often integrated with AppLocker or WDAC (Windows Defender Application Control) to enforce strict execution policies.
Detection Logic:
When CLM is enforced, PowerShell evaluates the execution environment. If the session is in CLM, only a limited subset of PowerShell cmdlets and functions are allowed, primarily those necessary for basic system administration. Any attempt to execute restricted commands results in an error.
Use Case:
Scenario: An attacker attempts to use a custom PowerShell module to load malicious .NET assemblies.
Detection: CLM blocks the execution of commands that require full language mode. If combined with AppLocker or WDAC, unsigned or unauthorized scripts will also be blocked, stopping the attacker from progressing.
Comparison of Detection Features:
| Feature | When Triggered | Primary Purpose |
| System-wide Transcription | Logs all commands and output when enabled system-wide. | Auditing and forensic analysis. |
| Script Block Logging | Logs each script block's full content during execution. | Detecting and analyzing obfuscated or malicious scripts. |
| AMSI | Scans scripts pre-execution and at runtime. | Detecting and blocking malicious scripts in real-time. |
| CLM | Restricts functionality at the session start if enabled. | Reducing the attack surface by enforcing limited cmdlets. |
These features, when used together, significantly enhance the detection and prevention of malicious activities in PowerShell environments.
WorkFlow of Powershell Detection Logic
When you run a .ps1 script in PowerShell, the execution is monitored and processed by multiple security mechanisms. The order in which these mechanisms are triggered depends on the system configuration and the flow of execution. Below is a logical flow of how the 4 detection mechanisms: AMSI, Script Block Logging, System-wide Transcription, and Constrained Language Mode (CLM), interact when you execute a .ps1 script:
Execution Flow of Security Mechanisms
- Constrained Language Mode (CLM):
- First to Engage: When PowerShell initializes, it checks the environment for execution policies and restrictions like CLM. If CLM is enforced (via AppLocker, WDAC, or other policies), the script is limited to a reduced set of commands and functions. Advanced features like .NET calls or Add-Type may be blocked outright.
- Impact: If the script requires full language mode but is restricted to CLM, it fails immediately.
- AntiMalware Scanning Interface (AMSI):
- Second in Line: AMSI scans the script content before it is executed. This happens at two stages:
- Pre-execution: The script file is scanned when it is loaded into memory.
- Runtime: Any dynamically generated or modified script blocks are also passed to AMSI.
- Impact: If AMSI detects malicious content (based on signatures or heuristics), the script is blocked, or the antimalware software raises an alert.
- Second in Line: AMSI scans the script content before it is executed. This happens at two stages:
- Script Block Logging:
- Third to Trigger: Once AMSI clears the script, the script blocks are logged. Script Block Logging captures the entire script content, including any dynamically generated or obfuscated code, before execution. This log is sent to the
Microsoft-Windows-PowerShell/Operationallog for monitoring.
- Impact: Security teams can review these logs to analyze the intent and behavior of the script, even if it was successfully executed.
- Third to Trigger: Once AMSI clears the script, the script blocks are logged. Script Block Logging captures the entire script content, including any dynamically generated or obfuscated code, before execution. This log is sent to the
- System-wide Transcription:
- Last in the Sequence: Transcription records the commands executed and their output into log files. This includes any commands run interactively or by the script, as well as their respective output.
- Impact: If transcription is enabled, the activity trail of the script, including its execution results, is saved for auditing and forensic purposes.
Visualization of Flow
Here’s a simplified sequence:
- Script loaded → CLM checks if execution is allowed.
- Script passes CLM → AMSI scans for malicious patterns.
- Script passes AMSI → Script blocks are logged by Script Block Logging.
- Script executes → System-wide Transcription records commands and output.
Real-World Example
- You execute a
.ps1script to enumerate AD users using PowerShell.
- CLM Check: If CLM is active, advanced features are restricted, and the script fails if it relies on blocked commands.
- AMSI Scan: AMSI scans the script for malicious content. If the script is flagged (e.g., it contains known malicious code), it is blocked.
- Script Block Logging: If the script executes, its content is logged, including any dynamically generated code.
- System-wide Transcription: If transcription is enabled, the commands and their outputs are saved for auditing.
Key Takeaways
- CLM acts as the gatekeeper: It restricts script execution based on policies before other mechanisms engage.
- AMSI provides real-time scanning: It blocks malicious content at the earliest possible stage.
- Script Block Logging records intent: It captures the logic and flow of the script for analysis.
- Transcription provides post-execution records: It focuses on activity logs for auditing and investigation.
Understanding this flow allows attackers to design scripts or execution methods that avoid triggering these mechanisms during Red Team engagements. However, using native tools and techniques that align with legitimate activity remains the best way to avoid detection.
Powershell Detection Bypass
Staying undetected during a Red Team engagement requires careful planning, understanding of the environment, and using stealthy techniques to avoid triggering detection mechanisms. Here's an offensive perspective on bypassing PowerShell's security features to maintain stealth while achieving objectives:
General Offensive Strategy
- Environment Reconnaissance: Identify if transcription, script block logging, AMSI, or CLM is enabled. Misconfigurations or gaps in deployment can be leveraged.
- Living-Off-the-Land Binaries (LOLBins): Use trusted Windows binaries (e.g.,
MSBuild.exe,InstallUtil.exe) to execute payloads indirectly, bypassing PowerShell detections.
- Dynamic Execution: Execute scripts in memory using reflection or encoded payloads to avoid logging and AMSI scans.
- Minimal Use of PowerShell: Use it sparingly to reduce the chance of being detected.
1. Bypassing System-wide Transcription
System-wide transcription logs all commands and outputs in a session. To avoid detection:
- Avoid Native PowerShell Execution: Instead of running PowerShell directly, use LOLBins like
MSBuild.exeorRegsvr32.exeto execute PowerShell scripts indirectly.
- Tamper with Log Paths: If you have high privileges, alter or disable transcription policies by modifying registry keys or group policies:
Remove-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription -Name EnableTranscripting
- Redirect Output: Redirect command output to another location that isn’t monitored.
Example: Use powershell.exe -encodedCommand with obfuscated base64 payloads to minimize logging of meaningful content.
2. Bypassing Script Block Logging
Script block logging captures the full content of executed scripts. To bypass:
- Dynamic Code Execution: Use reflection or in-memory execution to load and execute scripts without creating script blocks:
[System.Reflection.Assembly]::Load([IO.File]::ReadAllBytes("payload.dll")).EntryPoint.Invoke($null, @())
- Inline Obfuscation: Obfuscate commands heavily to make them harder to analyze in logs. Tools like Invoke-Obfuscation can automate this.
- Indirect Invocation: Split commands across multiple execution points or use encoded payloads to hide the script logic.
- Disable Logging (High Privileges): If you have administrative access, disable script block logging:
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name EnableScriptBlockLogging -Value 0
Example: An attacker dynamically loads Mimikatz via a reflective DLL loader, which avoids generating script blocks.
3. Bypassing AMSI
AMSI scans scripts for malicious content. Bypasses include:
- Memory Patching: Modify
AmsiScanBufferin memory to return a clean status:$Mem = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')::"amsiInitFailed" If ($Mem -eq $null) {[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')::"amsiInitFailed" = $true}
- Payload Encryption: Encrypt payloads and decrypt them in memory just before execution to avoid AMSI detection.
- Custom .NET Assemblies: Use compiled .NET assemblies or unmanaged code for execution, as these are not directly scanned by AMSI.
- Bypass Tools: Leverage known AMSI bypass techniques/tools like
SharpSploitorInvoke-Phant0m.
Example: An attacker patches AMSI on the fly, then executes an encrypted payload that AMSI cannot scan.
4. Bypassing Constrained Language Mode (CLM)
CLM restricts the use of advanced PowerShell features. To bypass:
- Trusted Binary Execution: Use LOLBins like
InstallUtil.exeorRegsvr32.exeto execute .NET payloads, bypassing PowerShell restrictions.
- Escape CLM via AppLocker Gaps: If AppLocker is poorly configured, upload a signed but malicious binary to execute arbitrary code.
- Load .NET Directly: Use Add-Type or reflection to execute .NET assemblies, bypassing many CLM limitations.
- Alternative Execution Frameworks: Use tools like
Cobalt StrikeorSliverthat support executing PowerShell-like commands outside the native interpreter.
Example: An attacker uses InstallUtil.exe to execute a malicious assembly, bypassing both CLM and AppLocker restrictions.
Unified Stealth Use Case
- Reconnaissance: The attacker enumerates the target system to determine which PowerShell defenses are enabled (e.g., by querying group policies or registry keys).
- Payload Deployment: They create an obfuscated payload, encrypt it, and host it on a remote server.
- Execution: Instead of directly using
powershell.exe, they leverageMSBuild.exeto fetch and execute the payload in memory, bypassing transcription and CLM.
- Bypassing AMSI: Before execution, they patch
AmsiScanBufferin memory to disable AMSI.
- Avoiding Logs: The payload executes dynamically using reflection, avoiding script block logging.
By chaining these techniques, the attacker minimizes their footprint, bypasses all PowerShell security features, and achieves their objectives while avoiding detection.
Key Takeaways
- Always prioritize stealth by leveraging trusted tools and binaries available in the target environment.
- Use memory-based execution and obfuscation to avoid triggering logging and AMSI.
- Continuously adapt your approach based on the security posture and defenses in place.
This offensive approach is effective but should be used responsibly and within the scope of authorized Red Team engagements.