EDR内存与行为分析"

admin 2026-10-16 12:35:09 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

EDR内存与行为分析

原创

pandazhengzheng
pandazhengzheng

安全分析与研究

2026年9月18日 22:00
广东

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

目录

  1. 内存区域分类
  2. 内存扫描
  3. 查询进程信息
  4. 调用栈分析
  5. 线程状态分析
  6. 性能影响
  7. 熵值分析与加密 payload 检测
  8. 行为序列与规则引擎
  9. pe-sieve 与 moneta 检测原理
  10. 小结

1. 内存区域分类

1.1 PE 映射到内存

启动 .exe 时,PE 文件中的节区作为块完整拷入内存。

 EXE                              Process
┌──────────┐                     ┌──────────────┐
│ Header   ├────────────────────►│ Header       │
├──────────┤                     ├──────────────┤
│          │                     │ .text        │  Backed RX
│ .text    ├────────────────────►│              │
├──────────┤                     ├──────────────┤
│ .data    ├────────────────────►│ .data        │  Backed RW
└──────────┘                     ├──────────────┤
                                 │ Virtual      │  Unbacked RW
                                 │ Alloc()      │
                                 └──────────────┘

1.2 Backed vs Unbacked

来自 PE 文件映像的内存区域称为 backed(映像支持的)。它们可信,因为是磁盘 PE 文件的 1:1 副本(已被 AV 扫描)。内存区域\"backed\"于磁盘文件。也称为 IMAGE 区域。

进程通过 VirtualAlloc() 分配额外内存时,是 unbacked(无映像支持的)。也称为 USER 或 PRIVATE 内存。没有文件\"backing\"此区域。

1.3 内存区域属性

  • USER/PRIVATE/Unbacked:坏,潜在恶意,shellcode;
  • IMAGE/Backed:好,相当可信。

主要因为 shellcode(来自 exploit 或进程注入)通常位于 PRIVATE 内存。线程也应从 backed 区域启动。PRIVATE RWX 内存更可疑。

1.4 可信与不可信内存区域

可信的 IMAGE 类型内存区域(IMG):

Memory Regions Good

不可信的 PRIVATE 类型内存区域(PRV):

Memory Regions Bad

1.5 Copy-On-Write(COW)

内存页的一个酷特性是 Copy-On-Write(写时复制)。内存扫描器能检查内存页是否被写入,这对只读 .text 节区(应在进程间共享)是不寻常的。moneta 通过 PSAPI_WORKING_SET_EX_BLOCK(来自 PSAPI_WORKING_SET_EX_INFORMATION 结构)使用此特性。

Data-only 攻击(如 AMSI patch 或 ETW patch)受偏好,因为它们不触发 COW(修改的是已可写的页,而非 .text)。

1.6 内存类型的 VAD 视角

Windows 内核通过 VAD(Virtual Address Descriptor)树管理进程虚拟地址空间。VAD 的 Type 字段决定内存类型:

VAD Type 含义 可信度 来源
MEM_IMAGE 映像映射(PE 加载) 高 LoadLibrary /NtMapViewOfSection(SEC_IMAGE)
MEM_MAPPED section 映射(非映像) 中 MapViewOfFile /NtMapViewOfSection(SEC_COMMIT)
MEM_PRIVATE 私有内存(VirtualAlloc) 低 VirtualAlloc /VirtualAllocEx

关键:VAD 类型由映射方式决定,一旦通过 SEC_IMAGE 映射,永久为 MEM_IMAGE,后续覆写不改变 VAD 类型。

1.7 保护属性的可疑组合

保护属性 可疑度 说明
PAGE_EXECUTE_READWRITE (RWX) 极高 合法代码极少用 RWX
PAGE_EXECUTE_READ (RX)+ Private 高 私有可执行 = shellcode
PAGE_EXECUTE_READ (RX)+ Image 低 合法映像代码
PAGE_READWRITE (RW) 低 数据区域
PAGE_EXECUTE_WRITECOPY (RWX Copy) 中 映像节区可写副本

1.8 参考资源

  • Windows Processes: Nefarious Anomalies and You: Memory Regions
  • Bypassing pe-sieve and moneta
  • Solving the Unhooking Problem
  • NtCreateSection + NtMapViewOfSection Code Injection

2. 内存扫描

2.1 内存签名扫描

内存签名扫描检测内存中的恶意代码,在 .text 或数据节区(栈、堆、.data 等)。

                        Event
                          │
 Process                  ▼
┌───────────┐        ┌───────────┐
│           │        │           │
│ .text     ◄────────┤    EDR    │  Read + Scan
│  (bad)    │        │           │
│ .data     ◄────────┤           │
│  (bad)    │        └───────────┘
└───────────┘

基本与 AV 签名扫描相同:grep 或 yara 内存内容匹配已知恶意签名。

2.2 内存扫描的性能

内存扫描是性能密集操作。不持续进行,而是依赖触发器。

2.3 扫描触发时机

触发类型 说明 频率
周期性 固定间隔扫描 每 30s-数小时
事件触发 敏感事件发生时扫描 按需
可疑进程 高风险进程定期扫描 按进程
全量 系统空闲时全量扫描 每天/每周

2.4 扫描范围

EDR 通过 NtQueryVirtualMemory 枚举进程虚拟地址空间,筛选可执行区域:

MEMORY_BASIC_INFORMATION mbi;
PVOID addr = NULL;
while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi))) {
    if (mbi.State == MEM_COMMIT &&
        (mbi.Protect & PAGE_EXECUTE || mbi.Protect & PAGE_EXECUTE_READ ||
         mbi.Protect & PAGE_EXECUTE_READWRITE)) {
        if (mbi.Type == MEM_PRIVATE) {
            // Private+Execute:强可疑,重点扫描
            scanRegion(hProc, mbi.BaseAddress, mbi.RegionSize);
        } else if (mbi.Type == MEM_IMAGE) {
            // Image+Execute:校验完整性
            verifyImageIntegrity(hProc, mbi.BaseAddress, mbi.RegionSize);
        }
    }
    addr = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
}

2.5 YARA 内存扫描

rule shellcode_generic {
    strings:
        $s1 = { 4C 8B D1 B8 }          // mov r10,rcx; mov eax (syscall stub)
        $s2 = { FC 48 83 E4 F0 }       // cld; and rsp,0xF0 (shellcode prologue)
        $s3 = { 65 48 8B 04 25 60 00 00 00 } // mov rax, gs:[0x60] (PEB access)
    condition:
        any of ($s*)
}

rule reflective_loader {
    strings:
        $mz = { 4D 5A }               // MZ header
        $pe = { 50 45 00 00 }         // PE signature
    condition:
        $mz at 0 and $pe
}

2.6 内存扫描的规避

规避技术 原理 效果
Module Stomping shellcode 在 MEM\_IMAGE 不在 Private+Execute 扫描范围
Sleep Mask 睡眠时加密自身 扫描时看到密文
避免常见字节模式 不用典型 shellcode 序言 YARA 不匹配
分散内存 拆分为小块 降低单区域可疑度

3. 查询进程信息

3.1 事件富化

EDR 接收事件后,会尝试富化它:

  • 进程信息(如可执行名和命令行参数)
  • 内存扫描(可能)
  • 进程映像文件扫描(罕见)
                                                                     ┌──────────────┐
        ┌─────────────┐ EtwWrite() ┌──────────┐   Kernel callbacks   │              │
        │ Process     ├───────────►│          ├─────────────────────►│              │
        │             │            │          │                      │              │
        ├─────────────┤            │   OS     │   ETW                │    EDR       │
        │  ntdll.dll  │            │          ├─────────────────────►│              │
        │             │ syscall    │          │   ETW-TI             │              │
        │             ├───────────►│          ├─────────────────────►│              │
        │             │            │          │                      │              │
        │             │            └──────────┘                      │              │
        │             │                                              │              │
        │             │◄─────────────────────────────────────────────│              │
        │             │   Query Process Information                  │              │
        │             │   (NtQueryInformationProcess,                │              │
        │             │    memory scan, ...)                         │              │
        └─────────────┘                                              └──────────────┘

3.2 富化查询的信息

信息 获取方式 可信度
映像路径 QueryFullProcessImageName 高
命令行 PEB ProcessParameters.CommandLine 中(可被篡改)
父进程 PID NtQueryInformationProcess(ProcessBasicInformation) 中(可被篡改)
进程签名 查询映像文件的签名状态 高
进程时间 GetProcessTimes 高
线程列表 NtQuerySystemInformation 高
内存区域 NtQueryVirtualMemory 高
句柄表 NtQuerySystemInformation(SystemHandleInformation) 高

3.3 PEB 解析

EDR 通过解析 PEB(Process Environment Block)获取进程信息:

typedef struct _PEB {
    BOOLEAN InheritedAddressSpace;
    BOOLEAN ReadImageFileExecOptions;
    BOOLEAN BeingDebugged;
    BOOLEAN BitField;
    HANDLE Mutant;
    PVOID ImageBaseAddress;
    PPEB_LDR_DATA Ldr;                    // 已加载模块链表
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;  // 命令行等
    PVOID SubSystemData;
    PVOID ProcessHeap;
    // ...
} PEB;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
    // ...
    UNICODE_STRING CommandLine;           // 命令行
    UNICODE_STRING ImagePathName;         // 映像路径
    // ...
} RTL_USER_PROCESS_PARAMETERS;

注意:PEB 位于进程自身内存,可被进程自身篡改(命令行欺骗、映像欺骗——见第 4 篇)。

3.4 信息可信度

并非所有信息同等可信:

信息 可信度 原因
映像路径(QueryFullProcessImageName) 高 内核查询,不易篡改
命令行(PEB) 中 PEB 在进程内存,可篡改
父进程 PID 中 可通过属性列表篡改
签名状态 高 磁盘文件签名验证
内存区域属性 高 VAD 在内核,不易篡改

4. 调用栈分析

4.1 调用栈回溯的原理

EDR 在 hook 处理例程中回溯当前线程调用栈,检查调用方合法性。x64 Windows 使用基于表的栈回溯(table-based unwinding)。


EDR内存与行为分析" 网络安全文章

EDR内存与行为分析"

本文系统解析EDR内存与行为分析技术,核心在于通过内存区域分类区分可信的IMAGE区域与可疑的PRIVATE区域,结合内存扫描、YARA规则、进程信息富化等手段检测shellcode与进程注入。文章强调PRIVATE可执行内存为高危信号,建议EDR重点监控此类区域,并利用COW特性检测代码覆写。
牟林:阴谋暴露了!难怪特朗普要格陵兰岛" 网络安全文章

牟林:阴谋暴露了!难怪特朗普要格陵兰岛"

文章报道特朗普宣布美国与丹麦就格陵兰岛达成协议,美方获得对该岛安全事务的永久控制权,丹麦承认协议但保留名义主权。作者从中国视角分析认为这是不平等协议,丹麦被迫让渡实际主权,并探讨特朗普借此捞取政治资本、影响中期选举及俄乌局势等动机。
秦安:十几个人决定世界命运的游戏该结束了!" 网络安全文章

秦安:十几个人决定世界命运的游戏该结束了!"

本文为秦安战略公众号评论文章,批评美联储加息25个基点至3.75%-4.00%是维护美元霸权的垂死挣扎,认为加息旨在增加美元吸引力、促使资本回流,属预期管理手段。文章指出美国国债超42万亿美元,每日利息约40.8亿美元,加息将加重美国债务压力,呼吁结束少数人决定世界命运的游戏。
中文互联网基础语料4.0等三类高质量数据集正式发布" 网络安全文章

中文互联网基础语料4.0等三类高质量数据集正式发布"

2026年国家网络安全宣传周上正式发布三类高质量数据集,包括中文互联网基础语料4.0(120GB)、网络安全数据集1.0(含5个子数据集)及AIGC检测数据集(10万条文本和10万条图片数据),旨在为AI大模型训练及网络安全能力提升提供可信数据支撑。相关数据可通过中文互联网语料资源平台注册获取。
评论:0   参与:  0