利用漏洞实现 Outlook 的 RCE:第 2 部分

admin 2024年8月25日12:57:19评论18 views字数 8557阅读28分31秒阅读模式
免责声明
由于传播、利用本公众号红云谈安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号红云谈安全及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!请在授权的站点测试,遵守网络安全法!仅供学习使用,如若非法他用,与平台和本文作者无关,需自行负责!

## 攻击面

Outlook 要播放的声音文件是波形音频文件格式( WAV)。它通过接收声音文件路径的PlaySound函数播放。PlaySound将加载文件、解析它,然后调用soundOpen,后者将调用不同的波形函数,例如waveOutOpen

WAV 文件充当多个音频编解码器的容器(或包装器)。编解码器是一种对数据流(如图像、视频或音频)进行编码或解码的程序或代码。通常,编解码器将采用脉冲编码调制(PCM) 编码,这是一种表示采样模拟信号的简单方法。

我们可以在三个主要攻击面上搜索漏洞:

  1. WAV 格式解析
  2. 音频压缩管理器
  3. 不同的音频编解码器

WAV 格式解析

WAV 格式解析是在 winmm.dll(实现 Windows 多媒体 API 的库)中的函数soundInitWavHdr内实现的。那里呈现的攻击面并不大,而且似乎已经过审查;我们没有在那里发现任何漏洞。

什么是音频压缩管理器?

音频压缩管理器 (ACM) 是负责处理 WAV 文件中使用的编解码器不使用简单 PCM 编码的情况的代码,因此需要由自定义解码器进行解码。这些解码器在扩展名为 .acm 的文件中实现。一个常见示例是 MP3 编解码器,它在 l3codeca.acm 中实现。每个编解码器都由一个驱动程序处理(它与内核模式驱动程序不同,但功能相似),该驱动程序通过 ACM 注册。

每当需要转换时,例如将 MP3 转换为 PCM 或反之,ACM 就会开始工作并管理此转换。当我们使用未使用 PCM 的 WAV 文件时,将查询 ACM 以查看文件本身中指定的编解码器是否存在并且可以处理转换(图 1)。

Outlook 要播放的声音文件是波形音频文件格式( WAV)。它通过接收声音文件路径的PlaySound函数播放。PlaySound将加载文件、解析它,然后调用soundOpen,后者将调用不同的波形函数,例如waveOutOpen

WAV 文件充当多个音频编解码器的容器(或包装器)。编解码器是一种对数据流(如图像、视频或音频)进行编码或解码的程序或代码。通常,编解码器将采用脉冲编码调制(PCM) 编码,这是一种表示采样模拟信号的简单方法。

我们可以在三个主要攻击面上搜索漏洞:

  1. WAV 格式解析
  2. 音频压缩管理器
  3. 不同的音频编解码器

WAV 格式解析

WAV 格式解析是在 winmm.dll(实现 Windows 多媒体 API 的库)中的函数soundInitWavHdr内实现的。那里呈现的攻击面并不大,而且似乎已经过审查;我们没有在那里发现任何漏洞。

什么是音频压缩管理器?

音频压缩管理器 (ACM) 是负责处理 WAV 文件中使用的编解码器不使用简单 PCM 编码的情况的代码,因此需要由自定义解码器进行解码。这些解码器在扩展名为 .acm 的文件中实现。一个常见示例是 MP3 编解码器,它在 l3codeca.acm 中实现。每个编解码器都由一个驱动程序处理(它与内核模式驱动程序不同,但功能相似),该驱动程序通过 ACM 注册。

每当需要转换时,例如将 MP3 转换为 PCM 或反之,ACM 就会开始工作并管理此转换。当我们使用未使用 PCM 的 WAV 文件时,将查询 ACM 以查看文件本身中指定的编解码器是否存在并且可以处理转换(图 1)。利用漏洞实现 Outlook 的 RCE:第 2 部分介绍 利用我们在本博客系列第 1 部分中描述的漏洞,我们再次能够在目标上播放自定义声音文件,从而滥用 Outlook 的提醒声音功能。为了利用此功能并将其转变为完整的远程代码执行 (RCE),我们开始在 Windows 上搜索中的漏洞。## 攻击面

Outlook 要播放的声音文件是波形音频文件格式( WAV)。它通过接收声音文件路径的PlaySound函数播放。PlaySound将加载文件、解析它,然后调用soundOpen,后者将调用不同的波形函数,例如waveOutOpen

WAV 文件充当多个音频编解码器的容器(或包装器)。编解码器是一种对数据流(如图像、视频或音频)进行编码或解码的程序或代码。通常,编解码器将采用脉冲编码调制(PCM) 编码,这是一种表示采样模拟信号的简单方法。

我们可以在三个主要攻击面上搜索漏洞:

  1. WAV 格式解析
  2. 音频压缩管理器
  3. 不同的音频编解码器

WAV 格式解析

WAV 格式解析是在 winmm.dll(实现 Windows 多媒体 API 的库)中的函数soundInitWavHdr内实现的。那里呈现的攻击面并不大,而且似乎已经过审查;我们没有在那里发现任何漏洞。

什么是音频压缩管理器?

音频压缩管理器 (ACM) 是负责处理 WAV 文件中使用的编解码器不使用简单 PCM 编码的情况的代码,因此需要由自定义解码器进行解码。这些解码器在扩展名为 .acm 的文件中实现。一个常见示例是 MP3 编解码器,它在 l3codeca.acm 中实现。每个编解码器都由一个驱动程序处理(它与内核模式驱动程序不同,但功能相似),该驱动程序通过 ACM 注册。

每当需要转换时,例如将 MP3 转换为 PCM 或反之,ACM 就会开始工作并管理此转换。当我们使用未使用 PCM 的 WAV 文件时,将查询 ACM 以查看文件本身中指定的编解码器是否存在并且可以处理转换(图 1)。## 攻击面

Outlook 要播放的声音文件是波形音频文件格式( WAV)。它通过接收声音文件路径的PlaySound函数播放。PlaySound将加载文件、解析它,然后调用soundOpen,后者将调用不同的波形函数,例如waveOutOpen

WAV 文件充当多个音频编解码器的容器(或包装器)。编解码器是一种对数据流(如图像、视频或音频)进行编码或解码的程序或代码。通常,编解码器将采用脉冲编码调制(PCM) 编码,这是一种表示采样模拟信号的简单方法。

我们可以在三个主要攻击面上搜索漏洞:

  1. WAV 格式解析
  2. 音频压缩管理器
  3. 不同的音频编解码器

WAV 格式解析

WAV 格式解析是在 winmm.dll(实现 Windows 多媒体 API 的库)中的函数soundInitWavHdr内实现的。那里呈现的攻击面并不大,而且似乎已经过审查;我们没有在那里发现任何漏洞。

什么是音频压缩管理器?

音频压缩管理器 (ACM) 是负责处理 WAV 文件中使用的编解码器不使用简单 PCM 编码的情况的代码,因此需要由自定义解码器进行解码。这些解码器在扩展名为 .acm 的文件中实现。一个常见示例是 MP3 编解码器,它在 l3codeca.acm 中实现。每个编解码器都由一个驱动程序处理(它与内核模式驱动程序不同,但功能相似),该驱动程序通过 ACM 注册。

每当需要转换时,例如将 MP3 转换为 PCM 或反之,ACM 就会开始工作并管理此转换。当我们使用未使用 PCM 的 WAV 文件时,将查询 ACM 以查看文件本身中指定的编解码器是否存在并且可以处理转换(图 1)。利用漏洞实现 Outlook 的 RCE:第 2 部分图 1:使用 ACM 加载特殊音频编解码器

每个 ACM 驱动程序都必须实现acmdStreamSizeacmdStreamOpen等函数。第一个函数返回转换输出所需的大小(以字节为单位);第二个函数创建流结构并设置适当的字段,例如解码回调函数。

ACM 的攻击面并不大。然而,我们设法在该代码中找到了漏洞,我们将在本文后面展示。

不同的音频编解码器

对于最后一个攻击面,我们默认安装了不同的音频编解码器。在 WAV 文件中使用两种不同的方式指定编解码器:

  1. FORMAT 块中的 wFormatTag
  2. 如果 wFormatTag 是 WAVE_FORMAT_EXTENSIBLE,则 SubFormat 将保存音频编解码器的 GUID。

附录中描述了可用的编解码器列表。

音频信号处理基础

在深入研究代码之前,让我们先熟悉一下音频信号处理的一些基础知识。如果您已经熟悉这些概念,请直接跳至下一部分。

当我们听到声音时,我们实际上听到的是通过传输介质传播的振动。声音是耳朵接收到这些振动波并被大脑感知的结果。

音频信号是连续的波形。要对其进行数字处理,我们需要将其从模拟信号转换为数字信号(例如,使用 ADC 转换器)。这种转换是模拟信号的离散化。为此,我们以均匀间隔的数据点(称为样本)多次对模拟信号进行采样。采样率(也称为采样频率)决定了每秒采集多少个样本。更高的采样率可以捕获更多细节,但也需要更多的存储和处理。

除了采样率之外,我们还有样本大小,即每个样本使用多少位。同样,样本大小越高,样本质量越好(或更接近原始声音)。样本大小通常为每样本 16 位或 24 位。

音频编解码器基于心理声学模型。心理声学是研究声音感知和听力学的科学,即人类听觉系统如何感知各种声音。例如,人类的听力范围在 20 Hz 到 20,000 Hz 之间。因此,为了进一步减小文件大小,音频编解码器可能会删除人类听不到的频率。此外,如果信号的**音量不足以让人类耳朵听到,音频编解码器可以删除这些信号。例如,如果 20 Hz 的声音低于 60 分贝,则听不到。

心理声学模型的例子还有很多;例如,当安静信号在频率或时间上接近响亮信号时,就会被掩盖。

信号的分析、解释和修改都是通过滤波器组进行的,滤波器组将信号划分为子带——不同的分量带,以便对信号的特定部分进行更详细的检查和处理。常用的滤波器组是 DCT 和多相滤波器组。

有了这些基础知识,我们就可以深入研究不同的编解码器。

第一次尝试:越界写入

我们首先尝试研究 MP3,因为与其他编解码器相比,MP3 要复杂得多。大多数其他编解码器仅执行一些简单的转换,而 MP3 在解码过程中有多个步骤(图 2)。利用漏洞实现 Outlook 的 RCE:第 2 部分图 2:MP3 的解码过程 [https://www.researchgate.net/publication/289674716_A_Robust_Data_Embedding_Method_for_MPEG_Layer_III_Audio_Steganography] MP3 音频数据被组织成一系列帧,每帧代表一小段音频。帧由标头和音频数据组成。音频数据使用霍夫曼编码进行压缩。每帧代表每个通道(单声道/立体声)的 1,152 个频域样本。这被划分为两个称为颗粒的块,每个块有 576 个样本。每帧还包含与其解码相关的信息,称为边信息(图 3)。利用漏洞实现 Outlook 的 RCE:第 2 部分MP3 解码过程中执行的大多数操作都很复杂,虽然从理论上讲,它们可能是寻找微妙漏洞的有趣(和酷)的地方,但实际上,许多操作(例如改进的 DCT、多相滤波器组和混叠减少)都是在不断保存 576 个样本值的缓冲区上执行的。因此,在这里找到越界写入漏洞是不切实际的。一个有趣的地方是霍夫曼解码,因为它自然地适用于更动态的数据(而不是 576 个样本缓冲区)。

MP3 霍夫曼解码

使用代码表(而不是二叉树)对颗粒(576 个样本)进行霍夫曼编码。总频率范围从 0 到 22,050(奈奎斯特频率)被划分为五个区域(图 4):

1.、2. 和 3. 三个“大值”区域 - 样本值介于 -8,206 至 8,206 之间

4. “count1 区域” — 四倍值 -1、0 或 1

5.“rzero 区域”——假定较高频率值具有较低振幅,因此不需要编码;这些值等于 0。利用漏洞实现 Outlook 的 RCE:第 2 部分图 4:576 个样本频率线到不同区域的划分 [http://www.mp3-tech.org/programmer/docs/mp3_theory.pdf]

每个区域都有自己的哈夫曼表(0 区域除外),因此不同频率的样本采用不同的编码。

将样本划分到不同区域依赖于以下变量:

  • big_values — 指定大值区域中的样本总数
  • region0_count 和 region1_count — 将 big_values 划分为子区域;从 big_values 中减去它们的总和可得出 region2 中的样本数量。
  • part2_3length — 指定比例因子(第 2 部分)使用多少位,以及霍夫曼编码(第 3 部分)使用多少位

解码 576 个样本的过程如下:

  • 解码 big_values 区域中的样本
  • 解码 count1 区域中的样本
  • 如果处理的位数大于 part2_3length,那么我们实际上已经解码了所有输入数据,甚至过度读取了数据 -因此,从 total_samples_read 中减去 4(即丢弃这些输入位)
  • 如果还有样本,则用 0 填充(这形成 0 区域)

表 1 中的该逻辑以伪代码形式显示。

  total_samples_read = 0;

// Decode big_values region
[redacted for brevity]

// Decode count1 region [1]
for (int i = 0; i < count1; i++) {
    samples[total_samples_read++] = huff_decode(bitstream, count1_huff_table);
}
if (bits_processed > part2_3length) [2] {
    // Overread. Throw last 4 samples
    total_samples_read -= 4;
}

// Fill rzero region with zeros
for (int i = total_samples_read; i < 576; i++) {
    samples[total_samples_read++] = 0; [3]
}

复制

表1:霍夫曼解码逻辑的伪代码

不幸的是,代码遗漏了一个特定的边缘情况,这会导致整数下溢。

  • 大值区域大小为 0
  • Count1 区域大小为 0
  • Part2_3长度为0
  • Bits_processed 大于 0

在这个特定情况下,bits_processed 将大于 part2_3length(在 scalefactors 解码期间,它在解码过程之前达到非零值)。因此,代码将“丢弃”最后四个样本。由于代码未处理任何样本,total_samples_read 为 0。这里将出现下溢,代码认为我们处理了 -4 个样本。现在,它将按如下方式填充 0 区域:

  • 将缓冲区指针设置为 &samples[total_samples_read]。这指向样本缓冲区前的16 个字节。
  • 将写入大小设置为 576 - total_samples_read = 576 - (-4) = 580 个整数。

因此,我们在样本缓冲区之前直接进行了越界写入,值为零。太棒了!利用漏洞实现 Outlook 的 RCE:第 2 部分图 5:样本缓冲区的越界写入

那么为什么这个漏洞没有收到 CVE?样本缓冲区是结构的一部分,样本缓冲区之前的字段是 scalefactor 数组。这是一个包含我们已经控制的字段的数组,因此我们在这里并没有真正产生有趣的影响。

代码对样本进行反量化后,也会出现同样的漏洞。它再次填充 0 区域,这次是用反量化缓冲区填充的。想猜猜反量化缓冲区之前是什么吗?霍夫曼解码样本缓冲区。这是我们之前看到的相同样本缓冲区,我们也可以控制它。所以,再一次,我们没有受到真正的影响。

这些越界写入仍然存在于 MP3 解码器中(可通过 WAV 和 .mp3 文件访问),据 Microsoft 称,它们可能会在未来得到修复。虽然在编解码器逆向过程中没有发现影响深远的漏洞,但我们相信解码器执行的不同复杂操作中可能隐藏着漏洞。

第二次尝试:IMA ADPCM 编解码器中的整数溢出

我们的下一个尝试是 IMA ADPCM 编解码器,它在 imaadp32.acm 中实现。正如我们现在所知,ACM 将管理来自不同编解码器的转换。要注册编解码器,代码必须实现 ACM 函数。其中一个函数是 acmStreamSize 它返回目标缓冲区所需的字节数。

IMA ADPCM 编解码器根据输入有效负载的大小 ( cbSrcLength )、对齐 ( nBlockAlign ) 和每块的样本数 ( wSamplesPerBlock;表 2) 计算目标缓冲区大小。

  (cbSrcLength / pwfxSrc->nBlockAlign) *(pwfxSrc->wSamplesPerBlock * pwfxDst->nBlockAlign)

复制

表 2:缓冲区大小计算

在进行乘法之前,代码确保计算不会导致整数溢出(表 3)。

  SrcNumberOfBlocks = cbSrcLength / pwfxSrc->WaveFormat.nBlockAlign;
  v14 = pwfxSrc->wSamplesPerBlock * pwfxDst->nBlockAlign;

  if ( 0xFFFFFFFF / v14 < SrcNumberOfBlocks )
    return ERROR_OVERFLOW;

  IsThereRemainder = cbSrcLength % pwfxSrc->WaveFormat.nBlockAlign;

  if ( IsThereRemainder )
    ++SrcNumberOfBlocks;

  DstBufferLengthInBytes = v14 * SrcNumberOfBlocks;

复制

表 3:防止整数溢出的计算检查

显然,这种检查不足以防止溢出。如果cbSrcLength / pwfxSrc->nBlockAlign的除法中有余数,则代码会增加 ( cbSrcLength */ pwfxSrc->nBlockAlign )*的结果,该结果用于乘法。溢出检查不涵盖此增量。因此,我们仍然可以通过指定自定义值来溢出目标缓冲区长度。

我们需要提供cbSrcLength除以**pwfxSrc->nBlockAlign后有余数。

表 4 显示的是导致整数溢出的值的示例。

  cbSrcLength = 0x71c71c72
  pwfxSrc->nBlockAlign = 8
  pwfxSrc->wSamplesPerBlock = 9
  pwfxDst->nBlockAlign = 2

复制

表 4:导致整数溢出的值示例

这会导致目标缓冲区为 0xE 字节,而目标缓冲区应该要大得多。

虽然这看起来像是一个可能导致越界写入的整数溢出,但解码函数正确地确保在分配的缓冲区后没有发生写入,并且不会假设缓冲区分配了正确的大小。

因此,尽管我们提供了多个样本,但实际上当目标缓冲区已满时,代码就会停止。AD PCM 编解码器(在msadp32.acm中实现)中也会发生相同的行为。

第三次尝试:ACM 中的整数溢出(CVE-2023-36710)

最后,我们在ACM代码中发现了一个不错的漏洞。在播放WAV文件的过程中,ACM管理器中的mapWavePrepareHeader函数(在**msacm32.drv中实现)被调用。

此函数存在整数溢出漏洞。它调用acmStreamSize,后者调用驱动程序的回调。回想一下,此函数返回目标缓冲区所需的大小。收到此大小后,mapWavePrepareHeader会添加 176 个字节(将进入目标缓冲区的流头的大小),而不检查溢出。此添加的结果将传递给GlobalAlloc(图 6)。利用漏洞实现 Outlook 的 RCE:第 2 部分图 6:mapWavePrepareHeader 中的易受攻击的代码

这是一个可利用的问题。我们可以通过使acmStreamSize返回 0xffffff50 到 0xffffffff 之间的值,使**GlobalAlloc分配一个非常小的缓冲区,而不是一个很大的缓冲区。在此分配之后,我们可以导致两次越界写入:

  1. 流标头值,例如结构大小、源和目标缓冲区指针和大小。这些值是部分可控的。
  2. 编解码器的解码值。这些值是完全受控制的。

要触发漏洞,我们需要提供一个 WAV 样本,其大小在解码后将大于或等于 0xffffff50。虽然这听起来很容易实现,但我们在尝试过程中发现,在某些编解码器中可能无法实现。例如,对于 MP3 编解码器,作为计算的一部分,需要乘以 1,152 或 576(即每帧的样本数)。该计算的结果永远不会在我们想要的范围内。

最后,我们成功利用IMA ADP 编解码器触发了漏洞。文件大小约为1.8 GB。通过对计算结果进行数学限制运算,我们可以得出IMA ADP 编解码器的最小可能文件大小为1 GB。

如果有可用于动态构建漏洞的脚本引擎,利用此类漏洞会变得更加容易。由于 Windows Media Player 没有脚本引擎,因此利用起来可能更具挑战性。这可能仍然是可能的(正如 Chris Evans 在他的“高级漏洞利用:针对 Linux 桌面的无脚本 0day 漏洞利用”博客文章中所展示的那样)。然而,在 Outlook 应用程序上下文(或其他即时通讯应用程序)中成功利用此漏洞的机会更大。

概括

本系列博文涵盖了从在野利用的漏洞开始的研究。(如果您还没有阅读第 1 部分,请阅读。)研究之旅随后继续寻找绕过方法,最终找到了一个伴随漏洞并将其链接起来以实现零点击 RCE 链。虽然这些漏洞已修复,但攻击者仍在继续寻找可以远程利用的类似攻击面和漏洞。

截至目前,我们研究的 Outlook 攻击面仍然存在,并且有新的漏洞可以发现和利用。尽管微软已经修补了 Exchange,以删除包含 PidLidReminderFileParameter 属性的邮件,但我们不能排除绕过此缓解措施的可能性。

原文始发于微信公众号(红云谈安全):利用漏洞实现 Outlook 的 RCE:第 2 部分

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月25日12:57:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   利用漏洞实现 Outlook 的 RCE:第 2 部分https://cn-sec.com/archives/3094026.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息