在调试漏洞的过程中,个人感觉最棘手的就是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. centos7的防火墙配置

    centos7 不在使用iptables作为防火墙, 而是使用firewalld规则, 好吃是支持动态更新, 不需要重启服务, 第二个就是加入了zone概念. 所以和centos6在防火墙配置上有很大 ...

  2. java编程常用的快捷键

    Eclipse 常用快捷键 Eclipse的编辑功能非常强大,掌握了Eclipse快捷键功能,能够大大提高开发效率.Eclipse中有如下一些和编辑相关的快捷键. 1. [ALT+/] 此快捷键为用户 ...

  3. 动态创建table表格页面出现undefined原因以及修改

    源代码: var html: if(lists) { html += '<a href="https://www.4001149114.com/NLJJ/member/sharecel ...

  4. Golang panic用法

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  5. Qt 绘图与动画系统

    Qt 提供了内置的绘图系统以及独立的QtOpenGL模块提供对OpenGL的支持.Qt提供了基于状态机的QPainter系统和面向对象的Graphics View系统. QPainter 基于状态机的 ...

  6. Java异常(一)Java异常简介及其框架

    Java异常(一)Java异常简介及其框架 概要 本章对Java中的异常进行介绍.内容包括:Java异常简介Java异常框架 Java异常简介 Java异常是Java提供的一种识别及响应错误的一致性机 ...

  7. Javascript实现图片翻转

    使用Js的对象属性能实现简单的翻转效果.通过onMouseover事件和onMouseOut事件就能实现鼠标移到链接上和移开链接发生反应.给两个图片加上链接实现都能翻转的效果. reverse.htm ...

  8. .NET中的异步编程

    开篇 异步编程是程序设计的重点也是难点,还记得在刚开始接触.net的时候,看的是一本c#的Winform实例教程,上面大部分都是教我们如何使用Winform的控件以及操作数据库的实例,那时候做的基本都 ...

  9. js返回一组日期中最近连续的天数

    用js获取一组日期(并把当天算入)中连续的天数 刚开始可能想到单纯的比较日期大小判断连续, 而又有大小月,平闰年这些因素,还是时间戳来的安全; 首先得有一组日期,比如: var arr = [ '20 ...

  10. Vue 框架-08-基础实战 demo

    Vue 框架-08-基础实战 demo 前面介绍了有 7 篇了,都是小实例,没有相对完整的应用,虽然有些功能挺实用,但还是有的不常用的,今天记录一篇关于前几篇基础内容的实战 demo,也是对 Vue ...