IE 11浏览器0day漏洞(CVE-2015-2425)UAF分析

前言

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

环境

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

poc

poc.html:

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

windbg+IDA分析

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

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

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

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

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

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

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

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

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

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

看一下这个函数的定义:

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

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

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

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

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

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

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

63e06604mov语句改变了eax:

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

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

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

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

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

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

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

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

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

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

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

为IE开启堆页,命令是:

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

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

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

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

总结

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

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2017-10-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

数据结构之堆和栈

内存分配策略     按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.  静态存储分配是指在编译时就能确定每个数据目标...

2239
来自专栏Google Dart

Dart 服务端开发 shelf_bind 包

shelf_bind倾向于约定优于配置,因此您可以编写必要的最小代码,但仍然可以根据需要覆盖默认值。

932
来自专栏性能与架构

JS this指针的理解

this是javascript的一个关键字,也是比较容易令人迷糊的一个概念 this的本质:当前对象的所有者 示例1 var x = 1; function t...

3697
来自专栏逆向技术

C++反汇编第六讲,认识C++中的Try catch语法,以及在反汇编中还原

      C++反汇编第六讲,认识C++中的Try catch语法,以及在反汇编中还原 我们以前讲SEH异常处理的时候已经说过了,C++中的Try catch...

23310
来自专栏hbbliyong

设计模式名录

本文给出了经典的23种设计模式的名录,包括他们的分类、名称、定义以及简要说明,方便大家能够快速的回忆起他们。也是前面写过的或者后面将要写的设计模式的一个目录。...

2847
来自专栏养码场

再刷一波起来!Java后端开发面经大集锦2.0,刷完顺利拿下Offer!

昨天场主献上Java后端开发面经大集锦1.0,反响特别好!还有程序员“指控”场主:为啥不早点推送??并送上了一个意味深长的微笑

1012
来自专栏Janti

Java基础巩固计划

3.26-4.1 JVM 虚拟机的内容写五篇博客 解决以下问题: 1. Java的内存模型以及GC算法 2. jvm性能调优都做了什么 3. 介绍JVM中7个区...

4497
来自专栏大大的微笑

java 多线程暂停与恢复:suspend,resume

这边做了一个小测试: 实现了runnable接口,在方法中打印count的值: int count =0; @Override public void ...

2195
来自专栏Android中高级开发

Android并发编程 开篇

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索...

912
来自专栏java一日一条

用Java实现一个通用并发对象池

这篇文章里我们主要讨论下如何在Java里实现一个对象池。最近几年,Java虚拟机的性能在各方面都得到了极大的提升,因此对大多数对象而言,已经没有必要通过对象池来...

852

扫码关注云+社区

领取腾讯云代金券