Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【漏洞分析】7z的LZMA压缩算法与Bitdefender的堆缓冲区溢出漏洞

$
0
0
【漏洞分析】7z的LZMA压缩算法与Bitdefender的堆缓冲区溢出漏洞

2017-08-24 11:13:02

阅读:582次
点赞(0)
收藏
来源: landave.io





【漏洞分析】7z的LZMA压缩算法与Bitdefender的堆缓冲区溢出漏洞

作者:WisFree





【漏洞分析】7z的LZMA压缩算法与Bitdefender的堆缓冲区溢出漏洞

译者:WisFree

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


写在前面的话

前段时间,我们曾发表过一篇关于利用7z的PPMD压缩算法触发Bitdefender栈缓冲区溢出的技术文章【参考文章】。而就在该文章发表的几天之后,我又在Bitdefender的产品中发现了一个新的安全漏洞。虽然这同样是一个7z漏洞,但是这个漏洞与之前所发现的那个漏洞以及PPMD编码解码器都没有任何的关系。实际上,这个漏洞涉及到了动态内存管理方面的问题。需要注意的是,在此之前我们也发表过一篇文章来描述F-Secure反病毒产品中的一个任意释放漏洞【参考文章】,但是今天的这篇文章是本系列中第一篇介绍堆缓冲区溢出漏洞的文章。


漏洞介绍

此前,为了写好那篇关于7z PPMD压缩算法漏洞的文章,我阅读了大量的7-Zip源代码,然后从中发现了很多非常有价值的信息(这些信息可以更好地帮助我分析反病毒产品中的漏洞)。因此,我准备利用我手中所掌握的这些信息来分析一下Bitdefender的7z模块。

我之前曾写过一篇关于简化文件处理过程的文章,而Bitdefender 7z PPMD压缩算法的栈缓冲区溢出漏洞也是一个通过移除检测机制(实际上是移除了负责进行检测的相关源码)来简化文件处理流程的绝佳例子。

除此之外,这个漏洞也证明了有的时候向已存在的代码中添加新的代码是有多么的困难。但是一般来说,代码的修改永远都是不可避免的,哪怕是只修改其中的一小部分那也是需要考虑非常多因素的,如果考虑不周全的话,则很有可能会影响程序的内存分配以及文件访问的管理。而本文所要介绍的漏洞就是一个很好的例子,因为程序不正当地使用了内存分配函数并进一步导致Bitdefender的7z模块(7-Zip源代码)引起堆缓冲区溢出。


漏洞细节分析

当Bitdefender的7z模块在一份7z压缩文档中发现了一个EncodedHeader时,它会尝试使用LZMA解码器进行解压。该模块的代码似乎是基于7-Zip的源码进行开发的,但是Bitdefender的开发人员对代码进行了一些修改。

注:EncodedHeader的作用是在一份压缩文档中包含超过一个文件时对多个header进行压缩。关于7z文件格式的更多内容可以从7-Zip源码包中的DOC/7zFormat.txt中获取【传送门】。

简单来说,提取7z EncodedHeader的实现过程大致如下:

1.从7z EncodedHeader中读取unpackSize;

2.分配unpackSize字节数据;

3.使用7-Zip自带的LZMA解码器的C API来解码流数据;

下面给出的代码段显示了分配函数的调用过程:

1DD02A845FAlearcx,[rdi+128h]//<--------result 1DD02A84601movrbx,[rdi+168h] 1DD02A84608mov[rsp+128h],rsi 1DD02A84610movrsi,[rax+10h] 1DD02A84614mov[rsp+0E0h],r15 1DD02A8461Cmovedx,[rsi]//<--------size 1DD02A8461EcallSZ_AllocBuffer

大家可以先回忆一下x64架构的函数调用惯例。实际上在这个代码段中,前两个整形参数是通过rcx和rdx传递的。

SZ_AllocBuffer是Bitdefender的7z模块中的一个函数,这个函数可以接受两个参数:

第一个参数result是一个指针,这个指针指向的是保存结果的内存地址。

第二个参数size则是待分配的内存空间大小。

接下来,让我们一起看一看该函数的代码实现:

260ED3025D0SZ_AllocBufferprocnear 260ED3025D0 260ED3025D0mov[rsp+8],rbx 260ED3025D5pushrdi 260ED3025D6subrsp,20h 260ED3025DAmovrbx,rcx 260ED3025DDmovedi,edx//<--------ediholdssize 260ED3025DFmovrcx,[rcx] 260ED3025E2testrcx,rcx 260ED3025E5jzshortloc_260ED3025EC 260ED3025E7callnearptrirrelevant_function 260ED3025EC 260ED3025ECloc_260ED3025EC: 260ED3025ECcmpedi,0FFFFFFFFh//<-------{*} 260ED3025EFjbeshortloc_260ED302606 260ED3025F1xorecx,ecx 260ED3025F3mov[rbx],rcx 260ED3025F6moveax,ecx 260ED3025F8mov[rbx+8],ecx 260ED3025FBmovrbx,[rsp+30h] 260ED302600addrsp,20h 260ED302604poprdi 260ED302605retn 260ED302606;------------------------------------ 260ED302606 260ED302606loc_260ED302606: 260ED302606movrcx,rdi//<------setsizeargumentformymalloc 260ED302609callmymalloc //[restofthefunctionomitted]

请注意其中的mymalloc函数,这是一个封装函数,它最终会调用malloc并返回处理结果。很明显,开发人员希望SZ_ALLocBuffer函数的size参数大小至少要32位以上,而这就是一个32位的值。

细心的同学可能已经发现了,编译器并没有成功地对上述代码中{*}所标注的地方(负责进行参数比较)进行优化。考虑到这里的比较结果还需要进行无符号比较(jbe),这就非常有意思了。

在SZ_AllocBuffer返回了处理结果之后,函数LzmaDecode将会被调用:

LzmaDecode(Byte*dest,SizeT*destLen,constByte*src,SizeT*srcLen,/*furtherargumentsomitted*/)

需要注意的是,dest是SZ_AllocBuffer函数分配的一个缓冲区,而destLen应该是一个指向缓冲区大小的指针。

在引用实现中,SizeT被定义成了size_t。有趣的是,Bitdefender的7z模块同时使用了32位和64位版本的SizeT,而这两个版本都存在安全漏洞。我怀疑Bitdefender的开发人员这样做的目的是为了给32位和64位引擎提供不同的功能行为而设计的。

接下来,LZMA解码器会提取出参数中给定的src流数据,然后将*destLen字节数据写入到dest缓冲区中,其中的*destLen是7z EncodedHeader中的一个64位unpackSize,而最终的结果就是一个堆缓冲区溢出漏洞。


触发漏洞

为了触发这个漏洞,我们所创建的7z LZMA流数据中包含了我们需要写入堆内存中的数据。接下来,我们构建了一个7z EncodedHeader(unpackSize大小为(1<<32) + 1),这样应该可以让函数SZ_AllocBuffer分配一个大小为一个字节的缓冲区空间了。

这听起来貌似非常的不错,但是这真的会有用吗?

0:000>g!Heapblockat1F091472D40modifiedat1F091472D51pastrequestedsizeof1(2f8.14ec):Breakinstructionexception-code80000003(firstchance)ntdll!RtlpNtMakeTemporaryKey+0x435e:00007ff9`d849c4ceccint30:000>db1F091472D51000001f0`91472d515945532c20544849-5320574f524b53abYES,THISWORKS.

攻击者如何控制并利用该漏洞?

攻击者可以在完全不受任何限制的情况下向堆内存中写入任意数据。一个文件系统的过滤器可以用来扫描所有需要存放在本地磁盘上的文件,而这将导致攻击者能够轻松地远程利用这个漏洞,例如攻击者可以通过向目标用户发送一封包含了特殊附件的恶意邮件来发动攻击。

除此之外,该引擎并不在沙盒环境中运行,而且正常的运行权限为NT Authority\SYSTEM。因此,这个漏洞就是一个影响非常严重的高危漏洞了。但是,由于Bitdefender采用了ASLR和DEP,所以如果攻击者想要成功地利用该漏洞实现远程代码执行的话,则需要其他漏洞(例如信息披露漏洞)的配合来绕过ALSR才可以。

还需要注意的是,很多不同的反病毒厂商都在使用Bitdefender的引擎,因此这个安全漏洞的影响范围将会非常的大。


漏洞修复

数修复后的SZ_AllocBuffer函数代码如下所示:

1E0CEA52AE0SZ_AllocBufferprocnear 1E0CEA52AE0 1E0CEA52AE0mov[rsp+8],rbx 1E0CEA52AE5mov[rsp+10h],rsi 1E0CEA52AEApushrdi 1E0CEA52AEBsubrsp,20h 1E0CEA52AEFmovesi,0FFFFFFFFh 1E0CEA52AF4movrdi,rdx//<-----rdiholdsthesize 1E0CEA52AF7movrbx,rcx 1E0CEA52AFAcmprdx,rsi//<------------{1} 1E0CEA52AFDjbeshortloc_1E0CEA52B11 1E0CEA52AFFxoreax,eax 1E0CEA52B01movrbx,[rsp+30h] 1E0CEA52B06movrsi,[rsp+38h] 1E0CEA52B0Baddrsp,20h 1E0CEA52B0Fpoprdi 1E0CEA52B10retn 1E0CEA52B11;----------------------------------- 1E0CEA52B11 1E0CEA52B11loc_1E0CEA52B11: 1E0CEA52B11movrcx,[rcx] 1E0CEA52B14testrcx,rcx 1E0CEA52B17jzshortloc_1E0CEA52B1E 1E0CEA52B19callnearptrirrelevant_function 1E0CEA52B1E 1E0CEA52B1Eloc_1E0CEA52B1E: 1E0CEA52B1Ecmpedi,esi//<------------{2} 1E0CEA52B20jbeshortloc_1E0CEA52B29 1E0CEA52B22xorecx,ecx 1E0CEA52B24mov[rbx],rcx 1E0CEA52B27jmpshortloc_1E0CEA52B3B 1E0CEA52B29;----------------------------------- 1E0CEA52B29 1E0CEA52B29loc_1E0CEA52B29: 1E0CEA52B29movecx,edi 1E0CEA52B2Bcallnearptrmymalloc //[restofthefunctionomitted]

更重要的是,我们可以看到该函数的第二个参数size已经被改成了64位类型。请注意{1}标注的部分,代码所执行的检测能够确保传递的size值不超过0xFFFFFFFF。

在标注了{2}的部分,rdi的值最大为0xFFFFFFFF,而这已经足够去使用32位寄存器edi了,但是在原始版本的代码中并没有这样的检测功能。

因此,只需要保证第二个参数size使用的是64位版本即可修复这个漏洞。


总结

简单来说,此次发现的这个漏洞是因为64位的size值被传递给了内存分配函数SZ_AllocBuffer所导致的:

void*SZ_AllocBuffer(void*resultptr,uint32_tsize);

如果size值不符合预定义的话,那么编译器应该要抛出如下所示的警告信息:

warningC4244:'argument':conversionfrom'uint64_t'to'uint32_t',possiblelossofdata

不过对于一款反病毒引擎而言,这种漏洞确实影响非常严重。但是这也足以证明,我们只需要向一个成熟的代码库中添加几行外部代码,就有可能导致一个严重的漏洞出现。


漏洞时间轴

2017年7月24日:发现漏洞

2017年7月24日:报告漏洞

2017年7月24日:Bitdefender回复称:“感谢提交漏洞报告,我们会立刻进行调查,并在第一时间给予回复。”

2017年8月22日:漏洞信息已确认,并成功修复了该漏洞。

2017年??月??日:漏洞奖金到手??


致谢

在这里我想感谢Bitdefender(尤其是Marius),感谢他们能够友好并迅速地给我回复,并及时修复了这个漏洞。


参考资料

1.https://landave.io/2017/07/bitdefender-remote-stack-buffer-overflow-via-7z-ppmd/

2.https://landave.io/2017/08/f-secure-anti-virus-arbitrary-free-vulnerability-via-tnef/

3.https://sourceforge.net/projects/sevenzip/files/7-Zip/17.00/7z1700-src.7z/download

4.https://news.ycombinator.com/item?id=15075242

5.https://www.reddit.com/r/netsec/comments/6vajy2/bitdefender_antivirus_heap_buffer_overflow_via_7z/



【漏洞分析】7z的LZMA压缩算法与Bitdefender的堆缓冲区溢出漏洞
【漏洞分析】7z的LZMA压缩算法与Bitdefender的堆缓冲区溢出漏洞
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://landave.io/2017/08/bitdefender-heap-buffer-overflow-via-7z-lzma/#fn:1

Viewing all articles
Browse latest Browse all 12749

Latest Images

Trending Articles





Latest Images