漏洞分析——[CVE-2016-5108]VIDEOLAN VLC MEDIA PLAYER 2.2.1越界写拒绝服务漏洞

对于软件VIDEOLAN VLC MEDIA PLAYER 2.2.1中存在的越界写导致的拒绝服务漏洞的分析。

参考自:https://whereisk0shl.top/post/2019-03-09-01
poc——https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/41025.mov

1.背景知识

之前的一篇漏洞分析中也简单介绍了WinDbg的常用命令,但是并不全面,在这里进行补充。更多的命令介绍可参考官方的命令手册

A.基本调试

命令 作用
g 运行程序
t 单步步入
p 单步步过
g [Address] 执行到指定地址
gu 执行到当前函数的返回地址

B.断点

命令 作用
bp [Address]/[Symbol] 在指定地址下断(可以使用地址或符号,如 bp 80561259(Windbg默认使用16进制) bp MyDriver!GetKernelPath bp MyDriver!GetKernelPath+0x12)
bu [Address]/[Symbol] 下一个需要延迟解析的断点(比如我们的驱动名为MyDriver.sys,那么在驱动加载之前下断bu MyDriver!DriverEntry,然后加载这个驱动时就可以断在驱动入口,并且这个是不需要调试符号支持的)
bl 列出所有断点
bc [id] 清除断点,id是bl查看时的断点编号
bd [id] 禁用断点
be [id] 启动被bd命令禁用的断点
ba Access Size [地址] 针对数据下断点,该断点在指定内存被访问时触发(Access 是访问的方式, 比如 e (执行), r (读/写), w (写);Size 是监控访问的位置的大小,以字节为单位,值为 1、2或4,还可以是 8(64位机)。比如要对内存0x0483DFE进行写操作的时候下断点,可以用命令 ba w4 0x0483DFE)

C.寄存器

命令 作用
r 显示所有寄存器的值
r eax 显示eax寄存器的值
r eax=1 修改eax的值为1

D.内存操作

命令 作用
db/dw/dd/dq [Address] 字节/字/双字/四字方式查看数据
da/du [Address] ASCII字符串/Unicode字符串方式查看指定地址

内存编辑相关常用命令详见下图——

E.栈相关操作

命令 作用
k 显示调用栈
kb 显示ebp和前3个参数
kp 以函数调用形式显示栈

F.参考

Windbg 基本调试入门
Exploit开发系列教程-Windbg

2.漏洞复现

安装运行软件后,打开poc文件,程序闪退。

接下来尝试用windbg附加到应用程序,定位漏洞分析的入手点,但是我的结果和参考链接中的结果就是不一样,如下图,并不能很好的定位到入手点。于是就暂时卡在这里了。

参考链接中的结果——

我的运行结果——

鉴于这是一个cve漏洞,可根据其官方说明如CVE-2016-5108 Detail,看看能否辅助寻找分析入手点。官方说明中漏洞点是位于modules/codec/adpcm.c的,所以可以定位到上图中红框标注处。

3.漏洞分析

A.尝试分析

初步判断漏洞产生于程序所加载的libadpcm_plugin.dll文件中,接下来分析获取其具体产生原因。

还是需要静态分析和动态调试结合起来,但是由于漏洞点位于程序加载的dll文件中,在attach到应用程序后对dll文件中的地址下断点会失败,所以卡在了动态调试上。后来在网上查阅资料,想到以下解决思路(以调试软件Windbg为例):

  • (1)在加载/卸载一个DLL 的时候下断点:加载某个DLL 的时候下断点的WinDBG 命令:sxe ld:[dll name];卸载某个DLL 的时候下断点的WinDBG命令:sxe ud:[dll name]。比如:sxe ld:wininet (在wininet.dll 被装载的时候断点)。
  • (2)静态分析,找到exe中调用要调试的dll的代码,并在对应地址下断点进行调试分析。但比上一种方法麻烦一些。
  • (3)利用WinDbg命令bulibadpcm_plugin.dll模块上下断点。

WinDBG技巧:在加载/卸载一个DLL 的时候下断点

在尝试利用方法(3)进行动态调试时报错如下图所示——

查阅资料发现这种情况需要在内核层面进行调试(WinDbg双机调试/使用内核级调试工具SoftIce),由于时间问题,暂时不考虑动态调试,先结合参考教程中的动态调试部分静态分析一下漏洞成因(但由于漏洞点都不一样,所以也没怎么参考)。

由上述可知,漏洞点位于插件libadpcm_plugin.dll中的sub_714C18B0函数中。但是并不是位于我们之前调试得到的下述代码处,因为分析发现在利用ecx定位数组中的具体值时,是限制了其上限为6的,并没有超出数组的界限。

后来不死心,又重新尝试动态调试,结果最6的是,在不同环境的windows虚拟机上(xp、win7)运行,崩溃时windbg给出的崩溃信息都不一样(在某一次调试过程中,最后触发的漏洞居然覆盖了eip,但并没有复现成功)(不知道是不是我虚拟机所在盘的内存不足导致的。。。)。。。也不能一直都耗在这里,先暂时放弃,后面有时间有思路就再看看。

B.参考分析

https://whereisk0shl.top/post/2019-03-09-01

接下来学习一下参考教程中的分析——关键的知识点总结如下:

(1)如何大概判定越界读写类型漏洞

//1.WinDbg捕获信息如下——
libadpcm_plugin+0x2501:
68322501 66891e          mov     word ptr [esi],bx        ds:0023:0d1fd000=????   //用bx向esi指针写入数据,esi指针的值是一个无效值

//2.此时就可以看看当前esi指针的值前面的值所指的地址是否有值
0:024> dd 0d1fd000-8
0d1fcff8  c0c0178f c0c0c0c0 ???????? ????????

//3.可以看到,前面还有值,故可初步判断这是一个长度控制不严格引发的越界写漏洞

(2)分析关键

静态分析和动态调试都应该重点关注关键数据的流向、关键寄存器/内存地址的值的传递和变化。

(3)漏洞利用

每次拷贝4个字节,经过算法处理后,会在待拷贝区偏移8字节,长度还要乘以2,最后拷贝的长度,超过了申请buffer的长度,造成了越界写,引发了异常。
这个漏洞不能造成任意地址写,因此不能利用,是个拒绝服务漏洞。

C.参考

http://advdbg.org/forums/2261/PrintPost.aspx
在WinDBG中手动设置断点
如何利用 WinDbg 进行双机调试
win10中“windbg+vmware+win7双机调试”设置