CVE-2011-0073浅析-firefox释放重引用漏洞
来源:互联网 发布:unity3d webgl 编辑:程序博客网 时间:2024/06/05 17:04
本文转载自对CVE-2011-0073的分析
确保XP SP3上安装了firefox(3.6.16)和windbg(设置好符号表)。用windbg附加firefox,打开POC后程序被断下。
(firefox3.6.16可以在《漏洞战争》的配套资料中找到,原文提供了POC附件)
查看函数调用栈。
可以看到最近的一次函数调用的返回地址是1046659e,使用命令!address 0x1046659e查看这个模块所属的地址。
可见这个地址属于模块xul.dll,用IDA Pro对这个文件进行反汇编之后,跳转到地址1046659e处查看。
显然程序的控制流是在执行call dword ptr [ecx+70h]时转向了地址0x7c34e7ba,从而触发了内存访问异常。根据C++成员函数this指针调用约定,可以推测此处的call指令应该调用的是某个对象的方法。ecx寄存器中保存着虚函数表的基地址,eax寄存器中保存着这个对象的地址。查看ecx和eax可以看到其中的内容都是一些很奇怪的数据。
根据函数的控制流图来看,eax中的的值来源于esi,而后者的值即为函数的参数。
由于异常是在该函数内部执行指令call dword ptr [ecx+70h]时触发的,所以可以用IDA Pro将该函数重命名为FireHere。根据Windbg显示的call stack,上一层函数调用的返回地址为0x10688447,但是跳转到该地址查看,可以发现此处调用的不是FireHere。
当前windbg没有获得正确的call stack信息,所以通过查看当前栈的信息来手动分析。
所有形如0x104XXXXX的地址都可以看作是函数的返回地址。
距离0x1046659e最近的一个函数返回地址为0x104a9484,跳转过去。
根据调用栈中的信息还可以判断,在执行0x104a947f处的call FireHere指令时,压栈的参数eax的值为0x03087060。
在偏移8字节的地方看到了可疑地址0x12001000,那么可以模拟一下在FireHere中发生悲剧的整个过程。
上文已经分析过,程序在调用FireHere时压入的参数即eax的值为0x03087060,它来源于调用函数sub_104a9473时传入的参数。再次回顾栈中的数据,可以确定这个参数是0320c580。查看其偏移0x1c字节的数据。
[0320c580+1c]等于0,但是根据程序的控制流来判断,只有当这个值不为0的话程序才会把这个值压栈并且调用函数FireHere。那么只有一种可能—在sub_104a9473中,[0320c580+1c]的值会被改写。为了判断它在何处被改写,可以下内存访问断点。
在0x106f0e1b处断下,而这个地址在函数sub_106f0df8内,用IDA Pro查看这个函数的控制流图。
可以看到loc_106f0e17对内存数据进行了清零。
函数先以这个值为参数调用FireHere,随后又以其为参数调用sub_10466536。
我在分析的时候发现打开POC网页不会出现异常,异常反而是在关闭POC网页时发生的。所以,猜想这个函数是在网页关闭时才调用的。为了分析清楚程序在执行过程中调用FireHere函数的次数以及调用FireHere和释放内存之间的先后顺序,设置下面的断点。
bp 104665A6 ".echo leave FireHere;gc"bp 1046657E ".echo enter FireHere;gc"bp 1046658D ".echo loc_1046658D hit;gc"bp 1046659E ".echo loc_1046659E hit;gc"bp 106F0E12 ".echo free memory;reax;gc"
从函数FireHere的流程图可以看到,循环执行的次数取决于0x104665a3和0x10466588这两处判断。
可以设置以下断点并打印一些信息。
bp 1046659E ".echo value of 0xBBBBBBBB+8 in the entry of loc_1046659E;dd esi+8 l1;gc"bp 1046657E ".echo value of 0xBBBBBBBB+8 in the entry of FireHere;dd poi(esp+8)+8 l1;gc"
在0xBBBBBBBB内存被释放后,[0xBBBBBBBB+8]被改写为0x12001000,于是程序的控制流会跳转到loc_10466583中,而[0xBBBBBBBB+8 ]+8=0x12001000+8=0x12001008,可以看到0x12001008地址上的值也不为0,于是程序的控制流会继续向下执行,最终触发异常。
Q: 被释放了的内存为什么会被程序引用?
A: 在地址为0xBBBBBBBB这块内存被释放之后, 地址为0xBBBBBBBB+8的内存单元中被写入了攻击者可控的值0x12001000。由于这个值不为0,导致在函数FireHere内部的循环中会再次引用已释放内存单元[0xBBBBBBBB+8]中的数据。
Q: 为什么引用被释放的内存会触发漏洞?
A: 根据程序对内存单元[0xBBBBBBBB+8]以及内存单元[[0xBBBBBBBB+8]]中数据的使用方式来看,内存单元[0xBBBBBBBB+8]中保存的是一个对象指针,内存单元[[0xBBBBBBBB+8]]中保存的是该对象的虚函数表指针。程序误将从[0xBBBBBBBB+8]读取的值0x12001000作为对象指针,并从地址为0x12001000的内存单元上读取了由漏洞利用Javascript代码写入的攻击者可控数据0x12001000作为虚函数表指针,当执行指令call dword ptr[ecx+70h]调用对象的成员函数时就会跳转到内存单元[0x12001000+70h]中保存的攻击者可控的地址0x7c34e7ba上执行任意代码。
这个漏洞的exploit为了绕过ASLR+DEP,使用从firefox加载的用于支持Java的msvcr71.dll中选取指令序列作为ROP Gadgets。由于这个DLL是一个非ASLR模块,所以其指令地址是固定的,0x7c34e7ba就是该DLL中一个作为ROP Gadgets指令序列的起始地址。但是在没有安装Java的机器上firefox不会加载msvcr71.dll,所以在这里会触发内存访问异常。
- CVE-2011-0073浅析-firefox释放重引用漏洞
- CVE-2012-4792浅析-Internet Explorer释放重引用漏洞
- CVE-2015-2545浅析-word释放重引用漏洞
- CVE-2015-2425浅析-Internet Explorer释放重引用漏洞
- CVE-2014-3153浅析-Android内核释放重引用(towelroot)漏洞
- CVE-2013-3346&CVE-2013-5065-Adobe Reader释放重引用漏洞+NDProxy.sys数组越界漏洞联合利用恶意样本分析
- CVE-2011-0065 Firefox mChannel UAF漏洞
- 安全漏洞--释放重引用(UAF)漏洞分析
- CVE-2011-0104浅析-excel栈溢出漏洞
- cve-2011-0027漏洞分析
- CVE-2017-5375&CVE-2017-5400&CVE-2016-9079浅析-firefox中的JIT喷射
- 浅析CVE-2011-3874(zergRush)
- 浅析cve-2011-1823(Gingerbreak)
- 影响所有Nexus手机的漏洞,浅析CVE-2015-1805
- CVE-2017-7269浅析-IIS6.0栈溢出漏洞
- CVE-2012-0158浅析-word栈溢出漏洞
- CVE-2010-3333浅析-word栈溢出漏洞
- CVE-2014-4113浅析-Win32k.sys特权提升漏洞
- Java学习路线图
- hdu 1754
- apk反编译
- pyspark调用jupyter notebook
- Android性能优化典范(一)
- CVE-2011-0073浅析-firefox释放重引用漏洞
- Vue.js开发环境搭建-新建项目
- HTTP 报文介绍
- 在C#客户端用HTTP上传文件到Java服务器
- PHP的线程安全与非线程安全版本的区别
- POJ-----2549---Sumsets---二分
- getline()和get()
- Python 中的基本文件操作
- Linux环境下Weblogic部署应用的一些问题