UAF漏洞学习

  产生原因:

  UAF漏洞的成因是一块堆内存被释放了之后又被使用。又被使用指的是:指针存在(悬垂指针被引用)。这个引用的结果是不可预测的,因为不知道会发生什么。由于大多数的堆内存其实都是C++对象,所以利用的核心思路就是分配堆去占坑,占的坑中有自己构造的虚表。

  分析方式:

  触发UAF漏洞需要一系列的操作,而不是像传统的溢出一个操作就会导致溢出。IE浏览器中的DOM标签由一个对象来表示,并且IE自带的类中存在了一些对象管理的方法。分析UAF漏洞的要点在于搞清楚对象是在哪里被分配的,哪里被释放的,哪里被重用的。UAF的异常触发点是很明显的,就是对已释放的对象进行操作导致的异常。所以异常点也就是重用点。而由于是对对象的操作,可以列出这个对象的所有方法,找出分配和释放的方法,对其下断来分析到底是怎么发生的UAF过程。

  首先要说明2个概念:

  1.   悬垂指针:悬垂指针是指一类不指向任何合法的或者有效的(即与指针的含义不符)的对象的指针。比如一个对象的指针,如果这个对象已经被释放或者回收但是

 指针没有进行任何的修改仍然执行已被释放的内存,这个指针就叫做悬垂指针

  2.  UAF漏洞:Use-After-Free是一种内存破坏漏洞,简单的说,漏洞的原因是使用了悬垂指针。

  

 

 

  IE浏览器DOM树的实现原理,这是根本

  常见的与UAF漏洞配合使用的就是堆喷射了,堆喷射的思想就是分配大量内存,增大靶子的面积。使EIP能跳进分配的内存中。而分配的内存中又充满了滑板指令,只要命中了滑板指令就可以命中Shellcode。为了利用UAF漏洞,要理解漏洞触发的时机,涉及的对象等。然后通过Js来精心布局内存并控制EIP的控制权。

  注意的是,对于UAF漏洞来说,调试器捕获的异常往往都不是漏洞发生的第一现场,所以一般都要使用gflags开启PageHeap和UST,命令如下(windbg自带gflags工具)

gflags.exe /i 程序名.exe +hpa +ust

  这样调试器就会定位到最先出错的位置

  此外有如下技巧:

  • 在IDA里查找函数后,在Windbg里下断。如果知道了一个对象的一个方法却不知道怎么断下它,就用IDA加载符号,搜索方法。说不定就能找到对应的C++函数名。
  • 1.打开poc文件后,出现crash就是对象被重用,根据crash地址来找到重用的对象起始地址。
  • 2.对对象起始使用!heap -p -a 地址。就可以获得这个对象的分配信息,由回溯还可以知道是什么函数分配的
  • 3.对分配函数下断来达到分配现场
  • 4.如果!heap -p -a 地址 后得到的是释放的回溯,那么怎么知道分配函数呢?答案是在释放函数上下断,然后断到那里时使用!heap -p -a 地址得到的就是分配的回溯了,计划通。
  • 在回溯中,所谓的分配函数一般就是RtlAllocateHeap的上层。而释放函数一般就是FreeHeap的上层(或者RtlFreeHeap?)

 

一个页面包含CMarkup对象来表示页面的结构或者DOM数。CMarkup对象包含一个指向根CElement对象的指针。CElement对象是很多实体类的父类。在图1Javascript对象e_1e_2是继承自CElementCObjectElement对象。CElement对象存在一个指向CTreeNode对象的指针。CTreeNode对象还存在一个与CElement对象相关的指针。CTreeNode的对象有一对指向CTreePos对象的指针。

那为什么一个CTreePos是必须的?因为IE使用了伸展树算法(Splay Tree)来操控DOM树。在伸展树算法树中CTreePos对象作为一个节点。CMarkupPointer对象代表CMarkup对象中的一个地址。所以CMarkupPointer对象有一个指向CTreePos对象的指针来代表他的地址。CMarkup对象有很多与UAF相关的状态。

嵌入状态:这意味着CMarkupPointer创建了CTreePos对象并加入了伸展树中。

非嵌入状态:这意味着CMarkupPointerCTreePos对象移出伸展树并释放。

下图展示了伸展树的交互过程:

http://p1.qhimg.com/t01ff04b0f36b13b1ee.png

 

 通过

posted @ 2016-03-25 20:26  Ox9A82  阅读(7686)  评论(1编辑  收藏  举报