对于软件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.参考
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命令
bu
在libadpcm_plugin.dll
模块上下断点。
在尝试利用方法(3)进行动态调试时报错如下图所示——
查阅资料发现这种情况需要在内核层面进行调试(WinDbg双机调试/使用内核级调试工具SoftIce),由于时间问题,暂时不考虑动态调试,先结合参考教程中的动态调试部分静态分析一下漏洞成因(但由于漏洞点都不一样,所以也没怎么参考)。
由上述可知,漏洞点位于插件libadpcm_plugin.dll
中的sub_714C18B0
函数中。但是并不是位于我们之前调试得到的下述代码处,因为分析发现在利用ecx定位数组中的具体值时,是限制了其上限为6的,并没有超出数组的界限。
后来不死心,又重新尝试动态调试,结果最6的是,在不同环境的windows虚拟机上(xp、win7)运行,崩溃时windbg给出的崩溃信息都不一样(在某一次调试过程中,最后触发的漏洞居然覆盖了eip,但并没有复现成功)(不知道是不是我虚拟机所在盘的内存不足导致的。。。)。。。也不能一直都耗在这里,先暂时放弃,后面有时间有思路就再看看。
B.参考分析
接下来学习一下参考教程中的分析——关键的知识点总结如下:
(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双机调试”设置