CVE-2023-38831(WinRAR)漏洞分析
CVE-2023-38831(WinRAR)漏洞分析
1. 漏洞简介
CVE-2023-38831
是WinRAR
(<=6.22
)版本中存在的可执行任意恶意代码的漏洞,该漏洞需要被攻击的用户双击压缩包中的文件,随后恶意代码将会在被攻击用户的电脑中运行,因此此漏洞可用于钓鱼。
2. 漏洞复现
复现环境与软件:Windows
操作系统、WinRAR
(<=6.22
)、二进制编辑器(如WinHex
)
Step1 文件准备
需要准备的文件及其结构如下所示:
1 |
|
其中FILE_NAME.xxxA
为文件夹,而FILE_NAME.xxxB
为文件,文件夹名和文件只有一个字符上的区别,此外xxx
为文件的后缀名。e.g.
Step2 压缩为ZIP文件
将上述FILE_NAME.xxxA
文件夹和FILE_NAME.xxxB
文件压缩为ZIP(请注意,这里请选择压缩为ZIP,否则后续打开时压缩包会显示损坏):
Step3 修改ZIP文件
使用二进制编辑软件打开上述压缩文件,这里我使用的是WinHex。然后,将FILE_NAME.xxxA
和FILE_NAME.xxxB
中的A
和B
字符替换为空格(必须是空格!):
Step4 触发漏洞
使用WinRAR
打开压缩包并双击FILE_NAME.xxx
文件,然后可以观察到恶意代码被执行(这里cmd里面仅打开了记事本):
上述展示了手工生成poc的方法,下面链接提供了自动生成poc的脚本exp:
b1tg/CVE-2023-38831-winrar-exploit: CVE-2023-38831 winrar exploit generator (github.com)
3. 漏洞原理
一句话根因描述:该漏洞主要利用了
WinRAR
解析过程中存在的同名前缀混淆问题和ShellExecuteExW()
细节:
sub_7FF7A7ADEBF4()
函数内while
循环体内遍历压缩包中的所有文件,然后找到匹配项(ZIP界面选中时会有一个文件名,与之匹配):
漏洞触发的第一个条件,恶意代码被解压到本地:
由于上述的代码逻辑比较复杂,这里猜测上述的匹配仅检查公共前缀,如果公共前缀相同,则会进行解压。
- e.g. 假设压缩包选中的文件名为
A
,由于我们对压缩包的二进制数据进行修改,实际的文件名为"A "
; - 注意到由于我们的修改,导致压缩包中出现了同名文件(文件名为
"A "
和文件夹名为"A "
,这在windows操作系统上是不允许的),在解压过程中,文件夹名为"A "
与文件名"A "
前缀相同,因此文件夹名为"A "
的文件均会被解压到临时目录中 [ZIP压缩包二进制中存储的文件名为"A \B"
,"A \C"
etc.]; - 因此,恶意的cmd文件也被错误的解压到临时目录中(⭐ 这一点很关键)。
- e.g. 假设压缩包选中的文件名为
sub_7FF7A7B1609C
函数内执行解压后的文件:
漏洞触发的第二个条件,恶意代码被执行:
WinRAR
使用ShellExecuteExW
执行解压的文件,传入的文件名为"A "
,也就是可以抽象称为ShellExecuteExW()
调用了file A
。- 由上述分析得知,文件
"A "
和文件夹内"A "
的所有文件均已被解压到本地临时目录(这里需要额外注意一点,文件"A "
的末尾空格是在后缀名之后,而Windows系统不允许文件名后有空格,因此在创建文件的时候,空格会被删除); ShellExecuteExW()
被调用是传入的文件路径为:"临时目录路径\A "
。在寻找该文件的时候,由于"A "
解压本地时文件名改为了"A"
(空格被删除),因此ShellExecuteExW()
实际上执行的是"A .cmd"
,即执行了恶意代码;
这里的陷阱和WinExec的很相似,可以参考下面这篇文章中的安全备注
- 因此,恶意的cmd文件名必须是
"A .cmd"
,否则ShellExecuteExW()
将无法被调用起来
- 由上述分析得知,文件
综上所述,该漏洞触发必须满足两个条件:
1⃣ 通过修改压缩包二进制数据构造同名文件和同名文件夹名(正常情况下是不允许的)且必须以一个空格作为后缀,此做法的目的是将同名文件夹下的恶意文件解压到本地;
2⃣ 包含恶意代码文件名必须与步骤1⃣中构造同名文件和同名文件夹名相同(包含空格),此做法保证
ShellExecuteExW()
执行的是恶意代码文件而不是解压的正确文件。
4. 修复措施
- 将
WinRAR
更新到高于6.22的版本 - 不打开来源不明的压缩文件