漏洞英文_IE 11浏览器0day漏洞(CVE-2015-2425)UAF分析_入门渗透入门教程

漏洞英文_IE 11浏览器0day漏洞(CVE-2015-2425)UAF分析_入门渗透入门教程

前言

CVE-2015-2425是 team泄露出来的一个IE11的0day漏洞,影响了IE11及之前的版本。在一封 Team高层收到的来自 安全公司的信件中被发现。 公司的研究者在信中向 Team提供了对于 7/8.1最新版的IE11的poc代码。但 Team并没有购买,所以只泄露了poc,并没有攻击代码。

环境

测试环境是win8.132位,IE版本是IE11。

poc

poc.html:

漏洞英文_uaf漏洞_漏洞英文bug

把IE11附加到上,然后运行poc.html,IE11崩溃到一个无法读取的地址:

漏洞英文bug_漏洞英文_uaf漏洞

+IDA分析

由于崩溃在一个不可访问的地址,不好确定之前的指令,这时需要用到与栈回溯相关的命令,就是中的k一系列命令:

漏洞英文bug_uaf漏洞_漏洞英文

每一行描述当前的一个栈帧,最上面的一行描述的是当前指令的返回地址:

漏洞英文_uaf漏洞_漏洞英文bug

由此可知崩溃的返回地址是,在::中,看当前的esp也可以得出同样的结论:

uaf漏洞_漏洞英文_漏洞英文bug

为了看到函数是怎么调用的,需要用到.frame命令,使用.frame /c 1回到崩溃栈的第一层,也就是上层函数调用时的状态:

漏洞英文_uaf漏洞_漏洞英文bug

看到回到了上层函数中,eip的值为崩溃处的返回地址,在反汇编窗口可以看到上层函数,也可以用u命令:

uaf漏洞_漏洞英文bug_漏洞英文

产生崩溃的地方是的call函数,调用的是[ebp-1Ch]处的函数指针,在IDA中看一下的定义:

漏洞英文bug_uaf漏洞_漏洞英文

这个函数是方式调用的,是一种快速调用方式,规定将前两个参数由寄存器ecx和edx来传递,其余参数还是通过堆栈传递(从右到左),不同编译器编译的程序规定的寄存器不同。在Intel 386平台上,使用ECX和EDX寄存器。

往前找更改ebp-1Ch内容的指令,只有处的mov指令:

漏洞英文bug_uaf漏洞_漏洞英文

edx是函数的第二个参数,也就是一个函数指针,所以处的指令是调用了函数指针所指向的函数,这样的话,还需要向上层看,到底是什么样的函数指针,回到上一层函数:

漏洞英文_uaf漏洞_漏洞英文bug

看到edx来源是[eax+0Ch],而eax的来源是[ebx+4],ebx来源于下面一句:

看一下这个函数的定义:

为了解决类成员调用中this指针传递而规定的,要求把this指针放在特定寄存器中,该寄存器由编译器决定。VC使用ecx。所以这里ecx里的指针就是this指针。梳理一下这里的过程:

漏洞英文bug_漏洞英文_uaf漏洞

推测这里调用了某个对象的成员函数,而这个对象是对象。

弄清楚后我们回到崩溃点所在的函数内,选择在call [ebp-1Ch]处下断点,断点会多次触发,触发5次后,停下,步入函数看:

漏洞英文_漏洞英文bug_uaf漏洞

在处的call后,eax就会变成一段已经释放内存的地址,看到这句的jmp指令跳到了eax指向的值,把这段函数汇编看一下:

漏洞英文bug_uaf漏洞_漏洞英文

eax里存放的应该是::的返回值,这次在这个函数上下断点再次调试,会触发六次断点,在返回前调用了::将eax置为了不可访问的地址:

漏洞英文bug_漏洞英文_uaf漏洞

看看::,这次还在调用::上下断点,六次断点后进入,发现里面还有一个call改变了eax的值,然后还有mov eax,edi:

漏洞英文_uaf漏洞_漏洞英文bug

再次用相同的方式调试,这次进入::t看看,这个函数如下:

漏洞英文bug_漏洞英文_uaf漏洞

的mov语句改变了eax:

uaf漏洞_漏洞英文_漏洞英文bug

这个函数返回后有一个mov eax,esi的指令,但这里edi值也已经是返回后eax的值了,看来还要追踪edi,看一下函数:

uaf漏洞_漏洞英文bug_漏洞英文

edi是作为参数传入t的,并且在函数内没有被改变,那么还要往回追踪,经过回溯,从函数开头开始跟,由于中间还有跳转,所以edi的值还会改变,跟到edi变成崩溃时的返回地址时可以得出:

漏洞英文_漏洞英文bug_uaf漏洞

那么还需要跟踪一下esi,可以看到来自eax,而eax来自ecx:

uaf漏洞_漏洞英文_漏洞英文bug

所以ecx中是的第一个参数:

uaf漏洞_漏洞英文bug_漏洞英文

是对象,说明在最后一次调用前这个对象就已经被释放了,用poi看看指针引用的过程,通过三次引用找到了那块已经释放的内存:

漏洞英文bug_uaf漏洞_漏洞英文

重启后在第五次断在时,ebx指向了对象,这时看一下触发漏洞的指针,然后在第六次时看一下指针:

漏洞英文bug_漏洞英文_uaf漏洞

两次指针并不相同,说明指针被改写了一次,重新运行一样在第五次断点被触发时看一下这里的内存,此时还没有被改写:

漏洞英文bug_uaf漏洞_漏洞英文

在这里可以下一个内存写入断点,看看什么时候被改写了:

uaf漏洞_漏洞英文bug_漏洞英文

真正的写入发生在上一句mov语句,这时的esi为,eax为:

uaf漏洞_漏洞英文_漏洞英文bug

而eax里的是上一个call的返回值,也就是ter::的返回值,这次在下断点,会触发五次,最后一次时步入函数:

漏洞英文bug_uaf漏洞_漏洞英文

由于这个函数是,所以ecx就是this指针,就是把类的一个成员赋给了eax。

为IE开启堆页,命令是:

漏洞英文_漏洞英文bug_uaf漏洞

再次下断点调试,看看这里堆的情况:

漏洞英文bug_漏洞英文_uaf漏洞

这时eax指向的内容还没有被释放,是一段函数代码:

漏洞英文_uaf漏洞_漏洞英文bug

那我们要找到这段内存是如何释放的,还是回到断点处,这次不进入函数,步过后那段内存并没有被释放,为了弄清楚在哪里被释放,给this指针和那段uaf的内存下访问断点:

uaf漏洞_漏洞英文bug_漏洞英文

断点触发时,还没有被释放,函数返回时已经被释放了,内存就是用来释放,在类中还有函数,应该是分配内存的函数。

总结

所以漏洞的成因应该是在内存被释放后又在::中使用而造成的UAF。由于这个漏洞的返回地址不可控,所以要用堆喷的方法的话可能还需要结合其他方法来绕过DEP和ASLR。

~

网络安全学习,我们一起交流

~

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值