在调试漏洞的过程中,个人感觉最棘手的就是ie浏览器的漏洞和flash player的漏洞了。这里打算记录一下学习过程中的心得(主要是基于uaf类),以方便新人学习。

首先,ie漏洞与众不同的是,程序的执行流程是由攻击者控制的。poc中的js脚本反应到mshtml中的c++代码决定了程序的执行流程,所以对于ie漏洞来说仔细研究poc非常的关键。此外就是调试ie漏洞需要对ie本身有很强的了解,这也是我写这篇博文的动机,如果完全不清楚ie背后的机制,那么ie漏洞根本没法去调。

调试IE漏洞的关键点:执行流程

CMarkup代表整个HTML树结构

CMarkup::CreateElement——>

mshtml!CreateElement——>

CXXXElement::CreateElement

tips:1.析构函数在windbg里直接用符号是断不下来的,需要找到函数地址,最好是在call free上下断。

元素对象统一继承自CElement。

0x00偏移:虚表(dword),对此处求ln会得到符号

0x08偏移:是引用计数?

0x14偏移:对应的CTreeNode对象的指针

0x24偏移:Tag (byte),0x58script 0x10body 0x2fhead

创建函数:CXXXElement::CreateElement(通用断点:监视类型mshtml!CreateElement [call eax]、监视内存CElement::CElement [堆分配传来的eax])

释放引用函数:CXXXElement::Release(通用断点:CBase::PrivateRelease 栈上arg_1 eax是虚表)

释放函数:CBase::SubRelease(CElement::~CElement)(通用断点CBase::SubRelease的jmp路径 ecx为要释放的对象指针)

DOM对象均为CTreeNode类的实例。

0x00偏移:对应的元素对象的指针(dword)

0x04偏移:指向父节点的CTreeNode(dword)

0x16偏移:指向此node的起始CTreePos

0x20偏移:指向此node的结束CTreePos

0x40偏移:引用计数?

创建函数:CTreeNode::CTreeNode(构造函数)(eax:缓冲区地址 edi:所属对象类型)

释放引用函数:CTreeNode::Release的if分支(通用断点:CTreeNode::Release的if分支 [待释放的edx],在比较处eax引用计数)

释放函数:CTreeNode::Release的另一if分支(通用断点:CTreeNode::Release的另一if分支 [待释放的edx],在比较处eax引用计数)

CTreePos对象是一一对应于CTreeNode对象的,主要是用于构成dom树的结构

0x00偏移:key

0x10偏移:上一个CTreePos对象(dword)

0x14偏移:下一个CTreePos对象(dword)

0x18偏移:引用计数,为0就会被释放(dword)

0x20偏移:对应的CTreeNode(dword)

释放函数:CMarkup::FreeTreePos

通用断点原则

IE中两类重要的对象:元素对象和DOM对象

IE中每一个元素标签都对应一个c++对象,这些类的总基类是CElement

每个元素对象都在DOM树中,但是联入数据结构的是CTreePos对象

IE浏览器使用引用计数来跟踪对象的生命期,引用计数数=指向对象的指针,就是说每当增加一个指针指向它引用计数就加1。

解除引用元素对象的函数都为如下,这个方法的调用执行关系如下(基于IUnknown)

    • CXXXElement::Release ——>
    • CElement::Release——>
    • CElement::PrivateRelease——>
    • CBase::PrivateRelease

如果可以监视所有的IE元素创建、DOM元素创建、IE元素释放、DOM元素释放,那么漏洞出在哪里将一目了然

对于一个元素标签,比如Object标签。那么对应的就是CObjectElement::CreateElement,这个函数的调用关系如下

元素对象创建的完整路径

  • CDocument::createElement——>
  • CDocument::CreateElementHelper——>
  • CMarkup::CreateElement——>
  • mshtml!CreateElement——>
  • CXXXElement::CreateElement——>
  • HeapAlloc+CElement::CElement

CTreeNode::SetElement(CXXXElement*);将DOM对象与元素对象关联起来

CTreeNode表示一个节点,CTreePos表示一个节点的标记。dom树就是由CTreePos表示的二叉树。

如果一个对象的指针计数为0,那么就会被垃圾清理释放掉

CTreeNode类的成员,来自IE5泄露源码

    // Class Data
CElement* _pElement; // The element for this node
CTreeNode* _pNodeParent; // The parent in the CTreeNode tree // DWORD 1
BYTE _etag; // 0-7: element tag
BYTE _fFirstCommonAncestorNode : ; // 8: for finding common ancestor
BYTE _fInMarkup : ; // 9: this node is in a markup and shouldn't die
BYTE _fInMarkupDestruction : ; // 10: Used by CMarkup::DestroySplayTree
BYTE _fHasLookasidePtr : ; // 11-12 Lookaside flags
BYTE _fBlockNess : ; // 13: Cached from format -- valid if _iFF != -1
BYTE _fHasLayout : ; // 14: Cached from format -- valid if _iFF != -1
BYTE _fUnused : ; // 15: Unused SHORT _iPF; // 16-31: Paragraph Format // DWORD 2
SHORT _iCF; // 0-15: Char Format
SHORT _iFF; // 16-31: Fancy Format

CTreeNode::CTreeNode(CTreeNode *pParent,CElement *pElement)这个构造函数的第一个参数是父CTreeNode节点,第二个参数是所属的Element对象。其中第二个参数往往为0。

如何跟踪CTreeNode::CTreeNode对象的创建?

断下CTreeNode::CTreeNode函数后,eax就是分配的内存地址。

第一个参数为父节点CTreeNode对象的地址,第二个参数恒为0

可以在call ~的下一条,mov esi,eax下断,这时CTreeNode已完成初始化,读eax就可知道是属于哪个元素

DOM树是由CTreePos组成的一个splay tree。

如图所示就是一个CxxxElement::CreateElement,上面已经说过了这是由mshtml!CreateElement调用的。我们可以看到调用了HeapAlloc函数后,eax的值没有改变直接传递到了CElement的构造函数——CElement::CElement中。实现了分配空间+初始化内存的操作。

对mshtml!CElement::CElement+0x48下断可以通用的监测对象创建的内容。

这张图是mshtml!CreateElement函数的关键部分,注意符号给出的CTagDesc *类型的常量,这是一个指针数组经过movzx eax,byte ptr [edi+1];shl eax,4;计算偏移得出CxxxElement::CreateElement的地址,然后调用过去。指针数组如下:

CTreeNode::Release可以获取到所有的CTreeNode的释放过程,edx是上面直接传递过来的CTreeNode对象的地址。对这个值监视即可获得所有CTreeNode对象的释放

<html>
<head>
<title>DOM 教程</title>
</head>
<body>
<h1>DOM 第一课</h1>
<p>Hello world!</p>
</body>
</html>
mshtml!CHtmlElement::CreateElement
mshtml!CHeadElement::CreateElement
mshtml!CBodyElement::CreateElement
mshtml!CHeaderElement::CreateElement
mshtml!CParaElement::CreateElement

下断元素创建

:> bl
e 6a23480f () :**** mshtml!CElement::CElement ".echo 对象地址;r eax;gc"
e 6a234be7 () :**** mshtml!CreateElement+0x41 "ln eax;gc"
:> g
(6a23d088) mshtml!CHtmlElement::CreateElement | (6a23d0d8) mshtml!CHtmlElement::`vftable'
Exact matches:
mshtml!CHtmlElement::CreateElement = <no type information>
对象地址
eax=06131fd8
(6a23d359) mshtml!CHeadElement::CreateElement | (6a23d3a8) mshtml!CHeadElement::`vftable'
Exact matches:
mshtml!CHeadElement::CreateElement = <no type information>
对象地址
eax=06154fd8
对象地址
eax=05f6afd0
(6a2465fa) mshtml!CBodyElement::CreateElement | (6a246648) mshtml!CBodyElement::CBodyElement
Exact matches:
mshtml!CBodyElement::CreateElement = <no type information>
对象地址
eax=0302dfd0
(6a254c88) mshtml!CHeaderElement::CreateElement | (6a254ce0) mshtml!CHeaderElement::`vftable'
Exact matches:
mshtml!CHeaderElement::CreateElement = <no type information>
对象地址
eax=0628efd0
(6a257e72) mshtml!CParaElement::CreateElement | (6a257ec0) mshtml!CParaElement::`vftable'
Exact matches:
mshtml!CParaElement::CreateElement = <no type information>
对象地址
eax=05d83fd8

IE漏洞调试的目的:

crash漏洞产生原因

找到发生UAF的对象

找出对象的分配释放重利用的时机

对应到poc的js语句

推断出UAF的本质成因

补丁对比!!!找出本质成因最好的办法

IE漏洞的调试心得的更多相关文章

  1. LPC2478_调试心得(转)

    1.在调试“E:\htwang\smart2200v201\ARM嵌入式系统实验教程(二)\开发板出厂编程程序\液晶显示程序\LCM_Disp”的程序时,想使用外部RAM进行仿真调试,在将ADS1.2 ...

  2. MIPI接口LCD屏调试心得(转)

    源: MIPI接口LCD屏调试心得

  3. VGA调试心得

    以前自己调试过视频信号,无非就时钟加行场同步加数据线,如果视频信号出问题,第一看现象,第二测频率,反正出问题不是消隐信号出问题,就是时钟频率出问题.通过这种方式也调试成功过几个显示屏,然后就以为自己对 ...

  4. js断点调试心得

    虽然网上已经有多的数不清的调试教程了,但仍然没有发现哪篇文章写的通俗易懂,索性自己尝试写写自己的一些使用习惯或者说是心得,希望对那些还不是很懂得使用断点调试的孩子有一些帮助(大神请无视~). 1.断点 ...

  5. React Native调试心得

    在做React Native开发时,少不了的需要对React Native程序进行调试.调试程序是每一位开发者的基本功,高效的调试不仅能提高开发效率,也能降低Bug率.本文将向大家分享React Na ...

  6. Pycharm Debug调试心得

    1.操作步骤: 1-1.添加断点:直接在标记处点击鼠标左键即可.(删除断点只需再点击断点处即可) 1-2.Debug下运行代码 1-3.按照所需调试进行代码调试.Debug的调试方式如下所示: 分别为 ...

  7. VxWorks Fuzzing 之道:VxWorks 工控实时操作系统漏洞挖掘调试与利用揭秘

    转载:freebuf 0×00 前言 关于VxWorks,这里引用44CON议题<攻击 VxWorks:从石器时代到星际>探究 一文章中的介绍: VxWorks 是世界上使用最广泛的一种在 ...

  8. CVE-2013-2551:Internet Explore VML COALineDashStyleArray 整数溢出漏洞简单调试分析

    0x01 2013 Pwn2Own 黑客大赛 在 Pwn2Own 的黑客大赛上,来自法国的 VUPEN 安全团队再一次利用 0day 漏洞攻破 Windows8 环境下的 IE10 浏览器,这一次问题 ...

  9. iOS 调试心得

    修复 bug 占用我们日常开发的大部分时间,熟练的使用调试工具可以给我们节约大部分的时间. LLDB 的常用命令 expression expresion 是一个非常常用的命令,我们可以通过这个命令来 ...

随机推荐

  1. C++中指针和引用、数组之间的区别

    指针指向一块内存,它的内容是所指内存的地址:而引用则是某块内存的别名,引用初始化后不能改变指向.使用时,引用更加安全,指针更加灵活. 初始化.引用必须初始化,且初始化之后不能呢改变:指针可以不必初始化 ...

  2. 转载《浅析MVC框架中View层的优雅设计及实例》

    在基于B/S的应用程序开发中,从基本的技术分工上来说就是两大块,一是软件显示界面,另一个是程序逻辑.在N年前的脚本语言时代,无论是asp.php还是jsp,我们基本是都是把这两者柔和在一起的.尽管我们 ...

  3. 玩转Git之初识Git

    git是什么 Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目 Git 和 svn 有什么区别 它们之间的主要区别是Git是分布式的,而svn是集中式. 当然Git也可 ...

  4. Ionic3 UI组件之 ImageViewer

    组件特性: 轻触图片可全屏查看 手势上下滑动可关闭全屏查看 点击导航箭头可关闭视图 双击查看全图,并可放大 参考地址:https://github.com/Riron/ionic-img-viewer ...

  5. 设计模式学习--面向对象的5条设计原则之Liskov替换原则--LSP

    一.LSP简介(LSP--Liskov Substitution Principle): 定义:如果对于类型S的每一个对象o1,都有一个类型T的对象o2,使对于任意用类型T定义的程序P,将o2替换为o ...

  6. jQuery源码分析-03构造jQuery对象-源码结构和核心函数

    3. 构造jQuery对象 3.1源码结构 先看看总体结构,再做分解: (function( window, undefined ) { var jQuery = (function() { // 构 ...

  7. [转]Log4Net日志插件配置详解

    log4net是一款优秀的第三方日志框架,可以很容易的加载到开发项目中(引用log4net的dll,再配置些基本参数即可),帮助程序员把日志信息输出到各种不同的目标,常见的有文本.数据库.window ...

  8. 面向对象(基础oop)之垃圾回收与静态成员

    大家好,我叫李京阳,,很高兴认识大家,之所以我想开一个自己的博客,就是来把自己所了解的知识点通过自己的话写一下,希望被博客园的朋友们点评和一起讨论一下,也希望从博客园中多认识一些软件开发人员!现在我开 ...

  9. java 数据脱敏

    所谓数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护.在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份 ...

  10. PHP IN_ARRAY 函数 使用需要注意的地方

    今天 看PPChttp://bbs.phpchina.com/thread-171993-1-7.html 这个问题. 其实关键还是因为 php是弱类型语言,php进行比较的时候 最好还是使用stri ...