RUNBOOK // Endpoint Malware & Infostealer Containment
SEVERITY 1 / 2
ENDPOINT TRIAGE & ERADICATION
Whether dealing with an Infostealer (Lumma, RedLine, Vidar), a Loader/Dropper (Qakbot, Gootloader), or a malicious script/LNK payload, this runbook covers the triage procedure to isolate the host, kill malicious process trees, and eradicate persistence.
🛑 Step 1: Emergency Host Isolation (< 5 Minutes)
Section titled “🛑 Step 1: Emergency Host Isolation (< 5 Minutes)”Sever all inbound and outbound network connectivity to prevent malware from downloading secondary payloads, beaconing to C2, or propagating laterally:
Option A: Defender for Endpoint (MDE Cloud Isolation)
Section titled “Option A: Defender for Endpoint (MDE Cloud Isolation)”# Isolate machine via MDE Live Response / API# Preserves Defender cloud communication while severing all internal/external network access- Open Microsoft Defender Portal $\rightarrow$ Device Inventory $\rightarrow$ Search machine name.
- Click Isolate device $\rightarrow$ Select Full Isolation.
- (Optional) Check Allow Outlook and Teams only if essential communication is required.
Option B: Local PowerShell Firewall Isolation
Section titled “Option B: Local PowerShell Firewall Isolation”If EDR agent is uninstalled or tampered with by malware:
# Block all outbound host traffic immediatelyNew-NetFirewallRule -DisplayName "EMERGENCY_MALWARE_BLOCK_ALL" -Direction Outbound -Action Block -Profile Any -Priority 1# Optional: Allow specific IR jumpboxNew-NetFirewallRule -DisplayName "EMERGENCY_ALLOW_IR_JUMPBOX" -Direction Outbound -Action Allow -RemoteAddress "10.0.10.50" -Profile Any -Priority 2⚡ Step 2: Kill Active Malicious Process Trees
Section titled “⚡ Step 2: Kill Active Malicious Process Trees”Identify the root process and all child processes spawned by script interpreters:
1. KQL Query: Map Full Process Tree in Defender XDR
Section titled “1. KQL Query: Map Full Process Tree in Defender XDR”let TargetDevice = "WKSTN-FIN-02";let AlertTime = ago(2h);DeviceProcessEvents| where Timestamp > AlertTime| where DeviceName =~ TargetDevice| where FileName in~ ("cmd.exe", "powershell.exe", "rundll32.exe", "mshta.exe", "wscript.exe", "cscript.exe")| project Timestamp, FileName, ProcessId, InitiatingProcessFileName, InitiatingProcessId, ProcessCommandLine, InitiatingProcessCommandLine, FolderPath| sort by Timestamp asc2. Live Response Process Kill Script
Section titled “2. Live Response Process Kill Script”# Terminate process and all child sub-processes by PIDfunction Kill-ProcessTree ($pidToKill) { Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq $pidToKill } | ForEach-Object { Kill-ProcessTree $_.ProcessId } Stop-Process -Id $pidToKill -Force -Verbose}
# Example: Kill malicious rundll32.exe and any child processesKill-ProcessTree -pidToKill 4912🔍 Step 3: Persistence Eradication & Dropped Files Hunt
Section titled “🔍 Step 3: Persistence Eradication & Dropped Files Hunt”Adversaries drop secondary payloads into user writable directories to survive reboots:
1. Identify Recently Dropped Executables & DLLs
Section titled “1. Identify Recently Dropped Executables & DLLs”# Scan user-writable directories for PE files dropped in the last 4 hours$searchDirs = @($env:TEMP, $env:APPDATA, $env:LOCALAPPDATA, "C:\Users\Public", "C:\PerfLogs")
Get-ChildItem -Path $searchDirs -Include *.exe,*.dll,*.bat,*.vbs,*.ps1,*.lnk -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.CreationTime -gt (Get-Date).AddHours(-4) } | Select-Object FullName, Length, CreationTime, LastWriteTime | Format-Table -AutoSize2. Check and Purge Common Persistence Locations
Section titled “2. Check and Purge Common Persistence Locations”# Check Run / RunOnce keys$regPaths = @( "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run", "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce", "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run", "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce")foreach ($reg in $regPaths) { if (Test-Path $reg) { Get-ItemProperty $reg | Select-Object * -ExcludeProperty PS* | Format-List }}
# Check recently registered Scheduled TasksGet-ScheduledTask | Where-Object { $_.Date -gt (Get-Date).AddDays(-1) -or $_.Actions.Execute -match 'temp|appdata|public|perflogs'} | Select-Object TaskName, @{N='Command';E={$_.Actions.Execute}}, State | Format-Table -AutoSize🍪 Step 4: Special Infostealer Scoping (Lumma / RedLine / Vidar)
Section titled “🍪 Step 4: Special Infostealer Scoping (Lumma / RedLine / Vidar)”If the malware was identified as an Infostealer, assume all credentials stored on the endpoint are compromised:
+-----------------------------------------------------------------------+| CRITICAL: Infostealers dump browser SQLite databases within 60 seconds|| of execution. They extract: || 1. Saved Browser Passwords (Chrome, Edge, Firefox). || 2. Active Session Cookies (M365, AWS, Salesforce, Google). || 3. Crypto Wallets (Metamask, Phantom browser extensions). || 4. Desktop VPN / RDP Profiles (AnyDesk, OpenVPN, FileZilla). |+-----------------------------------------------------------------------+Required Containment Actions:
Section titled “Required Containment Actions:”- Revoke Active User Cloud Sessions:
Terminal window Revoke-MgUserSignInSession -UserId "affected.user@company.com" - Force Cloud Password Reset: Force password change on the user’s Entra ID account and rotate security credentials.
- Notify User to Reset Personal Passwords: If user logged into personal banking or webmail from corporate device.
🛡️ Step 5: Safe Sample Extraction & IOC Hash Blocking
Section titled “🛡️ Step 5: Safe Sample Extraction & IOC Hash Blocking”- Calculate SHA256 of the malicious sample:
Terminal window Get-FileHash -Path "C:\Users\Target\AppData\Local\Temp\payload.dll" -Algorithm SHA256 - Submit hash to Defender Indicators of Compromise (IoC) list with action set to Block and remediate.
- Safely package sample into a password-protected zip (
infected) for sandbox analysis on VirusTotal or Any.Run.