Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2014-1773 — CVE-2014-1773 的技术分析,该漏洞是 Internet Explorer 的 MSHTML 引擎中的堆损坏漏洞,包含详细的崩溃调用堆栈、反汇编以及用于漏洞利用的堆操作技术。 | Kitploit
工具/GitHubGitHub/day6reak/cve-2014-1773
内存取证漏洞分析漏洞利用逆向工程调试器二进制利用
GitHubday6reak/cve-2014-1773

CVE-2014-1773

CVE-2014-1773 的技术分析,该漏洞是 Internet Explorer 的 MSHTML 引擎中的堆损坏漏洞,包含详细的崩溃调用堆栈、反汇编以及用于漏洞利用的堆操作技术。

查看仓库
611年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CClipStack::PushClipRect():无效的数组索引

首先,在启用了页面堆的情况下,从崩溃时的调用栈开始:

ChildEBP RetAddr 0919aac8 6b58459f MSHTML!CWorldTransform::IsAxisAligned 0919ab40 6ba228e9 MSHTML!CDispSurface::CClipStack::PushClipRect+0x1a2 0919aba4 6be25b58 MSHTML!CDispSurface::PushClipRectInternal+0x2f 0919abc0 6bf1118f MSHTML!CDispSurface::PushClipRectUser+0x26 0919ac24 6bf1157e MSHTML!CCanvasCompositor::ClearRightAndBelowRenderedRegion+0xcd 0919acd8 6b28108c MSHTML!CCanvasCompositor::ExecuteCompositionEffects+0x34d 0919ace0 6b2802f4 MSHTML!CCanvasCompositor::Flush+0x3d 0919ace8 6bf0c867 MSHTML!CCanvasCompositor::~CCanvasCompositor+0x10 0919ae28 6bf0b668 MSHTML!CCanvasRenderingContext2D::StrokeRectInternal+0x1b3 0919ae70 6bf0e032 MSHTML!CCanvasRenderingContext2D::ExecuteStrokeRect+0x1c5 0919aebc 6bd74b6f MSHTML!CCanvasRenderingContext2D::Var_strokeRect+0xac 0919aee0 6ae7056e MSHTML!CFastDOM::CCanvasRenderingContext2D::Trampoline_strokeRect+0x3b 0919af50 6ae6cdda jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x165 0919b328 6ae6dc86 jscript9!Js::InterpreterStackFrame::Process+0x1e74 0919b474 09560fd9 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x1e7

如果往回调一个函数,这个家伙设置了导致崩溃的对象指针:

.text:63CDE575 ; public: long __thiscall CDispSurface::CClipStack::PushClipRect(class CRectF const &, class CWorldTransform const *, bool, bool) .text:63CDE575 mov edi, edi .text:63CDE577 push ebp .text:63CDE578 mov ebp, esp .text:63CDE57A sub esp, 64h .text:63CDE57D and [ebp+var_8], 0 .text:63CDE581 mov edx, ecx .text:63CDE583 push ebx .text:63CDE584 push esi .text:63CDE585 mov esi, [ebp+arg_0] .text:63CDE588 push edi .text:63CDE589 lea edi, [ebp+var_28] .text:63CDE58C mov [ebp+var_4], edx .text:63CDE58F movsd .text:63CDE590 movsd .text:63CDE591 movsd .text:63CDE592 movsd .text:63CDE593 mov esi, [ebp+arg_4] .text:63CDE596 test esi, esi .text:63CDE598 jnz loc_63B1A8DF .text:63CDE59E .text:63CDE59E loc_63CDE59E: .text:63CDE59E imul ecx, [edx+4], 18h .text:63CDE5A2 xor bl, bl .text:63CDE5A4 mov eax, [edx+8] .text:63CDE5A7 add eax, 0FFFFFFE8h .text:63CDE5AA add eax, ecx .text:63CDE5AC mov [ebp+arg_0], eax .text:63CDE5AF mov edi, [eax+14h]

外层对象 CDispSurface 内部包含一个 CClipStack 对象。CClipStack 对象从 CDispSurface 对象偏移 0x64 处开始。CClipStack 基本上只是 CImplAry 的一个子类,而 CImplAry 是 Internet Explorer 中到处使用的通用数组类。在上述函数 CDispSurface::CClipStack::PushClipRect 中,'this' 指针是外层 CDispSurface 内部的子对象 CClipStack。

CClipStack 对象看起来像这样:

DWORD dwMaxElems; DWORD dwCurElems; VOID *pElems;

所以,看上面的代码,你可以猜到发生了什么。上述代码的作用是从 CClipStack 数组中提取最后一个元素。数组中每个元素的大小是 0x18 字节,因此:

imul ecx, [edx+4], 18h ; dwCurElems * 0x18 mov eax, [edx+8] ;pElems

但是接下来你可以看到:

add eax, 0FFFFFFE8h ; 从 pElems 中减去 0x18 add eax, ecx ; pElems += (dwCurElems * 0x18)

然而,如果数组为空,dwCurElems * 0x18 等于 0,那么 pElems 实际上会指向数组开始之前的位置,进入其下面的相邻堆块。数组本身包含的类型是 CWorldTransform,从崩溃代码中从数组中提取对象后不久即可推断出这一点。ecx 是从 'mov edi, [eax+14h]' 操作中获取的对象指针:

.text:63B1A940 ; public: bool __thiscall CWorldTransform::IsAxisAligned(void)const

.text:63B1A940 test dword ptr [ecx+8], 80000000h ;ecx == BAD

那么,这个数组是在哪里分配的:

MSHTML!CDispSurface::CClipStack::PushClipRect+0x32: 6b97e5a7 83c0e8 add eax,0FFFFFFE8h 0:013> !heap -p -a eax address 0c4b0fa0 found in _DPH_HEAP_ROOT @ 211000 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize) c45123c: c4b0fa0 60 - c4b0000 2000 739f8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229 77a95e7a ntdll!RtlDebugAllocateHeap+0x00000030 77a5a3ba ntdll!RtlpAllocateHeap+0x000000c4 77a25a70 ntdll!RtlAllocateHeap+0x0000023a 6b55c592 MSHTML!CImplAry::EnsureSizeWorker+0x00000061 6b584513 MSHTML!CDispSurface::BeginDraw+0x00000122 6b2847a0 MSHTML!CCanvasRenderingContext2D::BeginDraw+0x00000041 6b286155 MSHTML!CCanvasContextBase::OpenBitmapRenderTarget+0x00000014 6b283b77 MSHTML!CCanvasCompositor::Initialize+0x0000102f 6b285cf7 MSHTML!CCanvasRenderingContext2D::StrokeGeometry+0x00000131 6b285090 MSHTML!CCanvasRenderingContext2D::ExecuteStroke+0x000002c4 6b284dae MSHTML!CFastDOM::CCanvasRenderingContext2D::Trampoline_stroke+0x00000035 6ae7056e jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x00000165 6ae6cdda jscript9!Js::InterpreterStackFrame::Process+0x00001e74 6ae6dc86 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x000001e7

它位于 0x60 LFH 箱中。我们可以通过一些堆构造来控制数组后面的块。但上面代码中用于提取所用对象的计算是:

(BYTE *)pArrayStart - 0x18 + 0x14 => (BYTE *)pArrayStart - 0x4

这导致将 LFH 块头的 flags/index 字段用作对象指针。这并不太好,因为该字段中的字节不太可控(我认为)。

关于如何可能控制 LFH 头部的第二个双字,请参见:

http://illmatics.com/Understanding_the_LFH.pdf

与 Sean Larsson 合作

下载工具