WinRAR 代码执行漏洞

Posted by JenI on 2019-02-23 00:00:00+08:00

前言

WinRAR是一个文件压缩管理共享软件,由EugeneRoshal开发。首个公开版本RAR1.3发布于1993年。近日Check.Point团队爆出了一个关于WinRAR的代码执行漏洞,但严格意义上来讲,这实际上是一个目录穿越漏洞,攻击者利用漏洞可以构造恶意的压缩文件,待用户使用 WinRAR 进行解压时,则会触发漏洞,从而导致恶意文件被写入任意目录.

漏洞分析

此漏洞是由于 WinRAR 所使用的动态链接库 UNACEV2.dll 文件在处理 ACE 文件时,没有对文件名做充分的过滤,从而使得文件通过恶意的文件名进行了目录穿越操作。

先来了解一下 ACE 归档文件的具体格式。

我随便准备了个文件,并使用 WinAce 进行打包,打包时注意选择存储完整路径

WinRAR-Code-Execution-1

然后使用 acefile.py 查看 test.ace 文件头部信息,acefile.py 文件可以在下面的链接下载:

https://github.com/droe/acefile

在终端执行下面的命令

python acefile.py --headers test.ace
WinRAR-Code-Execution-2

我在图中标出来三个部分

  1. 第一个部分是对文件的一个总的概览,都很好理解,其中 headers 里的字段,MAIN:1 表示 ace 归档文件主体,FILE:1 表示这个 ace 压缩包内包含一个文件

  2. 第二个部分是 MAIN 的 header 信息。因为软件是未注册版本,因此在创建归档文件的过程中,为其添加了 advert 广告字段。

  3. 第三个部分是压缩包内文件的 header 信息,这里比较关键,因为漏洞的位置就在这一部分的 filename 字段,此处需要着重关注一下 hdr_crc、hdr_size、、filename 三个字段,漏洞的实现需要对这三个部分的数据进行修改。hdr_crc 是一个校验值,如果 hdr_crc 和数据不匹配,解压缩的过程则会被中断,hdr_size 是文件头部信息的总长度,filename 是文件名,由于创建 ace 文件时选择的是 store full path,因此这里的 filename 是包含完整路径的。

再使用十六进制编辑器具体看看文件的情况,我这里使用了 C32asm

WinRAR-Code-Execution-3

图片中我使用不同颜色的线标识出了十六进制与 acefile 脚本读取文件头部信息相对应的位置。红线为文件头部校验数据段 hdr_crc,在 C32asm 中十六进制数据采用了小端序,因此和 acefile 读取出的 hdr_crc 数据内容是相反的。黄线为文件头部字节大小,其包含了从下一字节开始到 filename 末尾字节的总长度,十六进制 00 4E,转换为十进制刚好为 78。粉红线为文件名,十六进制数据中文件名之前的两个字节存储了文件名的长度,图中使用绿色方框标出,十六进制大小 002F,转换为十进制 47,与粉红线标出的文件名长度吻合。

到这里就基本了解了 ace 文件的头部信息,可以构造恶意的 ace 文件了。通过十六进制编辑器修改 filename 字段的值,然后根据 filename 字段长度修改前面的两个字节,再修改对应的 hdr_size,最后通过 acefile.py 计算出文件的校验值,修改 hdr_crc 对应位置数据即可成功创建恶意的 ace 文件。

漏洞复现

我使用的虚拟机环境为 64 位 Win7,开机启动文件夹的路径为

C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

现在想要实现用户在解压 test.ace 文件时,test.txt 会被恶意的解压到 Startup 文件夹,则需要将 test.ace 文件 header 头中 filename 字段值内的路径修改为 Win7 的启动文件夹路径,具体操作如下

为方便操作,先新建一个十六进制文件,然后将恶意的 filename 粘进去,需要注意的是,这里的盘符要写两次,同时这里我将 test.txt 修改为了 virus.txt,方便与原文件进行区分:

C:\C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\virus.txt
WinRAR-Code-Execution-4

一共占用了 97 个字节,而 ace 文件内的 filename 字段占用了 47 个字节,因此需要为原本的 filename 增加 50 个字节的位置,选中 filename 字段的末尾,点击编辑,插入数据,大小为 50

WinRAR-Code-Execution-5

然后选中完整的 filename,将恶意的 97 个字节数据粘贴进来

WinRAR-Code-Execution-6

修改前两个字节 ,十进制 97,十六进制 61,小端序,61 00

WinRAR-Code-Execution-7

至此 header 长度为 128 字节,十六进制 80,小端序 80 00

WinRAR-Code-Execution-8

修改 hdr_size 为 80 00

WinRAR-Code-Execution-9

保存文件,使用 acefile.py 查看文件头部信息,因为还没有更改 hdr_crc,脚本抛出错误

WinRAR-Code-Execution-10

打开 acefile.py 文件,搜索报错关键字 "header CRC failed",定位到 3061 行附近,条件语句中 ace_crc16(buf) 的值就是我们需要的 hdr_crc 值,这里修改下代码,在抛出错误之前将 ace_crc16(buf) 的值输出

WinRAR-Code-Execution-11

运行脚本,脚本成功输出 hdr_crc 值,十进制 15289,对应十六进制 3BB9,小端序 B9 3B

WinRAR-Code-Execution-12

修改 test.ace 中 hdr_crc 对应的数值,保存后再次运行脚本,脚本成功读取文件的头部信息,可以看到此时的 filename 字段已经修改为了我们的恶意文件名。

WinRAR-Code-Execution-13
WinRAR-Code-Execution-14

此时解压这个文件,就会在 Win7 的启动文件夹内解压出 virus.txt

WinRAR-Code-Execution-15

另外,这个修改后的 ace 文件是可以改后缀为 rar 的,这样可以更好的隐藏攻击

针对此漏洞,有大佬编写了相关脚本,可以更方便的生成 EXP,Github 地址:

https://github.com/WyAtu/CVE-2018-20250

参考

https://research.checkpoint.com/extracting-code-execution-from-winrar/


作者:   JenI   转载请注明出处,谢谢


Comments !