Game of Rars--探索 WinRAR 中新的远程代码执行漏洞(CVE-2023-40477)
2023-8-31 16:28:0 Author: paper.seebug.org(查看原文) 阅读量:33 收藏

原文链接:“Game of Rars” – Exploring a New Remote Code Execution Vulnerability in WinRAR with Proof-of-Concept (CVE-2023-40477)
译者:知道创宇404实验室翻译组

摘要

  • 拥有5亿以上用户的WinRAR,曝出新的漏洞(CVE-2023-40477,CVE-2023-38831);
  • CVE-2023-40477的PoC
  • 虽然被认为是RCE假定可被利用,但实际上影响并不大;
  • 本文研究内容包括:其影响、可被利用的场景以及缓解措施;
  • 该漏洞已在最新的Winrar v6.23中得到修复,本文也会提出解决办法。

CVE-2023-40477:概述和PoC

八月中旬,WinRAR 6.23发布了一些关于关键漏洞的警告。我们了解到漏洞(CVE-2023-40477)目前已经修复,且公布了以下信息,具体内容详看下文:

img

二进制文件对比

我们知道6.23版本已经修复,为了复现找到了修复前的版本。通过下载便携版的WinRAR-v6.23和WinRAR-v6.22,观察了解到:

img

WinRAR的目录结构和的文件

可以看到winrar.exe可能只是一个图形界面,如果在解压过程中存在漏洞,那么它也可能存在于“unrar.exe”中。通过对比6.23和6.22的差异(忽略注释),我们得到以下结果:

img

第一个BinDiff输出

查看流程图,6.23版本中发现了几个有趣的新增内容(大型函数图中,看起来像是主要的提取):

img

提取中的BinDiff附加内容

仔细观察,这些似乎是额外的检查!

img

blocksBinDiff x86中有趣的附加块

这看起来很有希望!我们在这里看到一些var < 255!!有趣的是,这里看起来进行了溢出检查。所以是时候触发漏洞了(例如将字节更改为最大值)。

我对RAR格式进行了研究,从描述中我们知道这与RAR4(vol3?)恢复卷有关,因此我生成了具有这些特性的RAR4文件,它给出了以下文件列表:

  • RAR_FILE.rar
  • RAR_FILE.r00
  • RAR_FILE00.rev
  • RAR_FILE.r01
  • RAR_FILE01.rev

我尝试对".rev"和"rXX"卷中“类字节”的值进行了暴力破解,但没有成功。它没有触发任何内容。 接着尝试搜索一些"unrar"源代码 ,然后成功找到了这个旧的存储库:https://github.com/aawc/unrar

查看源代码,可以看到多个"255"常量检查,尤其是在"recvol3.cpp"中。它们也出现在最初的6.22源代码中,难道是因为溢出而添加了额外的检查?

在深入研究的过程中,我发现实际上这些安全检查均与0xff / 255有关。

漏洞

img

在recvol3.cpp中的CVE-2023-40477

在这里,P[i]’s是从 ".rev" 文件中提取的。它们位于文件末尾。这些P[i]’s用于确定它们代表哪个恢复卷以及适用于哪个 FileNumberFileNumber 也从中获取,存储在 P[2] 中。

紧接着,在我们控制的索引位置上分配并放置了 File\ ,而这个数组的大小是256!(第241行),而这解释了为什么有255次检查。

因为该索引实际上等于:P[2]+P[0]-1,我们几乎可以任意控制rev卷的内容。因此,我们可以用指针(指向 File 结构)来覆盖该缓冲区,它们将覆盖当前对象中的下一个属性。

Poc撰写

为了触发该漏洞,我们发现需要在recvol3.cpp中调用"Restore()"函数。此外还需要进行重建步骤,以便对指针进行覆写。

为了实现这一点,需要有一些缺失的rar卷(.r00文件缺失),以及可用的.rev文件。此外,还要确保crc32校验正确,而这只需要几行代码就能进行触发。

为了方便起见,使用了通过GUI生成的原始rar4恢复卷,但是这可以使用更小且更高效的触发方式,且最多可能只需2-3个文件。

# 1. re-generate malformed recovery vols.
data = open('%s01.rev' % ARCHIVE_NAME, 'rb').read() # just use the first and malform it up.
names = ['%s%s.rev' % (ARCHIVE_NAME, str(i).zfill(2)) for i in range(256)]
# "destroy" the P[i]'s
datas = [data[:-7] + bytes([0xf0, 0x00, i]) + calc_crc(data[:-7] + bytes([0xf0, 0x00, i])) for i in range(256)]

# 2. overwrite malformed recovery vols.
for i in range(256):
    fname = names[i]
    data = datas[i]
    open(fname, 'wb').write(data)
PoC地址:https://github.com/wildptr-io/Winrar-CVE-2023-40477-POC/

在发现漏洞后不久,还看到了rar-labs网站上的https://www.rarlab.com/vuln_rev3_names.html, 这基本上证实了我们的发现。

利用这一点,成功地在几种情况下使winrar/unrar崩溃:

  • 内存集用零覆盖无效内存(可能在缓冲区之后):

在Buf的memset上,使用winrar的unrar.exe时崩溃

源代码中的Buf的memset
  • 在使用“提取到”功能时,winrar.exe中可能出现堆溢出的情况
winrar.exe堆溢出–可能的场景

利用性

为了确定可利用性,看看在256个数组之后覆盖的结构。以此来确定攻击者如何利用这个原语来获取远程代码执行(RCE),以及存在哪些缓解措施。

// RecVolume3 struct - that gets overflowed
class RecVolumes3
{
  private:
    File *SrcFile[256]; // overflow in here with File* pointers.
    Array Buf;

#ifdef RAR_SMP
    ThreadPool *RSThreadPool;
#endif
  public:
    RecVolumes3(CommandData *Cmd,bool TestOnly);
    ~RecVolumes3();
    void Make(CommandData *Cmd,wchar *ArcName);
    bool Restore(CommandData *Cmd,const wchar *Name,bool Silent);
    void Test(CommandData *Cmd,const wchar *Name);
};
...
...
// Array template class:
template  class Array
{
  private:
    T *Buffer;
    size_t BufSize;
    size_t AllocSize;
    size_t MaxSize;
  public:
    Array();
    Array(size_t Size);
    Array(const Array &Src); // Copy constructor.
    ~Array();

总而言之,我们用“File*”指针溢出“Buffer”对象,同还需要绕过这里启用的许多防御措施。 幸运的是,里面有很多保护措施:ASLR、CFG、Stack-Cookie和DEP。

这还没有提到winrar版本之间的二进制差异。尽管可能存在漏洞利用的潜力,但对于普通黑客来实际上的利用可能性并不高。

影响

尽管其CVE等级很高,但成功利用漏洞所需的复杂性表明广泛滥用的可能性很低,这与广泛利用的Log4j RCE漏洞不同。

有趣的是,Chromium似乎也使用了unrar库:https://chromium.googlesource.com/chromium/src/+/6ff23b0604e2edbe7ef282564ea340f5c72ab91a%5E%21/.

尽管没有代码参考表明其使用情况,但unrar库有可能作为第三方依赖项被集成到Chrome OS中。

解决措施

可考虑的应对措施:

  • 完全修复:将Winrar更新到6.23+将完全修复。

  • 补丁修复:如果更新不可用或难以部署,可以考虑阻止使用*.rev文件(最好同时阻止*.rXX文件和*.partXX.rar文件)。尽管并没有官方支持肯定,但这可能是目前的一个快速的修复方法。

参考链接

  1. CVE-2023-40477 in the news – The Register

  2. CVE-2023-40477 report

  3. RAR-Labs extra explanation for CVE-2023-40477 in 6.23 fix


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/3019/



文章来源: https://paper.seebug.org/3019/
如有侵权请联系:admin#unsafe.sh