
1. 恶意驱动样本概述这个恶意驱动样本是一个典型的内核级攻击框架它通过滥用Windows内核提供的合法回调机制实现隐蔽注入和进程保护。从逆向分析来看该样本主要针对64位Windows系统通过多层次的系统回调注册构建了一个完整的攻击链。样本最显著的特点是采用主动被动双重攻击模式被动模式通过PsSetLoadImageNotifyRoutine监控系统DLL加载事件主动模式通过CreateSystemThread创建内核线程主动寻找目标进程这种混合架构使得攻击具有更高的可靠性即使某一种注入方式被安全软件拦截另一种方式仍可能成功。我在分析过程中发现该样本特别关注explorer.exe、taskmgr.exe和perfmon.exe这三个高权限进程这显然是为了获取系统级权限并规避任务管理器的监控。2. 核心回调机制分析2.1 映像加载通知回调样本通过PsSetLoadImageNotifyRoutine注册了一个NotifyRoutine回调函数这是整个攻击链的起点。这个Windows内核API原本设计用于防病毒软件等合法用途允许驱动在系统加载任何PE映像DLL或EXE时获得通知。回调函数的伪代码逻辑如下void NotifyRoutine( PUNICODE_STRING FullImageName, // 加载的映像完整路径 HANDLE ProcessId, // 加载映像的进程ID PIMAGE_INFO ImageInfo // 映像信息结构体 ){ // 1. 检查进程ID有效性(排除系统关键进程) // 2. 验证当前IRQL等级为PASSIVE_LEVEL // 3. 检查映像路径是否包含\System32\或\SysWOW64\ // 4. 判断进程架构(32位/64位) // 5. 检查进程名是否为explorer.exe/taskmgr.exe/perfmon.exe // 6. 满足条件则触发注入流程 }在实际调试中我注意到该样本特别处理了WoW64进程的情况。它会通过PsGetProcessWow64Process判断当前进程是32位还是64位环境并只对64位进程进行注入这可能是为了避免在32位环境中留下更多痕迹。2.2 对象管理器回调样本还注册了ObRegisterCallback来监控进程和线程句柄操作。这是一种高级的内核保护技术通常被用于进程保护防止其他进程通过PROCESS_TERMINATE权限终止恶意进程反调试阻止调试器获取PROCESS_VM_READ/WRITE权限读取或修改内存早期预警监控对特定进程的句柄操作请求在IDA中分析对应的回调函数时我发现它对名为diamondage.exe的进程进行了特殊保护这很可能是恶意软件自身的进程名。这种保护使得常规的任务管理器或Process Explorer等工具无法终止该进程。3. 注入技术深度解析3.1 APC注入机制样本采用APCAsynchronous Procedure Call注入技术将恶意DLL加载到目标进程。APC注入的核心原理是利用线程的APC队列异步执行加载操作关键步骤如下通过PsLookupThreadByThreadId获取目标线程KeInitializeApc初始化APC对象KeInsertQueueApc将APC插入线程队列以下是样本中APC注入的关键代码片段NTSTATUS InjectAPC(HANDLE ProcessId, PWSTR DllPath) { PKAPC pApc ExAllocatePool(NonPagedPool, sizeof(KAPC)); PETHREAD pThread; // 获取目标线程 PsLookupThreadByThreadId(ProcessId, pThread); // 初始化APC KeInitializeApc(pApc, pThread, OriginalApcEnvironment, (PKKERNEL_ROUTINE)KernelRoutine, NULL, NULL, KernelMode, NULL); // 插入队列 KeInsertQueueApc(pApc, NULL, NULL, 0); // 释放资源 ExFreePool(pApc); ObDereferenceObject(pThread); return STATUS_SUCCESS; }在实际测试环境中我观察到这种注入方式有几个特点无文件落地DLL直接从内存加载难以检测内核模式的APC注入用户态安全软件难以监控高成功率只要目标线程进入可警告状态就会执行3.2 主动注入技术除了APC注入外样本还采用了更激进的主动注入方式通过CreateSystemThread创建内核线程使用KeStackAttachProcess附加到目标进程地址空间直接写入Shellcode到目标进程这种技术的优势在于完全在内核态执行绕过用户态Hook不依赖特定API对抗安全软件的API监控可以注入到高权限系统进程在IDA中可以看到样本使用的Shellcode模板如下48 83 EC 28 sub rsp, 28h 48 31 C9 xor rcx, rcx 48 31 D2 xor rdx, rdx 49 B8 00 00 00 00 00 00 00 00 mov r8, 0 49 B9 00 00 00 00 00 00 00 00 mov r9, 0 48 B8 ... mov rax, 函数地址4. 对抗分析与检测方案4.1 恶意行为特征总结通过对该样本的完整分析可以总结出以下检测指标驱动特征注册PsSetLoadImageNotifyRoutine回调使用ObRegisterCallback进行进程保护创建内核线程(CreateSystemThread)进程行为注入explorer.exe/taskmgr.exe/perfmon.exe加载路径为C:\ProgramData\DiamondAge\的DLL存在名为diamondage.exe的受保护进程代码特征Shellcode中包含特定的字节序列使用KeStackAttachProcess附加进程查找LdrLoadDll函数地址的动态解析4.2 检测与防御方案基于这些特征我建议采用以下防御措施静态检测# YARA规则示例 rule MaliciousDriver { strings: $psSetLoadImage PsSetLoadImageNotifyRoutine $obRegister ObRegisterCallbacks $createSystemThread CreateSystemThread $shellcode {48 83 EC 28 48 31 C9 48 31 D2 49 B8} condition: any of them }动态检测方案监控内核回调注册使用Windows ETW记录回调注册事件特别关注PsSetLoadImageNotifyRoutine和ObRegisterCallback进程注入检测监控explorer.exe等系统进程的DLL加载检查非Microsoft签名的模块内核线程分析扫描系统中运行的内核线程检查线程起始地址是否在可疑驱动范围内5. 逆向工程实战技巧5.1 驱动加载与调试在分析这类恶意驱动时我通常采用以下步骤使用OSR Driver Loader在测试环境中加载驱动通过WinDbg双机调试附加到测试机设置关键函数断点bp /w $thread-Process-ImageFileName malware.sys nt!PsSetLoadImageNotifyRoutine bp malware!DriverEntry使用!analyze -v分析崩溃转储重要提示分析恶意驱动必须在隔离的虚拟机环境中进行避免影响宿主系统。我通常会禁用虚拟机的网络连接并定期拍摄快照以便回滚。5.2 IDA分析技巧对于这类复杂驱动在IDA中分析时可以采用以下方法提高效率重命名关键函数根据调用关系标记回调函数对APC相关函数添加前缀APC_创建结构体// 手动定义IMAGE_INFO结构体 struct IMAGE_INFO { DWORD Characteristics; DWORD ImageBase; DWORD ImageSize; // ...其他字段 };使用IDAPython脚本自动化分析# 查找所有APC相关调用 from idautils import * from idaapi import * apc_funcs [KeInitializeApc, KeInsertQueueApc] for func in Functions(): for addr in XrefsTo(func): print(Found APC call at: %08X % addr.frm)5.3 常见问题排查在分析过程中我遇到过几个典型问题及解决方案驱动验证失败解决方法启用测试签名模式bcdedit /set testsigning on回调函数无法触发检查是否正确设置了通知回调验证目标进程是否真的加载了DLLShellcode分析困难使用WinDbg的!address命令确定内存属性使用u命令反汇编特定地址通过这次分析我深刻认识到现代恶意软件越来越倾向于滥用合法的内核机制来实现攻击。这种living-off-the-land技术使得检测变得更加困难也对我们安全研究人员提出了更高要求。在后续的工作中我会继续关注内核回调滥用方面的研究特别是微软新引入的内核保护机制如Kernel Mode Code Integrity (KMCI)等技术的实际防护效果。