mqac文件函数ACDeviceControl漏洞分析
字数 1714 2025-08-22 12:22:24

MQAC文件函数ACDeviceControl漏洞分析教学文档

1. 背景知识

1.1 Windows驱动通信机制

在Windows系统中,驱动程序使用设备控制代码(IOCTLs)与用户态应用程序进行通信:

  • 接收来自应用程序的命令(如打开、读取、写入或配置设备的操作)
  • 在硬件层面上执行这些操作
  • 将结果返回给发起请求的应用程序

1.2 ACDeviceControl函数

ACDeviceControl是一个回调函数,用于处理用户端发来的设备控制命令。其关键参数:

  • a2:IRP(I/O Request Packet)类型的数据结构
  • 主要调用ACSendMessage函数处理请求

2. 关键函数分析

2.1 ACSendMessage函数

Information = ACSendMessage(Irp, Options, (CQueue *)FileObject->FsContext, (struct CACSendParameters *)UserBuffer);

参数解析:

  • Options:来自CurrentStackLocation->Parameters.Create.Options
  • FileObject:来自CurrentStackLocation->FileObject
  • UserBuffer:来自Irp->UserBuffer

函数内部流程:

  1. 初始化两个内存指针
  2. 检查(CQueue *)this是否有效(CFG检查)
  3. 检查UserBuffer合法性
  4. UserBuffer指向v19,循环5次,每次偏移0x80
  5. 交换4个指针
  6. 调用ACDeepProbeSendParams将用户态数据复制到内核态

2.2 ACDeepProbeSendParams函数

主要操作:

  1. 检查UserBuffer偏移量:
    • 0x94、0x98、0x9c、0xA0
    • 如果为假,设置对应偏移0x49、0x4B、0x4D、0x4F处指针指向0
  2. 调用ACDeepProbeMsgPropsForSend(a1, a2)进行进一步数据复制
  3. 检查(char *)*((_QWORD *)a1 + 0x49)(char *)*((_QWORD *)a1 + 0x4B)是否为真
    • 如果为真,调用ACDeepCopyQueueFormat复制队列格式

2.3 ACDeepCopyQueueFormat函数

关键行为:

  • 接收三个参数:用户层队列格式、大小、内核层队列格式
  • 根据用户提供的大小在内核层分配内存
    • 如果分配不成功,尝试分配另一种标签的内存
  • 分配的分页内存块大小来自UserBuffer(用户控制)
  • 安全问题:分配时没有加锁

2.4 ACFreeDeepCopyQueueFormat函数

释放内存的关键点:

  • 释放内存的大小从UserBuffer获取,而非创建时的值
  • 释放逻辑:
    • 根据不同类型从不同偏移量释放,每次释放0x20大小
      • 类型3或8:从偏移0x8处释放
      • 类型6:从偏移0x10处释放
    • 直到NumElement减为0,释放所有元素后释放分页内存
  • 安全问题:释放内存时没有加锁

3. 漏洞原理

3.1 条件竞争漏洞

漏洞成因:

  1. 内存分配和释放的大小完全由用户控制
  2. 分配和释放操作都没有加锁保护
  3. 导致可能的竞争条件:
    • 线程A:持续分配内存(设置较小的大小值)
    • 线程B:在内存中修改分配的分页内存大小
    • 结果:影响释放内存时的释放大小,可能导致任意内存释放

3.2 漏洞触发过程

  1. 在分配分页内存和释放内存处设置断点
  2. 观察两个内存的大小值
  3. 典型崩溃场景:
    • 最后一次操作中,一个大小为1,另一个大小为10000
    • 导致程序崩溃
  4. 触发具有随机性(文档中提到第4次就触发了)

4. 漏洞利用分析

4.1 利用条件

  1. 能够控制UserBuffer内容
  2. 能够创建多个线程并发操作
  3. 能够精确控制内存分配和释放的时序

4.2 潜在影响

  1. 任意内存释放可能导致:
    • 内核内存破坏
    • 权限提升
    • 系统崩溃(蓝屏)

5. 防护建议

  1. 输入验证:

    • 对用户提供的UserBuffer大小进行严格验证
    • 设置合理的最大最小值限制
  2. 同步机制:

    • 在内存分配和释放操作中加锁
    • 使用适当的同步原语(如自旋锁)
  3. 内存管理:

    • 分配和释放时使用一致的大小值
    • 考虑使用内核池标记技术
  4. 防御性编程:

    • 检查内存操作返回值
    • 实现安全的内存释放机制
MQAC文件函数ACDeviceControl漏洞分析教学文档 1. 背景知识 1.1 Windows驱动通信机制 在Windows系统中,驱动程序使用设备控制代码(IOCTLs)与用户态应用程序进行通信: 接收来自应用程序的命令(如打开、读取、写入或配置设备的操作) 在硬件层面上执行这些操作 将结果返回给发起请求的应用程序 1.2 ACDeviceControl函数 ACDeviceControl 是一个回调函数,用于处理用户端发来的设备控制命令。其关键参数: a2 :IRP(I/O Request Packet)类型的数据结构 主要调用 ACSendMessage 函数处理请求 2. 关键函数分析 2.1 ACSendMessage函数 参数解析: Options :来自 CurrentStackLocation->Parameters.Create.Options FileObject :来自 CurrentStackLocation->FileObject UserBuffer :来自 Irp->UserBuffer 函数内部流程: 初始化两个内存指针 检查 (CQueue *)this 是否有效(CFG检查) 检查 UserBuffer 合法性 将 UserBuffer 指向 v19 ,循环5次,每次偏移0x80 交换4个指针 调用 ACDeepProbeSendParams 将用户态数据复制到内核态 2.2 ACDeepProbeSendParams函数 主要操作: 检查 UserBuffer 偏移量: 0x94、0x98、0x9c、0xA0 如果为假,设置对应偏移0x49、0x4B、0x4D、0x4F处指针指向0 调用 ACDeepProbeMsgPropsForSend(a1, a2) 进行进一步数据复制 检查 (char *)*((_QWORD *)a1 + 0x49) 和 (char *)*((_QWORD *)a1 + 0x4B) 是否为真 如果为真,调用 ACDeepCopyQueueFormat 复制队列格式 2.3 ACDeepCopyQueueFormat函数 关键行为: 接收三个参数:用户层队列格式、大小、内核层队列格式 根据用户提供的大小在内核层分配内存 如果分配不成功,尝试分配另一种标签的内存 分配的分页内存块大小来自 UserBuffer (用户控制) 安全问题 :分配时没有加锁 2.4 ACFreeDeepCopyQueueFormat函数 释放内存的关键点: 释放内存的大小从 UserBuffer 获取,而非创建时的值 释放逻辑: 根据不同类型从不同偏移量释放,每次释放0x20大小 类型3或8:从偏移0x8处释放 类型6:从偏移0x10处释放 直到 NumElement 减为0,释放所有元素后释放分页内存 安全问题 :释放内存时没有加锁 3. 漏洞原理 3.1 条件竞争漏洞 漏洞成因: 内存分配和释放的大小完全由用户控制 分配和释放操作都没有加锁保护 导致可能的竞争条件: 线程A:持续分配内存(设置较小的大小值) 线程B:在内存中修改分配的分页内存大小 结果:影响释放内存时的释放大小,可能导致任意内存释放 3.2 漏洞触发过程 在分配分页内存和释放内存处设置断点 观察两个内存的大小值 典型崩溃场景: 最后一次操作中,一个大小为1,另一个大小为10000 导致程序崩溃 触发具有随机性(文档中提到第4次就触发了) 4. 漏洞利用分析 4.1 利用条件 能够控制 UserBuffer 内容 能够创建多个线程并发操作 能够精确控制内存分配和释放的时序 4.2 潜在影响 任意内存释放可能导致: 内核内存破坏 权限提升 系统崩溃(蓝屏) 5. 防护建议 输入验证: 对用户提供的 UserBuffer 大小进行严格验证 设置合理的最大最小值限制 同步机制: 在内存分配和释放操作中加锁 使用适当的同步原语(如自旋锁) 内存管理: 分配和释放时使用一致的大小值 考虑使用内核池标记技术 防御性编程: 检查内存操作返回值 实现安全的内存释放机制