作者:B1tg
本文为作者投稿,Seebug Paper 期待你的分享,凡经采用即有礼品相送! 投稿邮箱:[email protected]
2023年8月23号,group-ib[1] 公开了 WinRAR 中存在的 0day 漏洞 CVE-2023-38831,其被在野利用于攻击交易员。
该漏洞触发需要用户打开 zip 压缩包并点击其中的诱饵文件,可被用于钓鱼攻击。
影响版本为 winrar < 6.23
漏洞触发过程主要分成两个环节: 1. 点击诱饵文件时额外的文件被释放 2. 点击文件后程序执行了额外释放的文件而非用户点击文件
文件释放 bug
zip 文件中包含三种数据结构:ZIPFILERECORD, ZIPDIRENTRY, ZIPENDLOCATOR,这里主要关心 ZIPDIRENTRY,其用于描述压缩包内目录的结构,每个文件/目录都对应一个这样的数据结构
用户在 winrar 窗口点击某个文件后,winrar 会遍历压缩包中的 direntry,依次比较direntry->filename 和点击文件名(click_name),匹配成功的 direntry 对应的文件后续会解压到临时目录下,比较函数为 0047F790,匹配成功该函数返回1,失败则返回0
比较成立的条件为 entry_name 等于 click_name,或者 entry_name 等于 click_name 加上路径分隔符。
比较逻辑用伪代码表示为:
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对应的文件就会被释放,下面进行验证。
构造如下的文件夹:
压缩成 zip 后包含7个 dirEntry 结构:
在二进制编辑器中修改 dirEntry[1]
的 filename,由Cir 改成 Dir
保存后打开该压缩包,可以看到同名的文件夹和文件夹
此时文件中的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(右击查看文件也可以),可以看到临时目录下有三个文件被释放,和分析结果一致。
反常的执行逻辑
poc样本具有如下结构:
根据上一节的分析,在 winrar 中双击样本的 dirEntry[2]("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 "
BOOL ShellExecuteExW(
[in, out] SHELLEXECUTEINFOW *pExecInfo
);
实际上 ShellExecuteExW 会运行临时目录下的 CLASSIFIED_DOCUMENTS.pdf .cmd
触发漏洞,整个过程可以描述为:用户在 winrar 中点击了一个文档文件,winrar 却执行了同名目录下的脚本而非文档文件本身。
ShellExecuteExW 函数为什么在路径末尾有空格的情况下执行了一个 .cmd 文件?
分析发现,ShellExecuteExW 函数会调用 shlwapi!PathFileExistsDefExtAndAttributesW 对路径进行处理
在 PathFileExistsDefExtAndAttributesW 函数中,当路径末尾有空格时 PathFindExtensionW 函数会返回NULL,之后会进入函数 sub_7FF741824B4 给路径添加上通配符.*
进行文件搜索,并对搜索到的文件进行后缀判断,第一个符合条件的文件名被用作后续执行,在前面的情况下,搜索到的就是文件"C:\\Users\\DELL\\AppData\\Local\\Temp\\Rar$DIa21552.1835\\CLASSIFIED_DOCUMENTS.pdf .cmd"
由于后缀判定按给定列表遍历,可以判断出 ShellExecuteExW 的后缀搜索的顺序依次为: - .pif - .com - .exe - .bat - .lnk - .cmd
也就是说如果在文件夹下放置多个这些后缀的文件,会按照优先级执行第一个。在构造样本时不一定要用 .cmd
后缀,上面的选项都能触发。
目前公布的在野样本、POC使用的都是类似如下的 direntry 组合触发漏洞:
- a.pdf
- a.pdf /
- a.pdf /a.pdf .cmd
一些厂商也通过 direntry 中空格加斜杠这样的特征[3]来检测此类漏洞。
通过对函数 PathFindExtensionW 进行分析发现,只要路径中的最后一个 .
后面包含空格,该函数返回值就为空,ShellExecuteExW 就能进入搜索逻辑。
于是可以构造类似如下 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://isc.sans.edu/diary/Analysis+of+RAR+Exploit+Files+CVE202338831/30164/
-
https://aleeamini.com/cve-2023-38831-winrar-bug-or-windows-feature/
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/3036/