借微软签名二进制骗过 EDR:2026 年最稳健的免杀绕过
DLL 侧加载(DLL Sideloading)借微软签名二进制的信任链,让恶意 DLL 在「Microsoft 签名进程」的光环下加载,EDR 对用户态写入与内存执行天然高看一眼。2026 年红队最稳健的 EDR 绕过手段,APT41、Lazarus、MuddyWater 都在用。
一、技术全貌:这是什么?
如果说 2023 年是「直接系统调用 + Unhook」的天下,2024-2025 年是「内核回调移除 + BYOVD」的主场,那么到了 2026 年,在微软驱动黑名单与 HVCI 的双重夹击下,一个看似「上古」的技术反而成了红队手里最稳的一张牌——DLL 侧加载(DLL Sideloading)。
所谓 DLL 侧加载,是指找到一个微软官方签名、但加载 DLL 时 搜索顺序可被劫持的合法二进制,把我们的恶意 DLL 以同名丢进它所在的可写目录,再启动这个签名程序。于是恶意代码借壳运行在「Microsoft 签名进程」的信任光环之下,EDR 对用户态的内存写入、模块加载、线程执行天然「高看一眼」,行为检测阈值被直接拉高。
RingSafe 在 2026 年 7 月的复盘把当前 EDR 绕过划为四大家族,其中明确写道:DLL 侧加载(通过签名二进制)至今仍高度有效(still highly effective)。APT41 借 Trend Micro 签名二进制侧载、Lazarus 借 Sangfor 签名驱动侧载、MuddyWater 借 SentinelOne 与 Fortemedia 签名二进制侧载——国家级对手都在用,因为它稳。
一句话:它不杀 EDR、不拦 EDR、不断 EDR,它只是「借一个好人身份干坏事」。
二、为什么这个技术如此重要
传统 EDR 压制手段有三个绕不开的死穴:
而 DLL 侧加载不杀、不拦、不断,它只是「借壳」。更关键的是:绝大多数 EDR 对 Microsoft 签名进程的内存读写、模块加载事件默认信任,侧载进来的 DLL 继承了这份信任,ETW 线程审计、行为关联引擎都很难把它和合法加载区分开。
这就是为什么在「上下文联动分析」成为主流的 2026 年,依赖特征码与简单 API 混淆的时代终结后,侧加载反而逆势回潮——它攻击的不是 EDR 的检测能力,而是 EDR 的信任模型本身。
三、技术原理解析
要点一:DLL 搜索顺序的「应用目录优先」
当一个 Windows 程序不指定完整路径去 LoadLibrary 一个 DLL 时,系统会按固定顺序查找。默认顺序里,应用程序所在目录排在第一位,先于 C:WindowsSystem32:
1. 应用程序所在目录 ← 攻击者把恶意 DLL 放这里
2. C:WindowsSystem32
3. C:WindowsSystem
4. C:Windows
5. 当前工作目录
6. 系统 PATH
7. 用户 PATH只要我们在「签名二进制」同目录放一个同名、且导出函数签名匹配的恶意 DLL,Windows 就会先加载我们的版本。
要点二:签名信任链的「光环效应」
EDR 的进程树/父子关系分析通常信任微软签名父进程拉起的子模块。恶意 DLL 被加载进 OneDrive.exe、Teams.exe、pdf24.exe 这类签名进程后,其内存执行、网络连接都被打上「可信进程」的标签。签名校验的是包装器,而不是它加载的内容——这是整个技术的命门。
要点三:可侧载目标的「NAME NOT FOUND」挖掘
最聪明的挖掘方式是用 Sysinternals Process Monitor:过滤 Operation = CreateFile、Result = NAME NOT FOUND、Path ends with .dll。任何签名二进制对某个 DLL 返回 NAME NOT FOUND,都是潜在侧载点。公开已知的稳定目标包括:
关键代码示例(演示用,仅授权实验环境)
下面是一段最小化演示 DLL(以 version.dll 为例),其 DllMain 在校验当前目录合法后仅弹出计算器,用于验证侧载链路是否打通。真实攻击会用 C2 beacon 替换 payload,本文不提供任何武器化代码。
// payload.c —— DLL 侧加载演示模板(良性,仅 calc.exe)
#include <windows.h>
// 演示用:仅启动计算器验证链路,不承载任何恶意逻辑
void demo_payload(void) {
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
CreateProcessA("C:\Windows\System32\calc.exe", NULL,
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
}
BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, LPVOID reserved) {
if (reason == DLL_PROCESS_ATTACH) {
demo_payload();
}
return TRUE;
}
// 必须导出宿主期望的函数,否则签名程序会因缺失导出而崩溃。
// version.dll 常见导出(保留空实现即可,重点是 DllMain 已执行):
__declspec(dllexport) DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR p, LPDWORD h) { return 0; }
__declspec(dllexport) BOOL WINAPI GetFileVersionInfoW(LPCWSTR p, DWORD h, DWORD s, LPVOID d) { return FALSE; }
__declspec(dllexport) DWORD WINAPI VerQueryValueW(LPCVOID b, LPCWSTR s, LPVOID* p, PUINT l) { return 0; }用 MinGW 编译为同名 DLL 投递到宿主目录:
x86_64-w64-mingw32-gcc -shared -o version.dll payload.c -luser32OPSEC 提醒:真实侧载必须精确匹配宿主期望的导出表(可用
dumpbin /exports或objdump逆向确认),否则宿主进程因缺导出直接崩溃,反而暴露痕迹;同时侧载 DLL 自身建议经合法签名或做内存加载,避免落地即被杀。
实战应用场景
初始访问后的「免杀落地」:钓鱼/漏洞拿到一个低权限 foothold,把「签名二进制 + 同名恶意 DLL」打包进 ISO/ZIP 诱导双击,恶意代码在可信进程内执行,绕开进程创建类检测。
EDR 内存扫描规避:合法进程上下文内的内存执行,被 ETW 与行为关联引擎归类为「白进程行为」,RWX 区段、远程线程等特征被信任光环稀释。
持久化与横向:配合计划任务/服务,把侧载目录固化,重启后自动在签名进程下复活。
国家级 APT 标配:MuddyWater 借 SentinelOne 的
fmapp.exe、sentinelmemoryscanner.exe侧载;APT41 借 Trend Micro 签名二进制;Lazarus 借 Sangfor 签名驱动——证明该技术在真实战场上的鲁棒性。