今天看啥
热点:

针对网页木马(CVE-2011-1260)的分析与实践(1)


本文假设你对漏洞挖掘,漏洞分析,汇编这些不太了解,但是对C,C++有一定了解。首先我们找一个具体的公开的例子——CVE-2011-1260,释放后重用漏洞。首先我们上网找一下这个漏洞的POC,得到如下运行环境XP SP3,IE8,开启DEP稍后解释什么是DEP)):

  1. <html> 
  2. <body> 
  3. <script language=;javascript;> 
  4. document.body.innerHTML+="<object hspace=;1000;   width=;1000;>TAG_1</object>"; 
  5. document.body.innerHTML+="<a id=;tag_3; style=;bottom:5000px;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px; >TAG_3</a>"; 
  6. document.body.innerHTML += "AAAAAAA"; 
  7. document.body.innerHTML+="<strong style=;font-size:1000pc;margin:auto -25000px auto auto;; dir=;ltr;>TAG_11</strong>"; 
  8. </script> 
  9. </body> 
  10. </html> 

0×1 漏洞分析

我们双击打开,发现IE崩溃了,到底是什么原因呢?
我们用windbg附加进程调试IE最好还是用微软的调试器,毕竟微软主场):附加后,按g,回车,如果限制了activeX控件运行,就按允许,然后windbg在崩溃的时候停止了:

 

从eax+70的地址取出数据,显然这个地址不合法,所以导致错误。我们按knL回车,从栈查看函数的调用情况:

不清楚栈的看这里,清楚的跳过:函数调用有很多种,这里指stdcall,在每一次调用之前,都会将参数压栈,从右到左,比如Void Aint a,int b),汇编就类似push,push,call,Call指令会将call指令的下一条指令的地址压栈,所以最后栈看起来是这样的:注意,压栈是从高往低压)

对应源代码:

 

所以我们从栈中可以看出崩毁之前调用过什么函数,以及现在在什么函数里面,函数返回地址等等很多信息。

这里我们可以看到是在CElement::Doc函数里面崩毁,看看附近的汇编指令:

取ecx地址的内容返回给eax,但是eax是0,导致后来的内存读取错误,显然ecx出了问题。一般情况下,在thiscall中,第一个参数是this指针(用ecx传递),而对象+0x0h的地方储存的是虚函数表的地址,所以可得这里是取虚函数表偏移0×70的地方的虚函数指针,再调用这个虚函数。

显然这里的ecx就是CElement对象,这个对象是IE里面很多元素的父类,如(CObjectElement,对应<object>标签,CImgElement,对应<img>标签等等),而我们从POC中可以看出我们生成了一个<object>标签,所以我们可以推断这个是CObjectElement对象,那么这个对象从哪里来的呢?再看进入这个函数之前的汇编代码:

取ebx地址的内容给ecx,那么ebx哪里来?我们用ida反汇编这个函数看看在mshtml.dll)

Ebx就是this指针,即ebx指向的地方就是CTreeNode,然后CTreeNode对象+0x0h的地方传给ecx(即偏移0x0h保存了对应的CElement指针),再传入CElement::Doc。那么CTreeNode和CElement有什么关系呢?

我们重新运行,然后定如下两个断点:

  1. bu  mshtml!CObjectElement::CreateElement+0x18 ".printf \"[%08x]\\n\",eax;g" 

在mshtml!CObjectElement::CreateElement+0×18出断下,并且打印eax的值,然后继续运行。从文字可以看出这个是构造CObjectElement的函数,里面会调用CObjectElement的构造函数,eax一般是函数返回的值,即这个对象的指针。
 

函数中分配了一个0xDC的堆,显然这是这个对象的大小。

  1. bu  mshtml!CTreeNode::CTreeNode+0x8c ".printf \"allocated CTreeNode at %08x, ref to CElement %08x of tbale %08x\\n\", eax, poi(eax), poi(poi(eax));dds poi(eax) L 1;g" 
这个断点是在CTreeNode+0x8c地方断下,打印对象指针,对应的CElement指针(CTreeNode+0×0处保存对应CElement对象),以及对应的CElement对象的虚函数表地址。

定好断点,GO!

从图可以看出,最后创建了一个CObjectElement对象在00201c30,然后立马又创建了与之对应的CTreeNode对象0338aa18,到了程序崩毁的地方,ebx(即CTreeNode对象)还是0338aa18,但是与之对应的CObjectElement对象(ecx)却改变了。

我们看00201c30的地方:

这里已经不是CObjectElement的虚函数表,说明这个对象已经被释放,所以与之对应的CTreeNode也在崩溃之前释放了,所以这里CTreeNode+0×0的CObjectElement指针也是错误的,所以指向的地方是00000000,然后读取虚函数表出错。我们定下断点:

  1. bu  mshtml!CTreeNode::Release+0x19 ".printf \"freeing CTreeNode at %08x, CElement at %08x, of table %08x\\n\", edx, poi(edx), poi(poi(edx)); g" 

这里可以看出,在IE崩溃前,CTreeNode已经释放了,然后崩溃时又引用了这个对象对应的CElement对象,然后call虚函数,导致程序出错。为什么会释放呢?因为<object>标签没指明clsid值,所以IE会释放这个标签,那么接下来我们可以干什么呢?




www.bkjia.comtruehttp://www.bkjia.com/hmmm/1002959.htmlTechArticle针对网页木马(CVE-2011-1260)的分析与实践(1) 本文假设你对漏洞挖掘,漏洞分析,汇编这些不太了解,但是对C,C++有一定了解。首先我们找...

相关文章

相关搜索: 网页木马 分析实践

帮客评论

视觉看点