Skip to main content

Lab 8.2: AMSI and PowerShell Detection

Learning Objectives​

By the end of this lab, you will be able to:

  • Understand how AMSI (Antimalware Scan Interface) works
  • Identify how malicious scripts are detected
  • Know bypass techniques (for defensive purposes)
  • Implement effective detection

Estimated Duration​

45 minutes

Prerequisites​

  • Windows 10/11 VM
  • Active Windows Defender
  • PowerShell 5.1+
  • Administrator rights

Professional Context​

AMSI is a critical interface for:

  • Detecting malicious scripts
  • Protecting against fileless malware
  • Integrating antivirus with PowerShell
  • Securing enterprise environments

WARNING​

This lab explains concepts for defensive purposes.

  • Bypass techniques are presented to understand threats
  • DO NOT use these techniques maliciously
  • Execute only on isolated test VMs

Part 1: Understanding AMSI​

Step 1.1: What is AMSI?​

AMSI (Antimalware Scan Interface) is a Windows interface that allows antivirus software to inspect the content of scripts before execution.

Execution flow:

PowerShell Script --> AMSI --> Antivirus --> Allow/Block

Applications supporting AMSI:

  • PowerShell
  • Windows Script Host (wscript, cscript)
  • JavaScript
  • VBScript
  • Office VBA macros
  • .NET assemblies

Step 1.2: Verify AMSI is active​

# AMSI is active if Windows Defender is active
Get-MpComputerStatus | Select-Object AMServiceEnabled, AntivirusEnabled, RealTimeProtectionEnabled

Step 1.3: Test AMSI​

Windows Defender detects the standard AMSI test string:

# This command SHOULD be blocked by AMSI
# It contains the official test string

# Try this (will be blocked):
"AM" + "SI" + "Test"

Note: Simply mentioning certain terms triggers AMSI.

Question 1: Was the AMSI test detected?


Part 2: How AMSI Detects Threats​

Step 2.1: Signature-based detection​

AMSI scans for known patterns:

# Examples of detected patterns (do not execute):
# - "Invoke-Mimikatz"
# - "Invoke-Empire"
# - Certain Base64 encoded commands
# - Shellcode patterns

Step 2.2: Encoded scripts​

Attackers often use Base64 encoding:

# Simple command
$cmd = "whoami"

# Encoded in Base64
$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
$encoded = [Convert]::ToBase64String($bytes)
Write-Host "Encoded command: $encoded"

# Decode
$decoded = [System.Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($encoded))
Write-Host "Decoded: $decoded"

AMSI analyzes content AFTER decoding, so encoding alone is not sufficient.

Step 2.3: Observe AMSI in action​

# This script shows how AMSI intercepts commands
# Execution with logging

# Enable PowerShell logging (requires admin)
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1 -ErrorAction SilentlyContinue

# Verify
Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -ErrorAction SilentlyContinue

Part 3: Bypass Techniques (Defensive Knowledge)​

Step 3.1: Why know the bypasses?​

As a defender, you need to know attackers' techniques to:

  1. Improve detection
  2. Test your defenses
  3. Understand security alerts
  4. Train SOC teams

Step 3.2: Categories of bypass​

TechniqueDescriptionDetection
Memory PatchingModify AMSI in memoryEvent ID 4104, suspicious behavior
ReflectionUse .NET reflectionScript Block Logging
ObfuscationObfuscate codeBehavioral analysis
COM HijackingHijack COM interfaceRegistry monitoring

Step 3.3: Detecting bypass attempts​

# Script to detect AMSI bypass attempts
# Search in PowerShell logs

Write-Host "=== AMSI BYPASS DETECTION ===" -ForegroundColor Cyan

# Search for suspicious terms in logs
$suspectTerms = @(
"amsi",
"AmsiInitFailed",
"AmsiContext",
"amsiSession",
"SetValue.*amsi"
)

$events = Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -MaxEvents 100 -ErrorAction SilentlyContinue

$suspicious = @()
foreach ($event in $events) {
foreach ($term in $suspectTerms) {
if ($event.Message -match $term) {
$suspicious += [PSCustomObject]@{
Time = $event.TimeCreated
EventId = $event.Id
Match = $term
Message = $event.Message.Substring(0, [Math]::Min(200, $event.Message.Length))
}
}
}
}

if ($suspicious.Count -gt 0) {
Write-Host "`n[ALERT] Suspicious activity detected:" -ForegroundColor Red
$suspicious | Format-Table -AutoSize
} else {
Write-Host "`n[OK] No bypass attempts detected" -ForegroundColor Green
}

Question 2: Were any bypass attempts detected?


Part 4: Strengthening Protection​

Step 4.1: Enable Script Block Logging​

# Configure full logging (requires admin)

# Create keys if necessary
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell" -Force -ErrorAction SilentlyContinue | Out-Null
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Force -ErrorAction SilentlyContinue | Out-Null

# Enable logging
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
-Name "EnableScriptBlockLogging" -Value 1 -Type DWord

Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
-Name "EnableScriptBlockInvocationLogging" -Value 1 -Type DWord

Write-Host "Script Block Logging enabled" -ForegroundColor Green

Step 4.2: Enable Module Logging​

# Enable module logging
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -Force -ErrorAction SilentlyContinue | Out-Null

Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" `
-Name "EnableModuleLogging" -Value 1 -Type DWord

# Log all modules
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" -Force -ErrorAction SilentlyContinue | Out-Null
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging\ModuleNames" `
-Name "*" -Value "*" -Type String

Write-Host "Module Logging enabled" -ForegroundColor Green

Step 4.3: Configure Constrained Language Mode​

# Check current language mode
$ExecutionContext.SessionState.LanguageMode

# To enforce constrained mode (via GPO or):
# [Environment]::SetEnvironmentVariable('__PSLockdownPolicy', '4', 'Machine')
# Requires reboot

# Note: Constrained mode limits PowerShell features
# Use with caution in production

Step 4.4: Verify configuration​

# PowerShell security configuration verification script
Write-Host "=== POWERSHELL SECURITY CONFIGURATION ===" -ForegroundColor Cyan

# AMSI
Write-Host "`n[AMSI]" -ForegroundColor Yellow
$defender = Get-MpComputerStatus -ErrorAction SilentlyContinue
if ($defender) {
Write-Host " AMSI Service: $($defender.AMServiceEnabled)"
Write-Host " Real-Time Protection: $($defender.RealTimeProtectionEnabled)"
}

# Language Mode
Write-Host "`n[Language Mode]" -ForegroundColor Yellow
Write-Host " Current mode: $($ExecutionContext.SessionState.LanguageMode)"

# Execution Policy
Write-Host "`n[Execution Policy]" -ForegroundColor Yellow
Get-ExecutionPolicy -List | Format-Table

# Script Block Logging
Write-Host "[Script Block Logging]" -ForegroundColor Yellow
$sbl = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -ErrorAction SilentlyContinue
if ($sbl.EnableScriptBlockLogging -eq 1) {
Write-Host " Status: Enabled" -ForegroundColor Green
} else {
Write-Host " Status: Disabled" -ForegroundColor Red
}

# Module Logging
Write-Host "`n[Module Logging]" -ForegroundColor Yellow
$ml = Get-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -ErrorAction SilentlyContinue
if ($ml.EnableModuleLogging -eq 1) {
Write-Host " Status: Enabled" -ForegroundColor Green
} else {
Write-Host " Status: Disabled" -ForegroundColor Red
}

Part 5: Monitoring and Alerts​

Step 5.1: Key events to monitor​

Event IDLogDescription
4103PowerShell/OperationalModule logging
4104PowerShell/OperationalScript block logging
1116Microsoft-Windows-Windows DefenderMalware detected
1117Microsoft-Windows-Windows DefenderMalware action

Step 5.2: Monitoring script​

# Monitoring suspicious PowerShell events
Write-Host "=== POWERSHELL MONITORING ===" -ForegroundColor Cyan

$suspectKeywords = @(
"bypass",
"encoded",
"downloadstring",
"invoke-expression",
"iex",
"reflection",
"assembly",
"shellcode",
"mimikatz"
)

# Script Block Logs (4104)
$events = Get-WinEvent -FilterHashtable @{
LogName = 'Microsoft-Windows-PowerShell/Operational'
ID = 4104
} -MaxEvents 50 -ErrorAction SilentlyContinue

Write-Host "`nAnalyzing the last 50 Script Block Logs..." -ForegroundColor Yellow

$alerts = @()
foreach ($event in $events) {
foreach ($keyword in $suspectKeywords) {
if ($event.Message -match $keyword) {
$alerts += [PSCustomObject]@{
Time = $event.TimeCreated
Keyword = $keyword
Preview = $event.Message.Substring(0, [Math]::Min(100, $event.Message.Length))
}
break
}
}
}

if ($alerts.Count -gt 0) {
Write-Host "`n[ALERTS] Suspicious content detected:" -ForegroundColor Red
$alerts | Format-Table -AutoSize
} else {
Write-Host "`n[OK] No suspicious activity detected" -ForegroundColor Green
}

Deliverables​

  1. Answers to the 2 questions

  2. Screenshots:

    • AMSI test (detection)
    • Security configuration
    • Monitoring script execution
  3. Report (1-2 pages):

    • Explanation of AMSI functionality
    • Importance of PowerShell logging
    • Recommendations for your environment

Evaluation Criteria​

CriterionPoints
AMSI Understanding25%
Logging Configuration30%
Detection Script25%
Report and Analysis20%

Resources​


Lab developed as part of the Operating Systems course - MODULE 8