11

Game of Rars--探索 WinRAR 中新的远程代码执行漏洞(CVE-2023-40477)

 1 year ago
source link: https://paper.seebug.org/3019/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原文链接:“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崩溃:

  • 内存集用零覆盖无效内存(可能在缓冲区之后):
18f97d08-7dfa-40bf-aebb-8fcdc567d65d.png-w331s

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

2b90b006-d525-4fb2-8aa1-4061627b8c6c.png-w331s

源代码中的Buf的memset

  • 在使用“提取到”功能时,winrar.exe中可能出现堆溢出的情况
    9b82c3fb-6155-4fea-9b7e-ad34cd3a8e4e.png-w331s

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文件)。尽管并没有官方支持肯定,但这可能是目前的一个快速的修复方法。


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


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK