CVE-2020-0787-Windows本地提权漏洞分析
字数 1802 2025-08-25 22:59:02

CVE-2020-0787 Windows本地提权漏洞深入分析与利用指南

漏洞概述

CVE-2020-0787是Windows后台智能传输服务(BITS)中存在的一个本地提权漏洞,允许低权限用户在系统上下文中执行任意文件移动操作,最终可能导致权限提升至SYSTEM级别。该漏洞由itm4n发现,影响多个Windows版本。

BITS服务简介

后台智能传输服务(BITS, Background Intelligent Transfer Service)是Windows提供的一项服务,用于:

  • 从HTTP Web服务器和SMB文件共享下载文件
  • 将文件上传到HTTP Web服务器和SMB文件共享
  • 考虑传输成本和网络使用情况,最小化对用户前台工作的影响
  • 处理网络中断,支持暂停和自动恢复传输
  • 在系统重启后仍能保持传输状态

漏洞组件分析

BITS COM类工作机制

BITS服务公开了多个COM对象,重点关注两类:

  1. "New" BIT Control Class (CLSID: 4991D34B-80A1-4291-83B6-3328366B9097)

    CoCreateInstance(CLSID_4991D34B-80A1-4291-83B6-3328366B9097) -> IBackgroundCopyManager*
    |__ IBackgroundCopyManager::CreateJob() -> IBackgroundCopyJob*
        |__ IBackgroundCopyJob::AddFile(URL, LOCAL_FILE) 
        |__ IBackgroundCopyJob::Resume() 
        |__ IBackgroundCopyJob::Complete()
    
  2. Legacy Control Class (CLSID: 69AD4AEE-51BE-439B-A92C-86AE490E8B30)

    CoCreateInstance(CLSID_69AD4AEE-51BE-439B-A92C-86AE490E8B30) -> IBackgroundCopyQMgr*
    |__ IBackgroundCopyQMgr::CreateGroup() -> IBackgroundCopyGroup*
        |__ IBackgroundCopyGroup::CreateJob() -> IBackgroundCopyJob1*
            |__ IBackgroundCopyJob1::AddFiles(FILESETINFO)
            |__ IBackgroundCopyJob1::Resume()
            |__ IBackgroundCopyJob1::Complete()
    

未公开方法分析

在IBackgroundCopyGroup接口中发现了两个未文档化的方法:

  1. QueryNewJobInterface()

    virtual HRESULT STDMETHODCALLTYPE QueryNewJobInterface( 
        /* [in] */ __RPC__in REFIID iid,
        /* [iid_is][out] */ __RPC__deref_out_opt IUnknown **pUnk) = 0;
    
  2. SetNotificationPointer()

通过逆向分析qmgr.dll发现,当输入GUID匹配硬编码值37668d37-507e-4160-9316-26306d150b12(IID_IBackgroundCopyJob)时,会调用CJob::GetJobExternal()

漏洞原理

关键差异点

  1. CreateJob()方法流程

    (CLIENT) IBackgroundCopyGroup::CreateJob()
       |
       V
    (SERVER) COldGroupInterface::CreateJob()
          |__ COldGroupInterface::CreateJobInternal()
              |__ CLockedJobWritePointer::ValidateAccess()
              |   |__ CJob::CheckClientAccess() // 客户端模拟
              |__ CJob::GetOldJobExternal() // 返回IBackgroundCopyJob1*指针
    
  2. QueryNewJobInterface()方法流程

    (CLIENT) IBackgroundCopyGroup::QueryNewJobInterface()
       |
       V
    (SERVER) COldGroupInterface::QueryNewJobInterface()
          |__ CJob::GetJobExternal() // 返回IBackgroundCopyJob*指针
    

核心问题:当调用QueryNewJobInterface()获取新接口指针时,服务端没有正确模拟客户端身份,导致返回的指针具有SYSTEM权限上下文。

文件移动机制

  1. 服务创建临时文件(BIT*.tmp)并写入内容
  2. 写入完成后,通过MoveFileEx()重命名文件
  3. QueryNewJobInterface()获取的指针上下文中,文件移动操作以SYSTEM权限执行

漏洞利用步骤

准备工作

  1. 创建目录结构:

    %temp%\workspace
    |__ <DIR> bait
    |__ <DIR> mountpoint
    |__ FakeDll.dll
    
  2. 准备恶意DLL(FakeDll.dll)用于后续提权

详细利用流程

  1. 创建挂载点

    • 建立从%temp%\workspace\mountpoint%temp%\workspace\bait的挂载点
  2. 创建新Job

    • 使用Legacy Control Class接口创建新Job
    • 参数:
      • Target URL: \\127.0.0.1\C$\Windows\System32\drivers\etc\hosts
      • Local file: %temp%\workspace\mountpoint\test.txt
    • 实际路径解析为:%temp%\workspace\bait\test.txt
  3. 设置Oplock

    • 监控bait文件夹,查找类似BITAA6.tmp的临时文件
    • 在临时文件上设置Oplock
  4. 恢复Job并等待Oplock触发

    • 调用Resume()使服务开始写入临时文件
    • 写入操作触发Oplock
  5. 切换挂载点

    • 原始状态:
      TMP file   = %temp%\workspace\mountpoint\BIT1337.tmp -> %temp%\workspace\bait\BITAA6.tmp
      Local file = %temp%\workspace\mountpoint\test.txt -> %temp%\workspace\bait\test.txt
      
    • 切换操作:
      %temp%\workspace\mountpoint -> \RPC Control
      Symlink #1: \RPC Control\BITAA6.tmp -> %temp%\workspace\FakeDll.dll
      Symlink #2: \RPC Control\test.txt -> C:\Windows\System32\FakeDll.dll
      
    • 切换后状态:
      TMP file   = %temp%\workspace\mountpoint\BITAA6.tmp -> %temp%\workspace\FakeDll.dll
      Local file = %temp%\workspace\mountpoint\test.txt -> C:\Windows\System32\FakeDll.dll
      
  6. 释放Oplock

    • 允许服务继续写入操作
    • 服务将FakeDll.dll写入临时位置
    • MoveFileEx()操作因符号链接被重定向,将DLL移动到System32目录
  7. 提权

    • 利用Update Session Orchestrator服务加载移动到system32的恶意DLL
    • 通常替换WindowsCoreDeviceInfo.dll等常用库实现权限提升

防御与缓解措施

  1. 及时安装微软提供的安全更新
  2. 限制低权限用户对BITS服务的访问
  3. 监控系统目录下的异常文件操作
  4. 启用CFG(Control Flow Guard)等缓解措施
  5. 限制符号链接和挂载点的创建权限

参考资源

  1. 微软安全公告
  2. 漏洞PoC代码
  3. 技术分析文章
  4. 微软BITS API文档
  5. QMGR API文档
CVE-2020-0787 Windows本地提权漏洞深入分析与利用指南 漏洞概述 CVE-2020-0787是Windows后台智能传输服务(BITS)中存在的一个本地提权漏洞,允许低权限用户在系统上下文中执行任意文件移动操作,最终可能导致权限提升至SYSTEM级别。该漏洞由itm4n发现,影响多个Windows版本。 BITS服务简介 后台智能传输服务(BITS, Background Intelligent Transfer Service)是Windows提供的一项服务,用于: 从HTTP Web服务器和SMB文件共享下载文件 将文件上传到HTTP Web服务器和SMB文件共享 考虑传输成本和网络使用情况,最小化对用户前台工作的影响 处理网络中断,支持暂停和自动恢复传输 在系统重启后仍能保持传输状态 漏洞组件分析 BITS COM类工作机制 BITS服务公开了多个COM对象,重点关注两类: "New" BIT Control Class (CLSID: 4991D34B-80A1-4291-83B6-3328366B9097) Legacy Control Class (CLSID: 69AD4AEE-51BE-439B-A92C-86AE490E8B30) 未公开方法分析 在IBackgroundCopyGroup接口中发现了两个未文档化的方法: QueryNewJobInterface() SetNotificationPointer() 通过逆向分析qmgr.dll发现,当输入GUID匹配硬编码值 37668d37-507e-4160-9316-26306d150b12 (IID_ IBackgroundCopyJob)时,会调用 CJob::GetJobExternal() 。 漏洞原理 关键差异点 CreateJob()方法流程 : QueryNewJobInterface()方法流程 : 核心问题 :当调用 QueryNewJobInterface() 获取新接口指针时,服务端没有正确模拟客户端身份,导致返回的指针具有SYSTEM权限上下文。 文件移动机制 服务创建临时文件(BIT* .tmp)并写入内容 写入完成后,通过 MoveFileEx() 重命名文件 在 QueryNewJobInterface() 获取的指针上下文中,文件移动操作以SYSTEM权限执行 漏洞利用步骤 准备工作 创建目录结构: 准备恶意DLL( FakeDll.dll )用于后续提权 详细利用流程 创建挂载点 建立从 %temp%\workspace\mountpoint 到 %temp%\workspace\bait 的挂载点 创建新Job 使用Legacy Control Class接口创建新Job 参数: Target URL: \\127.0.0.1\C$\Windows\System32\drivers\etc\hosts Local file: %temp%\workspace\mountpoint\test.txt 实际路径解析为: %temp%\workspace\bait\test.txt 设置Oplock 监控 bait 文件夹,查找类似 BITAA6.tmp 的临时文件 在临时文件上设置Oplock 恢复Job并等待Oplock触发 调用 Resume() 使服务开始写入临时文件 写入操作触发Oplock 切换挂载点 原始状态: 切换操作: 切换后状态: 释放Oplock 允许服务继续写入操作 服务将 FakeDll.dll 写入临时位置 MoveFileEx() 操作因符号链接被重定向,将DLL移动到 System32 目录 提权 利用Update Session Orchestrator服务加载移动到system32的恶意DLL 通常替换 WindowsCoreDeviceInfo.dll 等常用库实现权限提升 防御与缓解措施 及时安装微软提供的安全更新 限制低权限用户对BITS服务的访问 监控系统目录下的异常文件操作 启用CFG(Control Flow Guard)等缓解措施 限制符号链接和挂载点的创建权限 参考资源 微软安全公告 漏洞PoC代码 技术分析文章 微软BITS API文档 QMGR API文档