漏洞介绍

2023年8月23号,group-ib0 公开了 WinRAR 中存在的 0day 漏洞 CVE-2023-38831,其被在野利用于攻击交易员。

该漏洞触发需要用户打开 zip 压缩包并点击其中的诱饵文件,可被用于钓鱼攻击。

影响版本为 winrar < 6.23

分析

漏洞触发过程主要分成两个环节:

  1. 点击诱饵文件时额外的文件被释放
  2. 点击文件后程序执行了额外释放的文件而非用户点击文件

文件释放 bug

zip 文件中包含三种数据结构:ZIPFILERECORD, ZIPDIRENTRY, ZIPENDLOCATOR,这里主要关心 ZIPDIRENTRY,其用于描述压缩包内目录的结构,每个文件/目录都对应一个这样的数据结构

image-20230915122125212.png

image-20230915122758907.png

用户在 winrar 窗口点击某个文件后,winrar 会遍历压缩包中的 direntry,依次比较direntry->filename 和点击文件名(click_name),匹配成功的 direntry 对应的文件后续会解压到临时目录下,比较函数为 0047F790,匹配成功该函数返回1,失败则返回0

image-20230915123421334.png image-20230915123431875.png

比较成立的条件为 entry_name 等于 click_name,或者 entry_name 等于 click_name 加上路径分隔符。

比较逻辑用伪代码表示为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
extract_list = []
def compare_click_and_entry(entry_name, click_name):
    click_name_len = len(click_name)
    if entry_name[:click_name_len] == click_name and \
      entry_name[click_name_len] in ("\\", "/", "\x00"):
        return 1
    return 0

for direntry in zip.direntry_list:
    if compare_click_and_entry(direntry.name, click_name):
        extract_list.append(direntry.name)

在poc样本中1 ,诱饵文件对应的是 dirEntry[2], 点击诱饵文件后 click_name = "CLASSIFIED_DOCUMENTS.pdf "

三个等待比较的 entry_name 为:

  • "CLASSIFIED_DOCUMENTS.pdf /"
  • "CLASSIFIED_DOCUMENTS.pdf "
  • "CLASSIFIED_DOCUMENTS.pdf /CLASSIFIED_DOCUMENTS.pdf .cmd"

三个 entry_name 比较结果都为 1,两个文件将会被释放到临时目录下,第一个 bug 出现了,虽然用户点击了一个文件,但是 winrar 额外释放了一个 .cmd 文件。

这个 bug 和 entry_name 中的空格、子文件的名字无关,只要 click_name 和 entry_name 成功匹配,entry对应的文件就会被释放,下面进行验证。

构造如下的文件夹:

image-20230915134747867.png

压缩成 zip 后包含7个 dirEntry 结构:

image-20230915134954415.png

在二进制编辑器中修改 dirEntry[1] 的 filename,由Cir 改成 Dir

image-20230915135223791.png

保存后打开该压缩包,可以看到同名的文件夹和文件夹

image-20230915140057322.png

此时文件中的7个 entry_name 如下:

  • Bir
  • Dir
  • Dir/
  • Dir/a1.txt
  • Dir/a2.txt
  • Eir
  • Eir/e1.txt

如果点击文件 Dir,匹配的 entry_name 如下,对应的文件会被释放

  • Dir
  • Dir/
  • Dir/a1.txt
  • Dir/a2.txt

双击winrar中的文件Dir(右击查看文件也可以),可以看到临时目录下有三个文件被释放,和分析结果一致。

image-20230915140310495.png

反常的执行逻辑

poc样本具有如下结构:

image-20230916095717911.png

根据上一节的分析,在 winrar 中双击样本的 dirEntry[1]("CLASSIFIED_DOCUMENTS.pdf "),winrar 会在临时目录下释放两个文件:

  • CLASSIFIED_DOCUMENTS.pdf
  • CLASSIFIED_DOCUMENTS.pdf .cmd

随后 winrar 会调用函数 ShellExecuteExW 执行文件,传入的 shExecInfo.lpFile 为: "C:\\Users\\DELL\\AppData\\Local\\Temp\\Rar$DIa21552.1835\\CLASSIFIED_DOCUMENTS.pdf "

1
2
3
BOOL ShellExecuteExW(
  [in, out] SHELLEXECUTEINFOW *pExecInfo
);

image-20230830210654263.png

实际上 ShellExecuteExW 会运行临时目录下的 CLASSIFIED_DOCUMENTS.pdf .cmd 触发漏洞,整个过程可以描述为:用户在 winrar 中点击了一个文档文件,winrar 却执行了同名目录下的脚本而非文档文件本身。

ShellExecuteExW 函数为什么在路径末尾有空格的情况下执行了一个 .cmd 文件?

分析发现,ShellExecuteExW 函数会调用 shlwapi!PathFileExistsDefExtAndAttributesW 对路径进行处理

image-20230916111142288.png

在 PathFileExistsDefExtAndAttributesW 函数中,当路径末尾有空格时 PathFindExtensionW 函数会返回NULL,之后会进入函数 sub_7FF741824B4 给路径添加上通配符.* 进行文件搜索,并对搜索到的文件进行后缀判断,第一个符合条件的文件名被用作后续执行,在前面的情况下,搜索到的就是文件"C:\\Users\\DELL\\AppData\\Local\\Temp\\Rar$DIa21552.1835\\CLASSIFIED_DOCUMENTS.pdf .cmd"

image-20230916105035776.png

image-20230916104932755.png

由于后缀判定按给定列表遍历,可以判断出 ShellExecuteExW 的后缀搜索的顺序依次为:

  • .pif
  • .com
  • .exe
  • .bat
  • .lnk
  • .cmd

也就是说如果在文件夹下放置多个这些后缀的文件,会按照优先级执行第一个。在构造样本时不一定要用 .cmd 后缀,上面的选项都能触发。

目前公布的在野样本、POC使用的都是类似如下的 direntry 组合触发漏洞:

  • a.pdf
  • a.pdf /
  • a.pdf /a.pdf .cmd

一些厂商也通过 direntry 中空格加斜杠这样的特征2来检测此类漏洞。

通过对函数 PathFindExtensionW 进行分析发现,只要路径中的最后一个 . 后面包含空格,该函数返回值就为空,ShellExecuteExW 就能进入搜索逻辑。

image-20230916224201333.png

于是可以构造类似如下 direntry 组合的样本绕过常规检测

  • top.secret pdf
  • top.secret pdf/
  • top.secret pdf/top.secret pdf.bat

相关链接

https://www.group-ib.com/blog/cve-2023-38831-winrar-zero-day/

https://github.com/b1tg/CVE-2023-38831-winrar-exploit

https://isc.sans.edu/diary/Analysis+of+RAR+Exploit+Files+CVE202338831/30164/

https://aleeamini.com/cve-2023-38831-winrar-bug-or-windows-feature/

Changelog: