高通驱动存在内核任意内存写入漏洞可导致本地提权

 

过程

最近,我在Qualcomm Atheros WLAN驱动服务(QcomWlanSrvx64.exe,版本12.0.0.825)中发现了一个内核任意内存写入(Kernel Write-What-Where)漏洞。这个服务在我刚买的戴尔XPS笔记本上是默认安装的。受此漏洞影响的内核模块是Qcamain10x64.sys。因为经过了戴尔自身的更新和设备管理器里面的驱动更新,我本来以为版本12.0.0.825就是最新的了,后来发现应用程序所带的Qcamain10x64.sys并不是高通公司所提供的最新版本,而在最新版本中此漏洞已经被修复。这意味着许多配备Qualcomm Atheros WLAN的戴尔XPS笔记本电脑可能会受到此问题的影响。我通知了高通公司戴尔的笔记本中没有使用他家最新版本的驱动程序,他们表示正在着手处理此事。如果你在阅读这篇文章的时候无法通过传统的驱动更新方法升级到版本12.0.0.827或更高版本(已修复该漏洞)的Qcamain10x64.sys,可以在这里找到最新的驱动版本。

在向高通披露此漏洞时,他们告诉我这个漏洞在去年已经被修复了。然而他们提供的漏洞号CVE-2019–10567仍然处于保留(reserved )状态。而且我也没有在其他地方找到有关于这个漏洞的预警或者write up,所以我决定在这里分析这个漏洞的攻击过程。

 

Qcamain10x64.sys概述

这个驱动程序漏洞出问题的点和许多其他驱动程序漏洞一样: 存在一个设备对任何用户可写。这意味着所有低权限的进程可以通过发送IOCTL码来与设备驱动进行交互。

这个设备是”ATH_WIFIDEV.00”,我们可以通过逆向来看它所支持的IOCTL码以及可通过各种IOCTL和缓冲区访问的程序路径。

下图展现了Qcamain10x64.sys的设备I/O控制请求调用的子程序树。

 

第一部分:设置缓冲区

在找到处理设备I/O请求的子程序之后,开始寻找我们感兴趣的代码路径。首先发现了一个地方存在往PCI配置空间任意写,可以通过往设备”ATH_WIFIDEV.00”发送IOCTL 0xC3502406触发(使用DeviceIoControl API),这会导致NdisMSetBusData被驱动程序调用,驱动程序会使用用户提供的数据和偏移来写入PCI配置空间。

开始时,我很难找到一个安全的偏移量来写入任意数据而不导致操作系统崩溃(蓝屏),在测试了各种偏移之后,我发现我们可以安全地在PCI配置空间中偏移0x14的地方写入4个字节而不会影响操作系统正常工作。这是我们内核任意内存写入的第一步,下图显示了从低权限进程向PCI配置空间写入“0xDEADBEEF”的代码示例。

到目前为止,我们可以做到的只是将任意数据写入某个PCI空间,这好像没多大用处; 然而,将它与我们可以触发的另一个驱动子程序相结合,情况就变得更加有趣起来。

 

第二部分:写缓冲区

现在我们已经把自定义payload存到了PCI配置空间中,我们需要做一些有趣的事情来让它们变得有用。我找到了一个会被驱动调用的函数: NdisMGETBusData ,它从PCI空间中读取给定偏移量处的数据写入缓冲区,而且我们可以通过发送正确的IOCTL来触发这个流程。

好像这还不够,触发上述流程的IOCTL是0x220043,从它的低2位可以判断出它的传输类型是METHOD_NEITHER。这意味着子程序将直接在从用户模式传递来的缓冲区上运行,并且在调用驱动程序例程之前不会进行映射/复制。这还不算完,期间没有调用ProbeForWrite来验证从用户模式传递来的这些缓冲区。这意味着我们可以把输出缓冲区设置成内核模式下的地址,并使例程将PCI数据直接写入提供的输出缓冲区(通过调用NdisMGetBusData之后的memcpy_s操作),一个受控的内核写就此达成。现在结合上一部分(将任意数据写入PCI配置空间),就可成功实现内核任意内存写入。以下是代码示例:

将“AAAA”写入内核模式下的地址0xFFFFBE8A2BA00000中。

 

漏洞利用

在Windows 10 (x64)上,默认漏洞缓释技术(如SMEP, CFG等)全部开启,使用这个内核任意内存写入漏洞,我成功地将权限提升到SYSTEM。至此,我成功地利用这个漏洞实现了本地提权,希望之后可以利用这个漏洞做更多的探索。

上图证明了这个漏洞的危害性。我敦促任何使用Qualcomm Atheros WLAN驱动程序服务的用户尽快更新到最新版本。

 

高通提供的补丁

在高通最新提供的补丁中,我们可以看到他们利用ProbeForWrite检查了从用户模式传来的缓冲区,从根本上封堵了这个漏洞。


发表评论 取消回复

电子邮件地址不会被公开。 必填项已用*标注