Windows Error Reporting 0day漏洞分析(CVE-2019-0863)

栏目: 编程工具 · 发布时间: 5年前

内容简介:2018年12月,名为“SandboxEscaper”的一名黑客公开了Windows Error Reporting(WER,Windows错误报告)组件中的一个0day漏洞。深入分析这个漏洞后,我发现了另一个0day漏洞,该漏洞可以用来提升至系统权限。根据微软的本文将与大家分享这个漏洞的具体原理。

Windows Error Reporting 0day漏洞分析(CVE-2019-0863)

0x00 前言

2018年12月,名为“SandboxEscaper”的一名黑客公开了Windows Error Reporting(WER,Windows错误报告)组件中的一个0day漏洞。深入分析这个漏洞后,我发现了另一个0day漏洞,该漏洞可以用来提升至系统权限。根据微软的 安全公告 ,攻击者一直在实际环境中利用该漏洞发起攻击,攻击活动直到2019年5月份微软推出安全补丁才暂告一段落。

本文将与大家分享这个漏洞的具体原理。

0x01 WER工作原理

Windows Error Reporting 工具是基于事件的一种反馈架构,用来收集Windows能够探测到的硬件以及软件方面的问题,向微软提交相关信息,并且可以为用户提供可用的解决方案。

比如,如果Windows出现系统崩溃,那么就会生成错误报告,存放到WER报告队列目录中( C:\ProgramData\Microsoft\Windows\WER\ReportQueue ),队列中每个报告都有自己的子目录以及唯一对应的 Report.wer INI文件(其中带有相关元数据)。为了能让所有进程都能报告错误信息,所有用户都具备 ReportQueue 目录的写入权限,如下图所示:

Windows Error Reporting 0day漏洞分析(CVE-2019-0863)

图1. Windows Error Reporting队列目录

报告生成后,会被发送到微软以便后续分析。这种交互行为可以通过多种方式来触发,其中一种方式就是利用名为 Windows Error Reporting\QueueReporting 的计划任务。从安全角度来看,这个任务比较有趣,主要有以下几个因素:

  • 该任务以 SYSTEM 权限运行,可参考任务对应的 Security Options 选项
  • 该任务可按需触发
  • 该任务会以固定的命令行参数来运行一个专用的程序: wermgr.exe -upload

Windows Error Reporting 0day漏洞分析(CVE-2019-0863)

图2. Windows Error Reporting计划任务

wermgr.exe 在执行后,会与挂起的报告文件以及目录交互。程序会读取并解析相关文件,将这些文件拷贝到其他目录,有时候甚至会删除文件。现在我们已经具有一个较高权限的组件,该组件能够访问任何用户都具备写入权限的文件。如果程序在逻辑实现过程中不够严谨,那么这种操作将引入一些非常严重的安全问题。

0x02 滥用文件系统链接

Windows支持不同类型的文件系统链接,我们可以利用这些链接将文件以及目录指向其他文件及目录。一旦链接被系统扫描以及重新解析,就会将用户重定向到目标路径。从安全角度来看,这里最大的风险在于滥用硬链接(hard links)以及挂载点(mount point),因为用户可以将这些组件链接到本来不具备写入权限的目标文件或者目录。

举个例子,比如不具备 kernel32.dll 写入权限的用户可以创建 c:\temp\Dir\x.dll 以及 C:\Windows\System32\kernel32.dll 之间的硬链接。具备重定向到较高权限组件的能力一直都是黑客追求的目标,这样就能读取、写入甚至删除敏感的关键文件。

Windows Error Reporting 0day漏洞分析(CVE-2019-0863)

图3. 硬链接至用户不具备写入权限的文件

0x03 漏洞分析

简而言之,攻击者可以利用WER来修改文件权限,利用前文提到的文件系统链接方式,将报告目录中的文件链接至主机上的其他目标文件,以获取对其他任意文件的读取、写入、编辑以及删除权限。

更具体一点,整体漏洞利用场景如下:

  • wermger.exe 逐一解析报告目录中的所有文件,将这些文件提交给微软
  • wermger.exe 检测到损坏的 Report.wer INI文件,就会删除该文件。然而 wermger.exe 首先会修改该文件的 DACL 属性,以便删除该文件
  • wermger.exe 在读取文件DACL属性以及添加删除权限之间存在较小的一个时间窗口,攻击者利用的正是这个时间窗口。如果攻击者创建这类文件与系统上其他任意文件的一个链接,那么在读取DACL之后, wermgr.exe 会错误地修改其他文件的安全描述符。这是非常糟糕的场景。

具体利用原理可分为以下几步。

步骤1:

wermgr.exe -upload 执行的第一个操作就是调用 wermgr!DoCoreUpload 函数,该函数会列出 ReportQueue 下的所有子目录,读取错误报告并将报告提交给微软:

int64 DoCoreUpload(/* ... */) {
    /* ... */
    Ret = WerpSubmitReportFromStore(ReportPath, /* ... */);
    if (Ret >= 0) {
        /* Report successfully uploaded */
    } else {
        if (Ret == ERROR_FILE_CORRUPT) {
            DeleteCorruptedReportFromStore(ReportPath);
        }
    }
}

步骤2:

wermgr.exe 遇到损坏的 Report.wer INI文件时,会修改文件的DACL,以便后续执行删除操作。更具体的细节为:

首先, wermgr!DeleteCorruptedReportFromStore 会列出报告子目录下的所有文件;

其次, wermgr!PreparePathForDeletion 会修改每个文件的权限。这里正是核心bug所在的位置,因为该函数会使用 kernel32!GetFileSecurity 来读取文件的安全描述符,然后调用 kernel32!SetFileSecurity 将删除描述符应用于该文件。

int64 PreparePathForDeletion(wchar_t* FileName) {
    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
    DWORD BytesRead = 0;
    PDACL Dacl = NULL;
    /* ... */

    if ( !GetFileSecurity(FileName, 
                    DACL_SECURITY_INFORMATION, 
                    NULL, 0, &BytesRead) ) {
        /* ... */
        return;
    }

    SecurityDescriptor = new BYTE[BytesRead];

    if ( !GetFileSecurity(FileName, 
                    DACL_SECURITY_INFORMATION, 
                    SecurityDescriptor, 
                    BytesRead, &BytesRead) ) { 
        /* ... */
        return;
    }

    if ( GetSecurityDescriptorDacl(SecurityDescriptor, 
                         &DaclPresent, 
                         &Dacl, &DaclDefaulted) )
    {
        /* ... */
        HANDLE TokenHandle = NULL;
        PACL NewAcl = NULL;
        EXPLICIT_ACCESS ExplicitAccess = {0};

        /* ... */
        LPVOID UserName = new BYTE[/* ... */];
        GetTokenInformation(TokenHandle, TokenUser, 
                      UserName, &BytesRead);

        ExplicitAccess.Trustee.ptstrName = UserName;
        ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_NAME;
        ExplicitAccess.grfAccessMode = GRANT_ACCESS;
        ExplicitAccess.grfAccessPermissions = DELETE | /* ... */;
        /* ... */

        SetEntriesInAcl(1, &ExplicitAccess, Dacl, &NewAcl);
        InitializeSecurityDescriptor(&SecurityDescriptor, 1);
        SetSecurityDescriptorDacl(&SecurityDescriptor, 1, NewAcl, 0);
        SetFileSecurity(FilePath, DACL_SECURITY_INFORMATION, 
                    &SecurityDescriptor);    
    }
}

能够在合适的时机成功创建文件系统链接是非常困难的一个操作,但如果攻击者非常有耐心,可以不断重试,直到成功完成该任务。攻击者很可能以可执行文件(DLL、EXE或者脚本)作为目标,然后以恶意payload覆盖这些文件,最后以 SYSTEM 权限来执行。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JSP网站开发典型模块与实例精讲

JSP网站开发典型模块与实例精讲

李振捷 / 电子工业出版社 / 2006-8 / 50.0

本书是典型模块与实例精讲丛书中的一本。 本书讲解了使用JSP开发网站系统的经典模块和工程实例,基本囊括了JSP的重点技术,对这些模块稍加修改就可以直接使用到实际项目中。为了方便本书的读者交流在学习中遇到的问题,特地在本书的服务网站上公布了很多QQ群组,读者只要拥有QQ号码,就可以参与到本书的QQ学习群组中一起讨论学习心得。本书的作者还在一定的时间给读者提供在线答疑服务。一起来看看 《JSP网站开发典型模块与实例精讲》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具