【技术分享】Linux上的0patch代理:微补丁CVE-2016-9445(含演示视频)

发表于:2017-02-10 11:20:33 来源:  安全客 阅读数(0人)



在12月,我们终于得到了Linux代理的工作原型。它已经制作了相当一段时间,现在,它处于alpha阶段,我们终于可以开始0patching Linux的用户空间代码。Linux代理仍然缺乏Windows代理支持的一些功能,但它已经准备好了。


超过65%的Web服务器运行着不同风格的Unix ,修补高可用性的Linux环境安全漏洞应该一直都不是问题。如果我们以Heartbleed漏洞为例,部署官方补丁所需的时间不仅包括供应商发布补丁所需的时间,还包括DevOps测试和部署它所需的时间。我们的目标是使补丁尽可能小,易于查看,甚至更容易部署,从而避免重新启动服务器的需要,从而大大缩短这一时间。


当在Ubuntu上开发和测试Linux代理时,我们已经为Heartbleed创建了一个补丁,虽然还有很多易受攻击的服务器,但是它们能马上能得修复。


这个漏洞在去年十一月发表了Chris的博客中。漏洞位于gstreamer的VMnc解码器,它处理VMware屏幕捕获格式。这是一个非常简单的整数溢出并且Chris提供了PoC。


我创建一个Fedora 25虚拟机,然后尝试使用totem,totem是一个原生于Gnome的视频播放器,它在未修补的Fedora 25上使用gstreamer编程框架。使用totem来播放PoC会导致崩溃。Chris对这个bug进行详细分析。他指出在vmncdec.c文件中的vmnc_handle_wmvi_rectangle方法发生了整数溢出,它是gstreamer-plugins-bad包的一部分。你可以在Gihub上查看其源码gstreamers github。Chris 解释发生溢出的原因是,因为用户提供的rect->width和rect->height会与bytes_per_pixel相乘,最终的结果会作为分配图像数据缓冲区的大小。这两个变量都是带符号的32位整数。如果提供足够高的值,则就会发生整数溢出。随后的内存分配(在下面的图像中标记为红色)会产生比图像数据小的缓冲区,这将导致缓冲区溢出。




我反汇编了libgstvmnc.so ,并定位vmnc_handle_wmvi_rectangle函数,在这个函数里高度和宽度相乘,缓冲器被分配(在下面的图像中标记为红色)。




当有效比特超过了结果的一半时,IMUL指令会设置进位和溢出标志,所以我的第一个想法是,如果这些标志设置,我们可以返回一个错误指令。补丁位置在上图中以绿色标记。这是我补丁的第一个版本,它应用于IMul的原位置上(绿色标记的上述图像上):


正如你所看到的,我们在每一个imul指令后都进行检查,如果进位标志被设置,则返回一个错误。 然而,应用补丁后,totem仍然崩溃。在经过一些调试后,我发现,仅仅在vmnc_handle_wmvi_rectangle函数里返回错误是不够的。因此我看了下方的官方补丁 。




在vmnc_handle_packet函数中可以找到官方补丁 。你可以看到,如果width大于16386或者height大于0x4000,就会返回一个错误。我们的补丁应该和它一样。我反汇编了未修补和已修补的两个版本的 vmnc_handle_packet 函数, 并用Bindiff寻找一个合适的补丁位置。下面的图像代表两个代码的组合视图。绿色代码是由官方补丁添加的。




只有当数据包类型等于TYPE_WMVi 或0x574D5669时, 官方补丁代码才会被执行。在我选择的修补程序位置(红色标记-点击上面的图片可查看大图)的%EDI 寄存器保存数据包类型值,而 %r8w 和%CX 保存着宽度和高度。这是最终生成的补丁:


cmp $0x574d5669,%edi //If the packet type doesn't equal TYPE_WMVi,

jnz _end //continue execution

cmp $0x4000,%r8w //If width is greater than 0x4000,

ja _bad //jump to return error

cmp $0x4000,%cx //If height is smaller than 0x4000,

jbe _end //continue execution, else return error

_bad:

mov $0xffffffff,%eax //Set %eax to -1

add $0x48,%rsp

pop %rbx

pop %rbp

pop %r12

pop %r13

pop %r14

pop %r15

retq //and return

_end:

补丁可以成功地阻止整数溢出和后续的内存分配,使文件可以正常播放,正如官方补丁一样。这里是我们Linux 0patch代理和我们刚刚开发的补丁的短视频。



如你所见,totem在尝试打开PoC时崩溃 。将补丁文件复制到补丁文件夹内并启用补丁后,totem不再崩溃,视频可以正常播放。


开发这个补丁花了大约8小时。这包括反汇编libgstvmnc.so ,尝试了开发了一个错误的补丁,分析了官方补丁并打上正确的补丁。这是一个相对简单的补丁,但我的目的是想展示我们的Linux代理及其功能,这几乎与我们在Windows上正在做的一样。


我们正在不断努力扩展支持的操作系统平台,所以我们有一天可以为需要它的每个人带来0patch


相关新闻

大家都在学

课程详情

逆向工具大全

课程详情

Linux网络服务配置与安全

课程详情

Linux基础