Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2014-1773 — Internet Explorer의 MSHTML 엔진에 있는 힙 손상 취약점인 CVE-2014-1773에 대한 기술 분석으로, 상세한 크래시 콜스택, 디스어셈블리 및 익스플로잇을 위한 힙 조작 기술을 포함합니다. | Kitploit
도구/GitHubGitHub/day6reak/cve-2014-1773
Memory ForensicsVulnerability AnalysisExploitationReverse EngineeringDebuggersBinary Exploitation
GitHubday6reak/cve-2014-1773

CVE-2014-1773

Internet Explorer의 MSHTML 엔진에 있는 힙 손상 취약점인 CVE-2014-1773에 대한 기술 분석으로, 상세한 크래시 콜스택, 디스어셈블리 및 익스플로잇을 위한 힙 조작 기술을 포함합니다.

저장소 보기
611년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CClipStack::PushClipRect() 잘못된 배열 인덱싱

먼저, pageheap이 활성화된 상태에서 발생한 크래시의 콜스택부터 살펴보겠습니다:

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 ; subtract 0x18 from pElems 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 bin에 있습니다. 힙 크래프팅(heap crafting)을 통해 배열 뒤(아래)의 청크를 제어할 수 있습니다. 하지만 위 코드의 나쁜 점은 객체 추출에 사용되는 계산이 다음과 같다는 것입니다:

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

그 결과 LFH 청크 헤더의 flags/index 필드가 객체 포인터로 사용됩니다. 그 필드의 바이트는 (제 생각에) 그다지 제어하기 쉽지 않기 때문에 그리 좋지 않습니다.

LFH 헤더의 두 번째 dword를 제어할 수 있는 방법을 보려면:

http://illmatics.com/Understanding_the_LFH.pdf

Sean Larsson과의 협업

도구 다운로드