mqac文件函数ACDeviceControl漏洞分析
la0gke 发表于 北京 二进制安全 470浏览 · 2024-08-12 03:54

mqac文件函数ACDeviceControl漏洞分析

函数描述

在Windows中,驱动程序使用设备控制代码(Device Control Codes,即IOCTLs)来接收来自应用程序的命令,或者向应用程序提供信息。

  1. 解析从用户空间传来的指定命令(如打开、读取、写入或者配置设备的操作)。
  2. 在硬件层面上执行这些操作。
  3. 将结果返回给发起请求的应用程序。

函数分析

ACDeviceControl

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

进入到函数内,参数二a2是一个IRP类型的数据结构。

目标调用处用到的几个参数,都来自a2

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

几个参数定义

Options = CurrentStackLocation->Parameters.Create.Options;
FileObject = CurrentStackLocation->FileObject;
UserBuffer = (void **)Irp->UserBuffer;

接着进入到ACSendMessage函数内部。

ACSendMessage

先初始化两个内存指针

接着判断(CQueue *)this是否有效,CFG 检查。

随后检查是否合法(UserBuffer)a4

(UserBuffer)a4指向v19,共循环5次,每次偏移0x80

接着再交换4个指针,然后调用ACDeepProbeSendParams把用户态发的的数据复制到内核态中。

ACDeepProbeSendParams

进入ACDeepProbeSendParams函数后,依次判断UserBuffer偏移0x940x980x9c0xA0如果为假,设置对应的偏移0x490x4B0x4D0x4F处指针指向0

还调用了ACDeepProbeMsgPropsForSend(a1, a2);进一步的复制,这里不进一步跟踪。

然后分别判断(char *)*((_QWORD *)a1 + 0x49)(char *)*((_QWORD *)a1 + 0x4B)为否为真,如果为真,分别调用函数ACDeepCopyQueueFormat来复制队列格式。

这个函数接收三个参数,用户层队列格式,大小,内核层队列格式

然后会根据这个大小来在内核层分配内存

如果没成功,分配另一种标签的内核内存


这个分页内存块的大小是从UserBuffer中获取的,也就是说来自用户,并且分配的时候没有锁。这是很不安全的。

最后,如果内存没有分配成功,调用ACFreeDeepCopyQueueFormat来释放未分配成功的内存块。

ACFreeDeepCopyQueueFormat

通过交叉引用可以看到,ACSendMessage函数也调用了该释放函数。跟进看一下

释放内存的大小,是从UserBuffer获取的,而不是创建时候的值。

进入到函数内部,看一下具体怎么释放

根据不同的类型确定从不同的偏移量释放,每次释放0x20大小

如果类型为3或者8,从偏移0x8处释放,

如果类型为6,从偏移0x10处是释放

直到NumElement减为0,所有的元素释放完,开始释放掉这个分页内存。

同样的,这里释放内存的时候没有上锁。

漏洞触发

这种情况下就存在条件竞争的可能。一个线程一直分配内存,分配的内存设置小一点,另一个线程直接在内存中修改分配分页内存的大小,从而影响释放内存时的释放大小,从而释放任意内存。

在分配分页内存和释放内存处分别设置断点,并打印两个内存的大小值。可以看到,在最后依次,一个大小为1,另一个大小为10000,接着就触发崩溃程序

随机性很大,这里第4次就触发了

0 条评论
某人
表情
可输入 255