深入分析调试CVE-2024-30090-ks.sys内核流服务权限提升漏洞
字数 6210 2025-10-01 14:05:52

CVE-2024-30090 内核流服务权限提升漏洞深入分析与调试教学

0x00 漏洞信息

  • 漏洞编号:CVE-2024-30090
  • 漏洞类型:内核竞争条件漏洞 (Race Condition)
  • 漏洞组件:Windows 内核流媒体服务驱动程序 ks.sys
  • 漏洞影响:权限提升 (Privilege Escalation)
  • 根本原因:Windows 权限验证机制在流媒体服务 (Kernel Streaming) 处理设备属性请求时存在缺陷,攻击者可通过构造恶意数据结构,利用竞争条件实现任意 IOCTL 调用原语 (Arbitrary IOCTL Primitive),从而以内核权限执行受限操作。

0x01 基本概念

1. ks.sys 的功能

ks.sys 是 Windows 内核流媒体 (Kernel Streaming, KS) 子系统的核心驱动程序。

  • 核心作用:提供内核级别的高效多媒体流数据处理。
  • 主要功能
    • 实时媒体流处理:支持音频、视频流的实时传输。
    • 低延迟:直接在内核操作,为游戏、视频会议等应用提供低延迟保障。
    • 资源管理:管理多媒体设备(如声卡、摄像头)的资源分配与通信。

2. ks.sys 的问题

ks.sys 出现问题或存在漏洞,可能导致:

  • 音频/视频播放异常
  • 系统蓝屏 (BSOD)
  • 多媒体设备无法正常工作
  • 权限提升等安全风险

3. 条件竞争 (Race Condition)

  • 官方概念:当多个线程并发访问共享资源(代码、变量、文件等),且缺乏适当的锁或同步机制时发生。
  • 在本漏洞中的应用:攻击者通过精确控制两个线程的执行时序,在一个线程(内核)读取并验证数据后、使用数据前,由另一个线程(用户态)篡改该数据,从而绕过安全检查。

4. CPU 亲和性 (CPU Affinity)

  • 作用:将特定线程绑定到指定的 CPU 核心上运行。
  • 目的:提高竞争条件漏洞利用的成功率。通过将触发线程和干扰线程绑定到不同的物理核心,确保它们能真正并行执行,最大化竞争窗口的利用机会,避免线程调度带来的不确定性。

5. ks 事件 (Kernel Streaming Events)

  • 事件集 (Event Set):一组可供侦听器请求通知的相关事件(如设备状态改变、流位置更改)。
  • 注册机制:侦听器通过调用 KsSynchronousDeviceControl 函数,并使用 IOCTL_KS_ENABLE_EVENT 控制码,附带指向 KSEVENTKSEVENTDATA 结构体的指针来注册事件通知。
  • 微型驱动支持:通过提供包含处理例程指针的 KSEVENT_ITEM 结构来描述对事件的支持。

0x02 工具与环境

  1. 调试工具
    • IDA Pro x64:用于静态分析驱动模块。
    • WinDbg x64:用于内核动态调试。
  2. 目标机环境
    • 操作系统:Windows 11 23H2
    • 版本号:Build 10.0.22621.3672
  3. 目标模块
    • ks.sys:漏洞所在的核心驱动。
    • ksthunk.sys:与内核流处理相关的另一个模块。
  4. 调试配置:配置好双机内核调试环境(宿主机调试目标机)。

0x03 利用代码分析

利用代码分为两个部分:Parent 进程 (64位) 和 Child 进程 (实现核心利用)。

Parent 部分

1. GetKernelBase 函数

  • 目的:动态获取 Windows 内核模块 ntoskrnl.exe 的基地址。
  • 原理与步骤
    1. 查询所需缓冲区大小:首次调用 NtQuerySystemInformation 函数,查询 SystemModuleInformation 类别,传入 NULL 指针,函数返回所需缓冲区大小 dwSize
    2. 分配内存并获取信息:根据 dwSize 分配内存,再次调用 NtQuerySystemInformation 获取完整的系统模块信息列表 (PSYSTEM_MODULE_INFORMATION)。
    3. 遍历查找:遍历模块列表,通过比对模块名(如 \SystemRoot\system32\ntoskrnl.exe)找到 ntoskrnl.exe 模块。
    4. 返回基址:返回找到模块的 ImageBaseAddress
  • 作用:为计算内核符号(如 nt!SeDebugPrivilege)的实际地址提供基准。

2. 传递地址

  • 将获取到的内核基址通过命令行参数传递给 Child 进程。
  • Parent 进程随后等待 Child 进程执行。

Child 部分

整体流程

  1. 接收 Parent 传来的内核基址。
  2. 检测 CPU 核心数:必须 >=2,否则无法实现可靠并行竞争。
  3. 进入核心利用函数 ExploitIoctlKsEnableEvent
  4. 利用成功后,创建 SYSTEM 权限的 cmd 进程 (spawn_cmd_system)。

1. ExploitIoctlKsEnableEvent 函数

  • 目的:操纵内核时钟驱动 (KSCATEGORY_CLOCK) 的事件处理机制,利用竞争条件篡改内核工作项对象 (KsWorkerObject) 指针,实现任意地址写入或代码执行。
  • 关键步骤
    1. 初始化数据结构
      • 指定事件类型为 KSEVENT_CLOCK_INTERVAL_MARK
      • 设置 KsWorkerObject 指向 target_addr - 0x5C (目的是覆盖 KSWORKITEM 结构中的回调函数指针)。
    2. 绑定 CPU 与启动干扰线程
      • 将主线程绑定到特定 CPU 核心。
      • 启动 flip_thread 线程,高频翻转 g_ksevent.Flags(在 KSEVENT_TYPE_ENABLEKSEVENT_TYPE_QUERYBUFFER 之间切换),制造竞争条件。
    3. 主循环(3次尝试)
      • 打开设备并启动:打开时钟设备,设置其状态为 KSSTATE_RUN,激活内部事件处理。
      • 发送恶意 IOCTL:通过 DeviceIoControl 发送 IOCTL_KS_ENABLE_EVENT 请求。
        • 输入缓冲区溢出:故意使用超长输入缓冲区 (sizeof(KSEVENT) + 0x100)。
        • 竞争窗口flip_thread 线程在驱动校验数据后、使用数据前,将 Flags 从高权限 (QUERYBUFFER) 改为低权限 (ENABLE) 以绕过二次检查。
      • 成功处理:若 DeviceIoControl 成功返回,说明竞争成功,内核会错误地将用户态 g_eventData 作为工作项处理。等待内核调度执行目标代码。
    4. 清理与重试:每次尝试后重置设备状态。3次尝试机制提高稳定性。

2. pin_name_to_cpu 函数

  • 功能:将当前线程绑定到指定的 CPU 核心。
  • 步骤
    1. GetCurrentThread 获取当前线程句柄。
    2. 通过位运算生成目标 CPU 的亲和性掩码(如 CPU0: 0x01, CPU1: 0x02)。
    3. 调用 SetThreadAffinityMask 设置线程亲和性。

3. xCreateThread 函数

  • 功能:封装 CreateThread,简化线程创建并增强错误处理。
  • 参数:线程函数地址 func,参数 lpParam,线程 ID 指针 pThreadId,失败退出标志 bExitOnFailure
  • 返回值:成功返回线程句柄,失败根据标志退出或报错。

4. 触发循环

  • 外层循环:控制成功次数 (inc_count < 3)。
  • 内层循环:持续尝试触发竞争条件。
    • KsOpenDefaultDevice 打开时钟设备。
    • SetClockState(hClockDevice, KSSTATE_RUN) 启动设备。
    • 设置 g_ksevent.Flags = KSEVENT_TYPE_QUERYBUFFER
    • 调用 DeviceIoControl 发送恶意请求。
    • 若成功,等待 (Sleep(1500)),停止设备,计数加一,跳出内层循环。

5. spawn_cmd_system 函数

  • 目的:创建 SYSTEM 权限的 cmd.exe 进程。
  • 步骤
    1. 获取 Winlogon PID:调用 GetProcessIDByName(L"winlogon.exe")。Winlogon 进程通常以 SYSTEM 权限运行。
    2. 打开进程句柄OpenProcess(PROCESS_CREATE_PROCESS, ...) 获取 Winlogon 进程句柄。
    3. 创建进程:调用 CreateProcessFromHandle (自定义函数),以 Winlogon 为父进程创建 cmd.exe,子进程继承 SYSTEM 权限。
    4. 清理资源:关闭句柄。

6. GetProcessIDByName 函数

  • 功能:通过进程名查找 PID。
  • 步骤
    1. CreateToolhelp32Snapshot 创建进程快照。
    2. 使用 Process32FirstProcess32Next 遍历快照。
    3. 比对 szExeFile 字段寻找目标进程。
    4. 找到返回 PID,否则返回 0。

7. CreateProcessFromHandle 函数

  • 功能:创建指定父进程的新进程。
  • 步骤
    1. 初始化 STARTUPINFOEX 结构。
    2. 初始化进程属性列表 (InitializeProcThreadAttributeList)。
    3. 设置 PROC_THREAD_ATTRIBUTE_PARENT_PROCESS 属性,将父进程指定为传入的 hProcess
    4. 调用 CreateProcess 创建 cmd.exe,并指定 EXTENDED_STARTUPINFO_PRESENT 标志使属性生效。

0x04 调试分析与原理解析

1. 调用链与漏洞原理

  • 漏洞触发点KsIncrementCountedWorker 函数中的 InterlockedIncrement 调用。该函数是一个增量原语 (Increment Primitive),会增加我们提供的地址处的值。
  • 核心利用链
    CKSThunkDevice::DispatchIoctl -> CKSAutomationThunk::ThunkEnableEventIrp -> KsSynchronousIoControlDevice -> KspEnableEvent -> ... -> KsGenerateEvent -> KsIncrementCountedWorker
  • 原理简述
    1. 设置 Flags = KSEVENT_TYPE_QUERYBUFFER,使请求进入高权限处理路径,此时 RequestorMode 被设置为 KernelMode,绕过许多检查。
    2. 利用竞争条件,在 CKSAutomationThunk::ThunkEnableEventIrp 复制数据到内核缓冲区后、调用 KsSynchronousIoControlDevice 前,通过干扰线程将 Flags 改为 KSEVENT_TYPE_ENABLE
    3. 内核后续处理 (KspEnableEvent) 看到低权限 Flags,省略了严格的检查。
    4. 最终,恶意构造的 KSEVENTDATA 结构被传递给 KsIncrementCountedWorker,其参数 (Worker) 被控制为 NtSeDebugPrivilegeVA - 0x5C
    5. KsIncrementCountedWorker 内部计算 Worker + 0x17*4 (0x5C) 正好指向 NtSeDebugPrivilegeVA,并对其执行增量操作。

2. 为何是 SeDebugPrivilege 和 3 次?

  • SeDebugPrivilege 是内核中的一个全局变量,其值控制着是否允许调试高权限进程。
  • 普通进程的 SeChangeNotifyPrivilege 通常被初始化为 0x17 (23)。
  • SeDebugPrivilege 被初始化为 0x14 (20)。
  • nt!PsOpenProcess 会调用 nt!SeSinglePrivilegeCheck 检查当前进程的权限是否与 SeDebugPrivilege 的值匹配。
  • 利用目标:将 SeDebugPrivilege 的值从 0x14 增加到 0x17,使其与普通进程的权限值匹配,从而绕过检查,获得 SeDebugPrivilege 权限。
  • 3次循环:因为需要增加 3 次 (0x14 -> 0x15 -> 0x16 -> 0x17)。

3. 关键调试断点与观察

  1. 断点于 CKSAutomationThunk::ThunkEnableEventIrp:观察传入的 IRP 和请求参数。验证 Flags 的初始值 (0x400 / KSEVENT_TYPE_QUERYBUFFER)。
  2. 断点于 KsSynchronousIoControlDevice:观察调用参数,确认输入缓冲区内容和 RequestorMode 已成为 KernelMode
  3. 断点于 KspEnableEvent:观察分支判断,验证竞争成功后传入的 Flags 已变为 KSEVENT_TYPE_ENABLE,从而走入低权限检查分支。
  4. 断点于 KsGenerateEventKsIncrementCountedWorker:观察 NotificationType 和传入的 Worker 参数,确认最终计算出的地址正是 nt!SeDebugPrivilege 的地址。
  5. 监视 nt!SeDebugPrivilege 内存地址:在调试器中持续查看该地址的值,观察其从 0x14 经过三次调用后变为 0x17 的过程。

0x05 复现结果

成功利用该漏洞后:

  1. Child 进程中的三次竞争条件尝试均成功触发。
  2. nt!SeDebugPrivilege 的值从 0x14 被递增至 0x17
  3. 随后调用 spawn_cmd_system 函数。
  4. 系统成功弹出一个以 SYSTEM 权限运行的 cmd.exe 命令提示符窗口。
  5. 至此,实现了从普通用户权限到最高系统权限的提升。

免责声明:本文档仅用于安全研究与教学目的。请勿将其用于任何非法或恶意活动。

CVE-2024-30090 内核流服务权限提升漏洞深入分析与调试教学 0x00 漏洞信息 漏洞编号 :CVE-2024-30090 漏洞类型 :内核竞争条件漏洞 (Race Condition) 漏洞组件 :Windows 内核流媒体服务驱动程序 ks.sys 漏洞影响 :权限提升 (Privilege Escalation) 根本原因 :Windows 权限验证机制在流媒体服务 ( Kernel Streaming ) 处理设备属性请求时存在缺陷,攻击者可通过构造恶意数据结构,利用竞争条件实现 任意 IOCTL 调用原语 (Arbitrary IOCTL Primitive) ,从而以内核权限执行受限操作。 0x01 基本概念 1. ks.sys 的功能 ks.sys 是 Windows 内核流媒体 ( Kernel Streaming , KS) 子系统的核心驱动程序。 核心作用 :提供内核级别的高效多媒体流数据处理。 主要功能 : 实时媒体流处理 :支持音频、视频流的实时传输。 低延迟 :直接在内核操作,为游戏、视频会议等应用提供低延迟保障。 资源管理 :管理多媒体设备(如声卡、摄像头)的资源分配与通信。 2. ks.sys 的问题 若 ks.sys 出现问题或存在漏洞,可能导致: 音频/视频播放异常 系统蓝屏 (BSOD) 多媒体设备无法正常工作 权限提升等安全风险 3. 条件竞争 (Race Condition) 官方概念 :当多个线程并发访问共享资源(代码、变量、文件等),且缺乏适当的锁或同步机制时发生。 在本漏洞中的应用 :攻击者通过精确控制两个线程的执行时序,在一个线程(内核)读取并验证数据后、使用数据前,由另一个线程(用户态)篡改该数据,从而绕过安全检查。 4. CPU 亲和性 (CPU Affinity) 作用 :将特定线程绑定到指定的 CPU 核心上运行。 目的 :提高竞争条件漏洞利用的成功率。通过将触发线程和干扰线程绑定到不同的物理核心,确保它们能 真正并行执行 ,最大化竞争窗口的利用机会,避免线程调度带来的不确定性。 5. ks 事件 (Kernel Streaming Events) 事件集 (Event Set) :一组可供侦听器请求通知的相关事件(如设备状态改变、流位置更改)。 注册机制 :侦听器通过调用 KsSynchronousDeviceControl 函数,并使用 IOCTL_KS_ENABLE_EVENT 控制码,附带指向 KSEVENT 和 KSEVENTDATA 结构体的指针来注册事件通知。 微型驱动支持 :通过提供包含处理例程指针的 KSEVENT_ITEM 结构来描述对事件的支持。 0x02 工具与环境 调试工具 : IDA Pro x64 :用于静态分析驱动模块。 WinDbg x64 :用于内核动态调试。 目标机环境 : 操作系统 :Windows 11 23H2 版本号 :Build 10.0.22621.3672 目标模块 : ks.sys :漏洞所在的核心驱动。 ksthunk.sys :与内核流处理相关的另一个模块。 调试配置 :配置好 双机内核调试 环境(宿主机调试目标机)。 0x03 利用代码分析 利用代码分为两个部分: Parent 进程 (64位) 和 Child 进程 (实现核心利用)。 Parent 部分 1. GetKernelBase 函数 目的 :动态获取 Windows 内核模块 ntoskrnl.exe 的基地址。 原理与步骤 : 查询所需缓冲区大小 :首次调用 NtQuerySystemInformation 函数,查询 SystemModuleInformation 类别,传入 NULL 指针,函数返回所需缓冲区大小 dwSize 。 分配内存并获取信息 :根据 dwSize 分配内存,再次调用 NtQuerySystemInformation 获取完整的系统模块信息列表 ( PSYSTEM_MODULE_INFORMATION )。 遍历查找 :遍历模块列表,通过比对模块名(如 \SystemRoot\system32\ntoskrnl.exe )找到 ntoskrnl.exe 模块。 返回基址 :返回找到模块的 ImageBaseAddress 。 作用 :为计算内核符号(如 nt!SeDebugPrivilege )的实际地址提供基准。 2. 传递地址 将获取到的内核基址通过 命令行参数 传递给 Child 进程。 Parent 进程随后等待 Child 进程执行。 Child 部分 整体流程 接收 Parent 传来的内核基址。 检测 CPU 核心数 :必须 >=2,否则无法实现可靠并行竞争。 进入核心利用函数 ExploitIoctlKsEnableEvent 。 利用成功后,创建 SYSTEM 权限的 cmd 进程 ( spawn_cmd_system )。 1. ExploitIoctlKsEnableEvent 函数 目的 :操纵内核时钟驱动 ( KSCATEGORY_CLOCK ) 的事件处理机制,利用竞争条件篡改内核工作项对象 ( KsWorkerObject ) 指针,实现任意地址写入或代码执行。 关键步骤 : 初始化数据结构 : 指定事件类型为 KSEVENT_CLOCK_INTERVAL_MARK 。 设置 KsWorkerObject 指向 target_addr - 0x5C (目的是覆盖 KSWORKITEM 结构中的回调函数指针)。 绑定 CPU 与启动干扰线程 : 将主线程绑定到特定 CPU 核心。 启动 flip_thread 线程,高频翻转 g_ksevent.Flags (在 KSEVENT_TYPE_ENABLE 和 KSEVENT_TYPE_QUERYBUFFER 之间切换),制造竞争条件。 主循环(3次尝试) : 打开设备并启动 :打开时钟设备,设置其状态为 KSSTATE_RUN ,激活内部事件处理。 发送恶意 IOCTL :通过 DeviceIoControl 发送 IOCTL_KS_ENABLE_EVENT 请求。 输入缓冲区溢出 :故意使用超长输入缓冲区 ( sizeof(KSEVENT) + 0x100 )。 竞争窗口 : flip_thread 线程在驱动校验数据后、使用数据前,将 Flags 从高权限 ( QUERYBUFFER ) 改为低权限 ( ENABLE ) 以绕过二次检查。 成功处理 :若 DeviceIoControl 成功返回,说明竞争成功,内核会错误地将用户态 g_eventData 作为工作项处理。等待内核调度执行目标代码。 清理与重试 :每次尝试后重置设备状态。3次尝试机制提高稳定性。 2. pin_ name_ to_ cpu 函数 功能 :将当前线程绑定到指定的 CPU 核心。 步骤 : GetCurrentThread 获取当前线程句柄。 通过位运算生成目标 CPU 的亲和性掩码(如 CPU0: 0x01, CPU1: 0x02)。 调用 SetThreadAffinityMask 设置线程亲和性。 3. xCreateThread 函数 功能 :封装 CreateThread ,简化线程创建并增强错误处理。 参数 :线程函数地址 func ,参数 lpParam ,线程 ID 指针 pThreadId ,失败退出标志 bExitOnFailure 。 返回值 :成功返回线程句柄,失败根据标志退出或报错。 4. 触发循环 外层循环 :控制成功次数 ( inc_count < 3 )。 内层循环 :持续尝试触发竞争条件。 KsOpenDefaultDevice 打开时钟设备。 SetClockState(hClockDevice, KSSTATE_RUN) 启动设备。 设置 g_ksevent.Flags = KSEVENT_TYPE_QUERYBUFFER 。 调用 DeviceIoControl 发送恶意请求。 若成功,等待 ( Sleep(1500) ),停止设备,计数加一,跳出内层循环。 5. spawn_ cmd_ system 函数 目的 :创建 SYSTEM 权限的 cmd.exe 进程。 步骤 : 获取 Winlogon PID :调用 GetProcessIDByName(L"winlogon.exe") 。Winlogon 进程通常以 SYSTEM 权限运行。 打开进程句柄 : OpenProcess(PROCESS_CREATE_PROCESS, ...) 获取 Winlogon 进程句柄。 创建进程 :调用 CreateProcessFromHandle (自定义函数),以 Winlogon 为父进程创建 cmd.exe ,子进程继承 SYSTEM 权限。 清理资源 :关闭句柄。 6. GetProcessIDByName 函数 功能 :通过进程名查找 PID。 步骤 : CreateToolhelp32Snapshot 创建进程快照。 使用 Process32First 和 Process32Next 遍历快照。 比对 szExeFile 字段寻找目标进程。 找到返回 PID,否则返回 0。 7. CreateProcessFromHandle 函数 功能 :创建指定父进程的新进程。 步骤 : 初始化 STARTUPINFOEX 结构。 初始化进程属性列表 ( InitializeProcThreadAttributeList )。 设置 PROC_THREAD_ATTRIBUTE_PARENT_PROCESS 属性,将父进程指定为传入的 hProcess 。 调用 CreateProcess 创建 cmd.exe ,并指定 EXTENDED_STARTUPINFO_PRESENT 标志使属性生效。 0x04 调试分析与原理解析 1. 调用链与漏洞原理 漏洞触发点 : KsIncrementCountedWorker 函数中的 InterlockedIncrement 调用。该函数是一个 增量原语 (Increment Primitive) ,会增加我们提供的地址处的值。 核心利用链 : CKSThunkDevice::DispatchIoctl -> CKSAutomationThunk::ThunkEnableEventIrp -> KsSynchronousIoControlDevice -> KspEnableEvent -> ... -> KsGenerateEvent -> KsIncrementCountedWorker 原理简述 : 设置 Flags = KSEVENT_TYPE_QUERYBUFFER ,使请求进入高权限处理路径,此时 RequestorMode 被设置为 KernelMode ,绕过许多检查。 利用竞争条件,在 CKSAutomationThunk::ThunkEnableEventIrp 复制数据到内核缓冲区后、调用 KsSynchronousIoControlDevice 前,通过干扰线程将 Flags 改为 KSEVENT_TYPE_ENABLE 。 内核后续处理 ( KspEnableEvent ) 看到低权限 Flags ,省略了严格的检查。 最终,恶意构造的 KSEVENTDATA 结构被传递给 KsIncrementCountedWorker ,其参数 ( Worker ) 被控制为 NtSeDebugPrivilegeVA - 0x5C 。 KsIncrementCountedWorker 内部计算 Worker + 0x17*4 (0x5C) 正好指向 NtSeDebugPrivilegeVA ,并对其执行增量操作。 2. 为何是 SeDebugPrivilege 和 3 次? SeDebugPrivilege 是内核中的一个全局变量,其值控制着是否允许调试高权限进程。 普通进程的 SeChangeNotifyPrivilege 通常被初始化为 0x17 (23)。 SeDebugPrivilege 被初始化为 0x14 (20)。 nt!PsOpenProcess 会调用 nt!SeSinglePrivilegeCheck 检查当前进程的权限是否与 SeDebugPrivilege 的值匹配。 利用目标 :将 SeDebugPrivilege 的值从 0x14 增加到 0x17 ,使其与普通进程的权限值匹配,从而绕过检查,获得 SeDebugPrivilege 权限。 3次循环 :因为需要增加 3 次 ( 0x14 -> 0x15 -> 0x16 -> 0x17 )。 3. 关键调试断点与观察 断点于 CKSAutomationThunk::ThunkEnableEventIrp :观察传入的 IRP 和请求参数。验证 Flags 的初始值 ( 0x400 / KSEVENT_TYPE_QUERYBUFFER )。 断点于 KsSynchronousIoControlDevice :观察调用参数,确认输入缓冲区内容和 RequestorMode 已成为 KernelMode 。 断点于 KspEnableEvent :观察分支判断,验证竞争成功后传入的 Flags 已变为 KSEVENT_TYPE_ENABLE ,从而走入低权限检查分支。 断点于 KsGenerateEvent 和 KsIncrementCountedWorker :观察 NotificationType 和传入的 Worker 参数,确认最终计算出的地址正是 nt!SeDebugPrivilege 的地址。 监视 nt!SeDebugPrivilege 内存地址 :在调试器中持续查看该地址的值,观察其从 0x14 经过三次调用后变为 0x17 的过程。 0x05 复现结果 成功利用该漏洞后: Child 进程中的三次竞争条件尝试均成功触发。 nt!SeDebugPrivilege 的值从 0x14 被递增至 0x17 。 随后调用 spawn_cmd_system 函数。 系统成功弹出一个以 SYSTEM 权限 运行的 cmd.exe 命令提示符窗口。 至此,实现了从普通用户权限到最高系统权限的提升。 免责声明 :本文档仅用于安全研究与教学目的。请勿将其用于任何非法或恶意活动。