[翻译]-用调用堆栈揭开攻击的帷幕
字数 1303 2025-08-23 18:31:34
调用堆栈分析在安全检测中的应用
1. 调用堆栈基础概念
1.1 什么是调用堆栈
调用堆栈(Call Stack)是线程特定的内存区域,用于记录函数调用关系:
- 当函数A调用函数B时,CPU会将当前指令地址(返回地址)保存到堆栈中
- 如果B再调用函数C,B中的返回地址也会被保存
- 这些返回地址可以通过堆栈遍历(Stack Walking)过程回收,重建函数调用序列
- 堆栈遍历按时间倒序列出返回地址,最新函数位于顶部
1.2 Windows调用堆栈示例
以Windows中双击notepad.exe为例,调用堆栈通常分为三部分:
- 绿色部分:操作系统基本线程初始化(所有操作中都相同)
- 红色部分:用户代码(多个模块组成,显示流程创建细节)
- 蓝色部分:Win32和本机API层(操作特定,转发到内核前的最后2-3个Windows模块)
2. 调用堆栈在安全分析中的应用
2.1 提高事件可解释性
调用堆栈提供比标准日志更深入的可见性:
- WMI启动进程分析:可区分是通过wmic.exe直接调用还是WMI事件订阅启动
- 计划任务识别:通过ubpm.dll!UbpmOpenTriggerConsumer调用识别真正的计划任务
- ZIP文档中脚本执行:通过zipfld.dll调用识别是从ZIP文件中执行的脚本
2.2 检测实例分析
2.2.1 进程相关检测
-
反射创建可疑进程(Dirty Vanity技术):
- 滥用process forking在现有进程副本中执行shellcode
- 调用堆栈显示RtlCreateProcessReflection和RtlCloneUserProcess
- 检测查询示例:
process where event.action == "start" and descendant of [process where event.action == "start" and _arraysearch(process.parent.thread.Ext.call_stack, $entry, $entry.symbol_info: ("*ntdll.dll!RtlCreateProcessReflection*", "*ntdll.dll!RtlCloneUserProcess*"))]
-
直接系统调用创建进程:
- 使用syscall指令而非NtCreateProcess API
- 检测查询示例:
process where event.action : "start" and not process.parent.thread.Ext.call_stack_summary : "ntdll.dll*" and _arraysearch(process.parent.thread.Ext.call_stack, $entry, ($entry.callsite_leading_bytes : ("*4c8bd1b8??????000f05", "*4989cab8??????000f05")))
2.2.2 文件相关检测
-
可疑的Microsoft Office嵌入式对象:
- 检测Office进程从OLE流写入可疑文件扩展名
- 检测查询示例:
file where event.action != "deletion" and process.name : ("winword.exe", "excel.exe", "powerpnt.exe") and _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: ("*!OleSaveToStream*", "*!OleLoad*")) and (file.extension : ("exe", "dll", "js", "vbs") or file.Ext.header_bytes : ("4d5a*"))
-
从未被支持的内存中进行文件重命名:
- 检测勒索软件注入可信进程后的文件操作
- 检测查询示例:
file where event.action : "rename" and process.code_signature.status : "trusted" and file.extension != null and process.thread.Ext.call_stack_summary :("ntdll.dll|kernelbase.dll|Unbacked")
2.2.3 库加载相关检测
-
未签名的打印监视器驱动程序:
- 检测打印后台服务加载未签名库
- 检测查询示例:
library where process.executable : ("?:\\Windows\\System32\\spoolsv.exe") and not dll.code_signature.status : "trusted" and _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: "*localspl.dll!SplAddMonitor*")
-
通过ROP Gadgets的DLL加载:
- 检测使用ROP绕过API监控的DLL加载
- 检测查询示例:
library where process.thread.Ext.call_stack_summary : ("ntdll.dll|*", "win32u.dll|*") and not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info: ("*ntdll.dll!Ldr*", "*KernelBase.dll!LoadLibrary*"))
-
LdrpKernel32覆盖规避:
- 检测通过覆盖引导DLL名称劫持进程
- 检测查询示例:
library where _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info : "*!BaseThreadInitThunk*") and not _arraysearch(process.thread.Ext.call_stack, $entry, $entry.symbol_info ("?:\\Windows\\System32\\kernel32.dll!BaseThreadInitThunk*"))
2.2.4 注册表相关检测
可疑的远程注册表修改:
- 检测远程注册表服务修改可执行文件或脚本相关项
- 检测查询示例:
registry where event.action == "modification" and process.name : "svchost.exe" and process.thread.Ext.call_stack_summary : "*regsvc.dll|rpcrt4.dll*" and (registry.data.strings : ("*.exe*", "*.dll*") or registry.path : ("HKLM\\SYSTEM\\ControlSet*\\Services\\*\\ServiceDLL"))
3. 调用堆栈分析的优势
- 减少误报:通过调用上下文更准确判断行为性质
- 减少漏报:检测传统方法可能忽略的高级规避技术
- 提高可解释性:提供更丰富的事件上下文信息
- 增强检测能力:识别API滥用、代码注入等高级攻击技术
4. 总结
调用堆栈分析为安全检测提供了三方面重要价值:
- 识别已知恶意行为模式
- 减少标准EDR事件的误报
- 简化行为解释过程
通过结合调用堆栈信息与传统检测方法,可以构建更强大、更准确的安全检测体系,有效应对现代高级威胁。