首页
社区
课程
招聘
[翻译]BitDefender:由7z PPMD产生的远程栈溢出漏洞
发表于: 2017-7-31 15:48 3186

[翻译]BitDefender:由7z PPMD产生的远程栈溢出漏洞

2017-7-31 15:48
3186

如果你读我之前的一篇文章觉得无聊的话,那么这篇可能是你想要的。在该系列的第二篇中,我将履行讨论在更复杂环境设置中发生错误的承诺。

需要非常小心的处理提取特定文档格式(例如7z)软件模块中的错误。这不仅对于软件本身,而且对于共享同一个库或基于相同参考实现的许多不同的软件产品来说,这一点至关重要。

所以,来解决这个问题:我相信这个bug并不影响Igor Pavlov的7z的参考实现。但是,如果BitDefender以外的产品受到这个影响,那不会使我感到意外。

在小型供应商的反病毒产品中发现重大漏洞后,我最终决定来探索一下Bitdefender的反病毒产品。因此,我开始了对引擎的模糊测试,一段时间之后就遇到了第一次崩溃,涉及到7z文件格式的崩溃。

7z确实相当复杂。文件格式本身就不简单,而且它还支持相当多的压缩方式。

幸运的是,这个bug只牵扯到了文件格式的一部分以及所谓的PPMd编码。PPMd是一个最初由Dmitry Shkarin开发的压缩算法。它通过部分匹配来使用预测,并将其与范围编码相结合。

实质上,部分匹配预测是建立一个试图给定n个前导符号预测下一个符号的模型。context存储了包含由n个最新符号组成的序列,常量n被称作模型的

我希望这些基础信息足以理解接下来的内容。如果你想阅读更多的关于PPM的信息,我强烈建议你去读读Cleary和Witten的论文。或者Mark Nelson的博客文章也是不错的选择。

如果没有调试符号,那么调试发生在7z代码中的反病毒软件会是一场噩梦!!

可能的补救措施是参考一下参考实现,并尝试来匹配函数名称。尽管BitDefender似乎重用了7-Zip的代码,但这也不是一件简单的事,因为编译器已经应用了大量的内联甚至函数内部优化。

一旦匹配了最重要的7-Zip函数,我们就可以在WinDbg中仔细来单步,并且轻松的观察到CreateSuccessors函数中栈分配ps时的缓冲区溢出。

在最新的7-Zip版本中,这个函数(上半部分)看起来是这样的:

我们看到当前正在遍历context(一个链表),并且填充ps缓冲区。

令人惊讶的是,这里没有任何限制的检查。因此,如果这是原始7-Zip实现中的代码,这正确吗?

回想一下,模型的是指该context种能够存储的符号的个数。如果该context总是被正确的更新,它不应该包含比模型的阶更多的元素。

那么如何确保正确的更新呢?不管实际的机制如何,一定要知道模型的阶数。变量PPMD7_MAX_ORDER已经暗示了64是最大的阶。然而实际的阶数可能有所不同。7-Zip的源代码展示了我们正在寻找的内容:

(注意:该代码不是Bitdefender引擎中的代码)

可以看到,阶是从props数组中读取的。事实证明,props直接从输入文件中获取的。更进一步,这是7z文件格式Folder结构中包含的Properties数组。

此外,我们还看到了参考实现确保了阶不会大于PPMD7_MAX_ORDER

我的使其崩溃的输入文件中的阶是0x5D,并且Bitdefender的7z模块无论如何都可以解压缩。所以他们忽略了这个检查。于是导致了栈缓冲区溢出。

攻击者可以完全控制阶的值,最大值是255。这允许攻击者插入最多255个指针到缓冲区中,产生191个溢出。这些指针指向下边这个类型的CPpmd_State结构(在Ppmd.h中定义)。

注意:所有的结构体成员都是由攻击者控制的。

Bitdefender使用了statck canary(请问这是什么意思?),同时也使用了ASLR和DEP。

有趣的是,他们似乎并没有在系统的大部分地方使用SafeSEH。这样做的原因是Bitdefender的核心动态的从专有二进制插件文件格式(非Windows DLL)中加载大部分模块(比如7z模块)。更具体的说,引擎包含了一个用来分配内存的加载器,从文件系统中读取插件文件,将其解密和解压缩,最终进行代码重定位。因此,Bitdefender没有使用Windows PE映像加载器来执行大部分的代码,这样就非常难以应用完整的SafeSEH保护机制了。似乎Bitdefender通过避免在插件的代码使用异常处理来解决这个限制。

引擎是在没有沙箱保护的情况下以NT Authority\SYSTEM用户运行的。此外,由于软件在文件系统中使用了minifilter,因此可以轻松的远程触发漏洞完成利用,例如通过发送带有精心设计的文件作为邮件的附件发送给受害者。

还要注意,Bitdefender的引擎许可许多不同的反病毒供应商,如F-Secure或G Data,所有这些都可能受到这个bug的影响。

Bitdefender 决定通过确保CreateSuccessors中一旦numPs(ps缓冲区的索引)达到了PPMD7_MAX_ORDER就抛出异常的方式来修复该bug。代码中仍然接受大于PPMD7_MAX_ORDER的值的阶数,但是,当解压过程中numPs==PPMD7_MAX_ORDER时就会中断解压缩过程。

选择这种设计是反病毒行业中常见的做法。这些人都喜欢以轻松的方式分析和处理文件。特别的,他们倾向于接受各种(部分)无效文件。

原因在于,消费者软件处理流行的文件格式(例如rar,zip或者7z)有许多不同的变体。放松文件解析和处理的目的是尽可能多的覆盖各种实现,并避免消费者软件可以成功处理而反病毒产品将文件解析为无效的这种场景。

这种观念来对待无效文件时,对PPMd阶的检查压根就被忽略了。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//