白帽故事 · 2024年3月23日 0

在Outlook上寻找远程代码执行漏洞【部分】

背景介绍

2023 年,NetSPI 发现 Microsoft Outlook 容易通过同步表单对象受到经过身份验证的远程代码执行 (RCE) 攻击。本文讲介绍如何他们是如何发现CVE-2024-21378漏洞,并通过修改Ruler(SensePost发布的一款Outlook渗透测试工具)将其“武器化”的整个过程。

漏洞概述

攻击的原始变种由 SensePost(Orange CyberDefense)的 Etienne Stalmans 于 2017 年记录在案,并利用 Outlook 表单对象内的 VBScript 代码来获取可访问邮箱的代码执行,作为回应,微软发布了一个补丁来强制将自定义表单中的脚本代码列入白名单,然而,这么多年过去了,这些表单对象的同步功能从未改变过。

表单使用IPM.Microsoft.FolderDesign.FormsDescription对象进行 MAPI 同步,这些对象带有特殊的属性和附件,用于在客户端首次使用表单时“安装”表单。整个过程如下:

  1. Outlook 请求特定邮件类 (IPM.Note.Evil) 的实例化
  2. 针对 IPM.Microsoft.FolderDesign.FormsDescription 对象,查阅相关文件夹的 MAPI 关联内容表
  3. 如果 PidTagOfflineAddressBookName 属性中存储的类名匹配,则表单安装过程启动
  4. PidTagOfflineAddressBookDistinguishedName 用作新表单安装的 CLSID(所有表单都是 COM 对象)
  5. 表单描述的第一个附件和特殊属性 0x6902001F 确定需要在 CLSID 下添加哪些注册表项才能安装表单
  • 在旧式表单(“绕过 Outlook 的表单”)中,这些注册表值通常包括 InProcServer 项或与提取到磁盘的 DLL 绑定的等效项
  • 在较新的表单中,特定于 Outlook 的 MsgClass 键用于将表单绑定到提取到磁盘的 OLE 对象
  • 在这些键中,%d可用于引用剩余表单附件的提取目录 (%localappdata%MicrosoftFORMS)
  1. 确认注册表更改后,Outlook 继续将表单作为 COM 对象加载

以上过程存在一些严重的问题:

    • 将附件提取到%localappdata%MicrosoftFORMS时,可以通过PidTagAttachFilename 属性执行路径遍历,还可以将多个文件写入磁盘,这本质上是在安装表单时的任意磁盘写入
    • 为表单创建注册表项时,0x6902001F 属性数据被预期 key=value 行的换行符破坏,每行的处理位置,其中 key 是 CLSID 的子键,value 是该键的默认值。为了防止“绕过 Outlook 的表单”,将典型 COM 服务器密钥(InProcServer、LocalServer 等)的拒绝列表与每行的开头 (OLMAPI32.DLL) 进行比较,但是,在安装该值时,可以使用字符来表示 HKCR 下的完整子键路径,例如,*CLSID<CLSID>InprocServer32=%devil.dll*将绕过拒绝列表检查并导致表单的完整 COM 对象注册
  • 因此能够在磁盘上创建任意文件,以及在 HKEY_CLASSES_ROOT (HKCR) 下安装任意注册表项(具有默认值),这些足以实现 RCE 攻击

深入研究

搭建环境

通俗来讲,该系列攻击属于第四次迭代,其前提是使用受损的凭据通过 Exchange 同步对象。2015 年底,Dreadnode 联合创始人 Nick Landers 就发表过一篇关于滥用 Outlook 规则进行 RCE 的博客(https://www.netspi.com/blog/technical/adversary-simulation/malicious-outlook-rules/),在接下来的几年里,Etienne (SensePost) 和 Nick Dual 发现了另外两组攻击向量,最终都被微软修补,其中就包括对 Outlook Forms(表单)的滥用。SensePost 发布了一组优秀的博客,深入研究了漏洞和底层技术以及利用工具 Ruler(详细了解可移步:https://‍github.com/se‍nsepost/ruler)。

研究人员打算重新进行这项研究,因为他们认为 Outlook 具有巨大且尚未充分开发的攻击面。通过从 Outlook 客户端以及 MFCMAPI 和 ProcMon 手动探索 Outlook 表单开始,研究人员对底层技术进行了系统性的了解,但本质上,通过 Outlook 提供的各种项目(消息、日历邀请、任务等)都是通过“inspector window(检查器窗口)”中的表单结构显示的。

Outlook 既包含标准表单,又允许通过 Exchange(包括 Exchange Online)发布和同步的自定义表单。在研究过程中,他们发现了可用于安装自定义表单的表单配置文件格式,尤其令人感兴趣的是文件和注册表项。

The File entry lists the form server application executable file that the form library maintains and loads into a new subdirectory in the disk cache when the form is launched…文件条目列出了表单库维护的表单服务器应用程序可执行文件,并在表单启动时加载到磁盘缓存中的新子目录中……The Registry entry is used whenever the File entry is used, it identifies the registry key for the form library where the executable file for the form server application is stored…每当使用文件条目时都会使用注册表条目,它标识存储表单服务器应用程序的可执行文件的表单库的注册表项…

首先尝试证明的是本地代码执行(LCE),下面是一个示例表单配置,可以将其直接导入 Outlook 来安装表单,将文件条目设置为我们想要通过表单安装的 DLL 的位置,并将该文件保存到c:pochello.cfg

[Description] MessageClass=IPM.Note.Hello CLSID={00000000-1234-1234-1234-000000000000} DisplayName=Hello Category=Standard Subcategory=Form Comment=Hello SmallIcon=C:WindowsSysWOW64OneDrive.ico LargeIcon=C:WindowsSysWOW64OneDrive.ico [Platforms] Platform1=Win16 [Platform.Win16] CPU=ix86 OSVersion=Win3.1 File = C:pochello.dll Registry = InprocServer32 = %dhello.dll

出于测试目的,研究人员在 DllMain 中编译了一个带有执行的 DLL,并再次将其放置在与上面 hello.cfg 文件相同的文件夹中。

#include <Windows.h> BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {      if (reason == DLL_PROCESS_ATTACH) {      MessageBoxA(0, "Hello", "Ruh Roh", 0);      }      return TRUE;}

然后,可以使用配置文件在 Outlook 中安装表单,方法是导航到文件 -> 选项 -> 高级 -> 自定义表单并选择 hello.cfg 文件。

[!CAUTION]

在通过配置文件安装自定义表单时要将位置设置为收件箱

导航到表单管理器(Forms Manager)

在收件箱文件夹中安装自定义表单配置文件

验证表单已安装

然后,继续选择“开发人员”选项卡(Developer Tab)-> “选择表单(Choose Form)”并打开刚新创建成功的表单。

尝试打开新安装的表单

emm…貌似不是很理想,在安装表单配置文件时可以看到了一个可能相关的配置,做些修改然后重试。

选择自定义表单选项

好多了!成功确认了任意DLL的执行,但这仅仅只是本地代码执行…..

加入星球,随时交流、全年畅享完整阅读:


(1-50位成员):99元/年

(51-100位成员):128元/年

100位+成员):199元/年