--- name: fileless-malware-analysis description: > Analyze memory-only and Living Off the Land Binary (LOLBin) threats that leave minimal filesystem artifacts. Use when encountering PowerShell-based attacks, WMI persistence, process injection, .NET in-memory assemblies, or abuse of legitimate Windows binaries (mshta, certutil, rundll32, regsvr32, etc.). Covers deobfuscation, payload extraction, and execution chain reconstruction. Supports both offline forensic analysis and online threat intelligence enrichment. --- # Fileless Malware Analysis Investigate threats that operate primarily in memory or abuse legitimate system binaries, leaving minimal traces on disk. This skill covers PowerShell-based attacks, WMI persistence, process injection, .NET reflection loading, and LOLBin abuse. ## Prerequisites - **Linux**: `strings`, `base64`, `python3`, `volatility3` (memory analysis) - **Windows**: PowerShell 5.1+, `wevtutil` or Event Viewer, Sysmon (recommended) - **Python packages**: `base64`, `re`, `argparse` (standard library); `yara-python` (optional) - **Tools (recommended)**: Process Monitor, Process Hacker, Volatility 3, PowerShell ScriptBlock logging enabled - **Online APIs (optional)**: VirusTotal, Any.Run, Hybrid Analysis for behavioral correlation ## Step-by-Step Instructions ### Step 1: Identify the Fileless Execution Method Determine which fileless technique is in use by examining available artifacts. **Check PowerShell ScriptBlock logs (Windows):** ```powershell Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" | Where-Object { $_.Id -eq 4104 } | Select-Object -First 20 TimeCreated, Message | Format-List ``` **Check for WMI event subscriptions:** ```powershell Get-WMIObject -Namespace root\subscription -Class __EventFilter Get-WMIObject -Namespace root\subscription -Class __EventConsumer Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding ``` **Check for suspicious scheduled tasks:** ```powershell Get-ScheduledTask | Where-Object { $_.Actions.Execute -match "powershell|mshta|certutil|rundll32|regsvr32|wscript|cscript" } ``` **Check Sysmon logs for process injection (Event ID 8, 10):** ```powershell Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" | Where-Object { $_.Id -in @(8, 10) } | Select-Object -First 20 TimeCreated, Message ``` **Linux - check for suspicious process activity:** ```bash # Look for processes with deleted executables ls -la /proc/*/exe 2>/dev/null | grep deleted # Check for memfd-based execution ls -la /proc/*/fd 2>/dev/null | grep memfd ``` Common fileless execution categories: | Category | Indicators | |---|---| | PowerShell cradle | `IEX`, `Invoke-Expression`, `DownloadString`, `-enc` | | WMI persistence | `__EventFilter`, `CommandLineEventConsumer` | | Process injection | Hollowed processes, unexpected DLLs, thread injection | | .NET reflection | `[Reflection.Assembly]::Load`, `Assembly.Load` | | LOLBin abuse | Legitimate binaries executing unusual payloads | | Registry-resident | Payloads stored in registry keys, loaded at runtime | ### Step 2: Analyze PowerShell Scripts Extract and deobfuscate PowerShell payloads from logs, command lines, or memory. **Extract base64-encoded commands:** ```bash # Decode -EncodedCommand / -enc payloads echo "BASE64_STRING_HERE" | base64 -d | iconv -f UTF-16LE -t UTF-8 ``` **Use the deobfuscation script:** ```bash python3 scripts/powershell_deobfuscator.py --input encoded_script.ps1 --output decoded.ps1 python3 scripts/powershell_deobfuscator.py --input-string "IEX([string]::join('',( (87,104,111,97,109,105) |%{[char]$_})))" python3 scripts/powershell_deobfuscator.py --input script.ps1 --max-depth 10 --verbose ``` **Key deobfuscation patterns to look for:** - String concatenation: `'Down' + 'load' + 'String'` - Character code conversion: `[char]87 + [char]104` - Base64 layers: `[Convert]::FromBase64String()` - Invoke-Expression wrapping: `IEX(...)`, `& (...)`, `. (...)` - Backtick insertion: `` I`nv`oke-`Ex`pression `` - Format string abuse: `"{0}{1}" -f 'Inv','oke'` - Variable substitution: `$a = 'IEX'; & $a (...)` See `references/powershell-obfuscation.md` for a complete catalog. ### Step 3: Examine WMI Persistence WMI event subscriptions provide persistent, fileless execution. **Enumerate all WMI subscriptions:** ```powershell # List event filters Get-CimInstance -Namespace root/subscription -ClassName __EventFilter | Select-Object Name, Query, QueryLanguage | Format-List # List event consumers Get-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer | Select-Object Name, CommandLineTemplate | Format-List Get-CimInstance -Namespace root/subscription -ClassName ActiveScriptEventConsumer | Select-Object Name, ScriptText | Format-List # List filter-to-consumer bindings Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding | Select-Object Filter, Consumer | Format-List ``` **Extract WMI repository from disk (forensic analysis):** ```bash # WMI repository location # C:\Windows\System32\wbem\Repository\OBJECTS.DATA strings OBJECTS.DATA | grep -iE "(powershell|cmd|http|eval|exec)" | sort -u ``` **Suspicious WMI indicators:** - `ActiveScriptEventConsumer` with inline VBScript/JScript - `CommandLineEventConsumer` launching PowerShell or cmd.exe - Filters triggered by common events: `__InstanceModificationEvent` on `Win32_LocalTime` - Filters with very short polling intervals (e.g., `WITHIN 5`) ### Step 4: Detect Process Injection Identify processes that have been injected with malicious code. **Using Volatility 3 (memory dump analysis):** ```bash # List processes python3 -m volatility3 -f memory.dmp windows.pslist # Detect injected code in process memory python3 -m volatility3 -f memory.dmp windows.malfind # List loaded DLLs for suspicious processes python3 -m volatility3 -f memory.dmp windows.dlllist --pid TARGET_PID # Check for VAD (Virtual Address Descriptor) anomalies python3 -m volatility3 -f memory.dmp windows.vadinfo --pid TARGET_PID ``` **Common injection techniques to look for:** | Technique | API Indicators | Detection | |---|---|---| | Classic injection | `VirtualAllocEx` + `WriteProcessMemory` + `CreateRemoteThread` | Malfind, unexpected RWX pages | | Process hollowing | `CreateProcess(SUSPENDED)` + `NtUnmapViewOfSection` | Image path vs. memory mismatch | | APC injection | `QueueUserAPC` + `NtTestAlert` | Unexpected APC targets | | Atom bombing | `GlobalAddAtom` + `NtQueueApcThread` | Unusual atom table entries | | Early bird | `CreateProcess(SUSPENDED)` + `QueueUserAPC` before resume | Thread context anomalies | **Live system detection (Windows):** ```powershell # Check for processes with unusual parent-child relationships Get-CimInstance Win32_Process | Select-Object ProcessId, ParentProcessId, Name, CommandLine | Where-Object { $_.ParentProcessId -ne 0 } | Format-Table -AutoSize ``` ### Step 5: Analyze .NET In-Memory Assemblies Detect and extract .NET assemblies loaded directly into memory. **Memory dump analysis:** ```bash # Volatility 3 - list .NET assemblies python3 -m volatility3 -f memory.dmp windows.netscan # Extract managed heaps python3 -m volatility3 -f memory.dmp windows.vadinfo --pid TARGET_PID | grep -A5 "PAGE_EXECUTE_READWRITE" ``` **PowerShell indicators of .NET reflection loading:** ``` [Reflection.Assembly]::Load([Convert]::FromBase64String("...")) [System.Reflection.Assembly]::Load($bytes) $assembly.GetType("Namespace.Class").GetMethod("Method").Invoke($null, @(...)) Add-Type -TypeDefinition $code -Language CSharp ``` **Extract .NET assembly from base64:** ```bash # If you find a base64-encoded assembly echo "BASE64_DATA" | base64 -d > extracted_assembly.dll # Analyze with dnSpy, ILSpy, or dotPeek # On Linux, use monodis: monodis --method extracted_assembly.dll ``` ### Step 6: Investigate LOLBin Abuse Analyze abuse of legitimate Windows binaries (Living Off the Land). **Use the LOLBin detector script:** ```bash python3 scripts/lolbin_detector.py --input sysmon_export.csv python3 scripts/lolbin_detector.py --command "mshta vbscript:Execute(\"CreateObject(\"\"Wscript.Shell\"\").Run ...\")" python3 scripts/lolbin_detector.py --input process_log.json --format json --output report.json ``` **Key LOLBins to examine:** | Binary | Legitimate Use | Malicious Abuse | |---|---|---| | `mshta.exe` | Run HTML Applications | Execute VBScript/JScript, download payloads | | `certutil.exe` | Certificate management | Download files (`-urlcache`), decode base64 (`-decode`) | | `rundll32.exe` | Execute DLL functions | Execute arbitrary DLLs, JavaScript via `mshtml` | | `regsvr32.exe` | Register COM objects | Load remote SCT scriptlets (`/s /n /u /i:URL`) | | `wmic.exe` | WMI management | Execute commands, XSL script execution | | `msiexec.exe` | Install MSI packages | Install remote malicious packages | | `bitsadmin.exe` | Background transfers | Download payloads stealthily | | `cmstp.exe` | Connection Manager | UAC bypass, arbitrary command execution | | `msdt.exe` | Diagnostics tool | Follina-style command execution | See `references/lolbins-reference.md` for comprehensive patterns. ### Step 7: Extract Payloads from Memory Retrieve the actual malicious payloads from memory dumps or live analysis. **Using Volatility 3:** ```bash # Dump suspicious process memory regions python3 -m volatility3 -f memory.dmp windows.memmap --pid TARGET_PID --dump # Dump specific VAD regions flagged by malfind python3 -m volatility3 -f memory.dmp windows.malfind --pid TARGET_PID --dump # Extract files from memory python3 -m volatility3 -f memory.dmp windows.dumpfiles --pid TARGET_PID ``` **Carve PE files from memory dumps:** ```bash # Search for MZ headers in memory dump strings -t d memory.dmp | grep "This program" # Use foremost or binwalk to carve embedded files foremost -t exe,dll -i process_memory.dmp -o carved_files/ binwalk --dd='.*' process_memory.dmp ``` **Extract PowerShell script blocks from event logs:** ```powershell Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" | Where-Object { $_.Id -eq 4104 } | ForEach-Object { $_.Properties[2].Value | Out-File -Append "extracted_scripts.ps1" "# --- Script Block Boundary ---" | Out-File -Append "extracted_scripts.ps1" } ``` ### Step 8: Trace the Execution Chain Reconstruct the complete attack flow from initial execution to final payload. **Build the process tree:** ```powershell # Sysmon Event ID 1 - Process Creation Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" | Where-Object { $_.Id -eq 1 } | Select-Object TimeCreated, @{N='Cmd';E={$_.Properties[10].Value}}, @{N='ParentCmd';E={$_.Properties[21].Value}} | Format-Table -AutoSize ``` **Typical fileless attack chain:** 1. Initial vector (phishing email, malicious document, exploit) 2. First-stage loader (PowerShell cradle, mshta, wscript) 3. Download/decode next stage (certutil, bitsadmin, PowerShell) 4. In-memory execution (.NET assembly load, process injection) 5. Persistence (WMI subscription, scheduled task, registry) 6. C2 communication (HTTPS, DNS, custom protocol) **Correlate multiple log sources:** - PowerShell ScriptBlock Logging (Event ID 4104) - Sysmon Process Creation (Event ID 1) - Sysmon Network Connection (Event ID 3) - Sysmon Registry Modification (Event ID 13) - Windows Security Event Log (Event ID 4688) - Prefetch files for execution evidence **Document the chain as a timeline:** ``` [Timestamp] User opens malicious document [Timestamp] Word spawns PowerShell.exe with -enc parameter [Timestamp] PowerShell downloads stage 2 via IEX(New-Object Net.WebClient).DownloadString [Timestamp] Stage 2 loads .NET assembly via reflection [Timestamp] Injected code into svchost.exe [Timestamp] WMI persistence established [Timestamp] C2 beacon initiated to attacker domain ``` ## Output Format Document findings in a structured format: ```json { "fileless_technique": "PowerShell cradle + .NET reflection", "initial_vector": "Macro-enabled document", "execution_chain": [ {"stage": 1, "method": "PowerShell -enc", "detail": "Base64-encoded downloader"}, {"stage": 2, "method": ".NET Assembly.Load", "detail": "In-memory C# payload"}, {"stage": 3, "method": "Process injection", "detail": "Injected into svchost.exe"} ], "persistence": "WMI event subscription", "c2": {"protocol": "HTTPS", "domains": ["example.com"]}, "lolbins_used": ["powershell.exe", "mshta.exe"], "iocs": { "domains": [], "ips": [], "hashes": [], "registry_keys": [], "wmi_objects": [] } } ``` ## Tips - Enable PowerShell ScriptBlock Logging and Module Logging before analysis - Enable Sysmon with a comprehensive configuration (e.g., SwiftOnSecurity's) - Memory analysis is essential for fileless malware - capture memory early - LOLBin abuse is context-dependent: the same command may be legitimate or malicious - Multi-layer obfuscation is common; run deobfuscation iteratively - Check for AMSI bypass attempts (`[Ref].Assembly.GetType(...)`) - Registry keys like `HKCU\Software\Classes\CLSID` may store payloads - Look for payloads stored in environment variables or alternate data streams