Listen to this Post

Introduction:
Windows App Control for Business (formerly WDAC) includes a script enforcement policy option that simultaneously kills mshta.exe, MSXML XSL transforms, VBS/JS/WSF scripts, and restricts COM to an allowlist. This single configuration flip eliminates decades of script‑based tradecraft—from HTA loaders to WSH persistence—forcing adversaries to rewrite tooling and bypass binary control, a much harder problem.
Learning Objectives:
- Identify and disable the five script‑based attack surfaces neutralized by script enforcement (mshta, MSXML, VBS/JS/WSF, COM scriptlets).
- Configure and deploy Windows App Control policies with script enforcement and COM allowlisting using PowerShell and Group Policy.
- Validate policy effectiveness with command‑line tests and event log monitoring, and understand adversary cost imposition.
You Should Know:
1. Hard‑Killing mshta.exe and HTA Delivery Ecosystems
The mshta.exe binary has been a favorite for delivering malicious HTA files since Windows 7. When script enforcement is enabled, mshta refuses to execute any code—signed or unsigned, in audit or enforce mode. The entire HTA delivery pipeline dies instantly.
Step‑by‑step guide to block mshta via App Control:
- Generate a base App Control policy (allow only System and published binaries):
New-CIPolicy -FilePath C:\AppControl\BasePolicy.xml -Level Publisher -UserPEs
2. Enable script enforcement (policy rule option 3):
Set-RuleOption -FilePath C:\AppControl\BasePolicy.xml -Option 3
3. Convert XML policy to binary for deployment:
ConvertFrom-CIPolicy -XmlFilePath C:\AppControl\BasePolicy.xml -BinaryFilePath C:\AppControl\SiPolicy.p7b
4. Deploy (local machine):
Copy-Item -Path C:\AppControl\SiPolicy.p7b -Destination C:\Windows\System32\CodeIntegrity\ -Force $RefreshPolicy = "C:\Windows\System32\CodeIntegrity\RefreshPolicy.exe" Start-Process -FilePath $RefreshPolicy -Wait -NoNewWindow
5. Test the kill:
mshta.exe javascript:alert("test")
Expected result: Process exits silently or errors with “This program is blocked by group policy.” Check event log:
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-CodeIntegrity/Operational'; ID=3076} | Select-Object -First 1
2. Neutralizing 15 Years of XSL Transform Exploits
MSXML’s XSL transform capability has been a red‑team staple since 2009—loading remote XSL scripts to execute arbitrary code. Script enforcement imposes a hard kill: MSXML refuses to process any XSL transform that would execute code.
Step‑by‑step validation and monitoring:
- Attempt a standard XSL transform attack (disabled by policy):
$xslt = @" <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt"> <ms:script language="JScript" implements-prefix="ms">Function Exec() { new ActiveXObject("WScript.Shell").Run("calc.exe"); }</ms:script> <xsl:template match="/"><xsl:value-of select="ms:Exec()"/></xsl:template> </xsl:stylesheet> "@ $xml = "<root/>" $xslDoc = New-Object System.Xml.Xsl.XslCompiledTransform $xslDoc.Load([System.Xml.XmlReader]::Create((New-Object System.IO.StringReader($xslt)))) $xslDoc.Transform($xml, $null)With script enforcement enabled, this fails with a security exception.
-
Monitor blocked XSL attempts in CodeIntegrity operational logs (event ID 3076):
Get-WinEvent -LogName "Microsoft-Windows-CodeIntegrity/Operational" | Where-Object {$<em>.Id -eq 3076 -and $</em>.Message -like "MSXML"} -
For audit mode (test without blocking), set policy to `Enabled:Audit Mode` (Option 11) and review events without breaking production.
3. Locking Down VBS/JS/WSF with Script Enforcement
Wscript and Cscript remain on disk, but every .vbs, .js, and .wsf they try to execute must be explicitly allowed by your App Control policy. Phishing macros dropping scripts to %TEMP% will fail the policy check—the script never runs.
Step‑by‑step to allow only approved scripts:
- Create a script allowlist by running your approved scripts while in audit mode:
Copy-Item C:\AppControl\BasePolicy.xml C:\AppControl\AuditPolicy.xml Set-RuleOption -FilePath C:\AppControl\AuditPolicy.xml -Option 11 Enable audit mode ConvertFrom-CIPolicy -XmlFilePath C:\AppControl\AuditPolicy.xml -BinaryFilePath C:\AppControl\SiPolicy_audit.p7b
Deploy as above, then run your legitimate scripts. Collect the file hash rules automatically created in
%OSDrive%\Windows\System32\CodeIntegrity\CiPolicy\Active. -
Extract allowed script rules and merge into enforce policy:
Merge-CIPolicy -OutputFilePath C:\AppControl\FinalPolicy.xml -PolicyPaths C:\AppControl\BasePolicy.xml, C:\ProgramData\Microsoft\Windows\CIPolicy\Active.xml
3. Test a dropped malicious script:
echo WScript.Echo "Hello" > %TEMP%\test.vbs cscript %TEMP%\test.vbs
Without an explicit allow rule, result: “This program is blocked by group policy.”
- Override temporarily for a signed script (if using publisher rules):
Add-SignerRule -FilePath C:\AppControl\FinalPolicy.xml -CertificatePath C:\Certs\YourCA.cer -UserPEs
4. COM Allowlisting: The Separate Latch
Disabling script enforcement does not turn off COM enforcement. COM is restricted to an allowlist bolted on a separate latch, killing COM scriptlet abuse, script‑based persistence, and lateral movement using CLSIDs like `ScriptControl` or WScript.Shell.
Step‑by‑step COM allowlisting:
1. Identify COM objects to allow using PowerShell:
Get-ChildItem HKLM:\SOFTWARE\Classes\CLSID | ForEach-Object {
$clsid = $<em>.PSChildName
$progid = (Get-ItemProperty -Path $</em>.PSPath -Name "ProgID" -ErrorAction SilentlyContinue).ProgID
[bash]@{CLSID=$clsid; ProgID=$progid}
} | Export-Csv C:\AppControl\COMObjects.csv
- Add COM CLSID allow rules to your policy XML (edit manually or use `Add-COMCLSIDRule` from WDAC Policy Wizard tools). Example rule snippet:
<AllowClsid RuleId="Allow_CLSID_WScriptShell" FriendlyName="WScript.Shell"> <Clsid>{72C24DD5-D70A-438B-8A42-98424B88AFB8}</Clsid> </AllowClsid> -
Apply policy and verify that an unauthorized COM object fails:
$com = New-Object -ComObject "ScriptControl" Requires allowlist
Without allow rule, error: “Operation is not allowed because the policy is blocked.”
5. Auditing and Enforcing Policies Across the Fleet
Use Group Policy or Intune to deploy App Control policies organization‑wide, and audit the impact before enforcing.
Step‑by‑step for enterprise deployment:
1. Create a deployment share:
mkdir \domain\sysvol\Policies\AppControl
- Convert policy to binary (
.p7b) and store there. -
Group Policy – Computer Configuration → Administrative Templates → System → Device Guard → “Deploy Windows Defender Application Control” → set to enabled and point to the `.p7b` UNC path.
4. Detect blocked scripts via event forwarding:
wevtutil set-log "Microsoft-Windows-CodeIntegrity/Operational" /enabled:true /retention:false /maxsize:1073741824
Forward events with Windows Event Collector (WEC) and query using `Get-WinEvent -ComputerName $target -LogName “Microsoft-Windows-CodeIntegrity/Operational” | Where-Object {$_.Id -in 3076,3077}`
5. Linux side note (if cross‑platform): Similar cost imposition exists with seccomp, AppArmor, or SELinux script policies. Example: Blocking `execve` on interpreter binaries via seccomp‑bpftrace.
6. Adversary Cost Imposition: Why This Matters
Commodity malware and red teams must now ship a binary instead of a script, then bypass App Control for binaries—which is far harder (requires code signing theft, vulnerable drivers, or kernel exploits). Attackers abandon delivery primitives that worked since Windows 7, spend money on rewriting tooling, and lose silent execution.
Verification command for overall policy state:
Get-CIPolicy -FilePath C:\Windows\System32\CodeIntegrity\SiPolicy.p7b | Select-Object -ExpandProperty Rules | Where-Object {$_.Option -eq 3}
Returns Enabled:Script Enforcement if active.
To revert (temporarily for testing):
Remove-Item C:\Windows\System32\CodeIntegrity\SiPolicy.p7b -Force Restart-Service -Name "CodeIntegrity"
What Undercode Say:
- One flip kills five vectors – mshta, MSXML transforms, VBS/JS/WSF, and COM abuse are all neutralized together, not piecemeal.
- Adversary cost is real – Attackers must now invest in binary payloads and bypass code integrity, a skill tier above script‑kiddie tooling.
- Free and native – No third‑party EDR required; Windows App Control ships with every modern Windows version.
- COM allowlist is independent – Even if you disable script enforcement, COM restrictions remain active, closing a common persistence bypass.
- Audit mode is your friend – Test for weeks without blocking to avoid breaking legitimate automation.
This single policy option represents one of the highest‑leverage security configurations available. It imposes asymmetric cost on adversaries while demanding near‑zero maintenance from defenders. The script‑era tradecraft that filled red‑team toolkits for 15 years collapses on a flip.
Prediction:
Within 18 months, script enforcement will become a baseline recommendation in all Windows hardening guides (CIS, DISA STIG), and we will see a measurable decline in HTA‑based and WSH‑based malware families. Attackers will pivot to fileless PowerShell and .NET in‑memory binaries—but those face UMCI and script enforcement already. The next arms race will shift to bypassing Event Tracing for Windows (ETW) and AMSI, not script delivery. Organizations that enable script enforcement today will retroactively defeat thousands of existing script‑based implants.
▶️ Related Video (82% Match):
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Michaelahaag App – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


