标签归档:Tencent

某国产DEX加固原理

Intro

这个加固是来自国内某个公司的作品,虽然在强度不是太高,但思路却不错,很好的平衡了性能和保护效果。目前看来,分析的这个版本只是一个很初级的框架,如果再此之上进行更多的防护和保护,强度会更好。

加固效果

加固之后,其效果是DEX中某些函数被加上ACC_NATIVE标志,原始的DEX代码已经消失,使得反编译、二次打包等功能失效。而加固之后新增的Libt**.so则负责在运行的时候,还原那些被抽取的Dalvik虚拟机代码。 More

RDB文件格式分析

RDB文件常见于腾讯的客户端软件,大多数与UI资源相关,包括了各种图片、XML等。

Layout

文件头包含了文件基本结构的信息,File Description Table描述了文件名、大小和偏移,最后就是实际文件的数据,没有加密或者压缩。 More

CVE-2013-3897 UAF Analysis

前几天面试管家,让我分析一个IE10以上的漏洞并给出详细报告,我挑了个CVE-2014-0322。从前都是从崩溃点之后开始分析ShellCode,这次把前前后后的细节都看了一遍,受益匪浅。趁着有感觉,今天又看了一下CVE-2013-3897,发现出错的逻辑是一样的,均和AddRef有关。
POC来自这里
分析的目标是Windows XP Professional SP3下IE8的mshtml.dll文件,详细信息如下:

这里只记录一下崩溃点之前对象的LifeTime,这也是UAF的主要原因。
IE内部对对象的管理,几乎都使用了这种方法。摘录一段:

AddRef和Release的功能不言而喻,类似于智能指针,这俩函数用于维护引用计数。当有函数引用对象的时候,应该调用AddRef增加计数,在用完之后调用Release减少计数。而当对象内部计数为0的时候,Release内部会自动释放掉对象。
这个设计的初衷是好的,但是手动档实在不好,程序员在使用的时候经常会手贱多加一个AddRef或者遗漏Release。忘记AddRef可能导致UAF,忘记Release则导致内存泄漏。
通过POC的崩溃点可以很容易的知道,被UAF的是一个CDisplayPointer对象,在进入CDisplayPointer::ScrollIntoView的时候,该对象还是好的。

之后的流程会往CDoc::ScrollPointerIntoView走,走了很多很多代码之后,最后会到这里:

ClearInterfaceFn将调用这个CDisplayPointer的Release函数,减少引用计数,并释放该对象。之后的代码,还会继续使用该对象,导致了UAF。
到这里,可以判断,CDisplayPointer的引用计数一定出了问题,至于是在CSelectTracker::Destroy手贱多写了一句,还是在CDisplayPointer::ScrollIntoView之前就忘记AddRef了,不得而知。
对于这种情况,只能通过补丁后的代码进行对比,分析是什么地方出了问题。用于进行对比的文件信息如下:

首先对比CSelectTracker::Destroy,看看是否手贱:

没有问题。那肯定就是在CDisplayPointer::ScrollIntoView之前忘记了AddRef。在CDisplayPointer::ScrollIntoView下断点观察之后,发现补丁后的版本,在进入CDisplayPointer::ScrollIntoView的时候,该CDisplayPointer的引用计数为2。所以,目前已经十分明显,在CDisplayPointer::ScrollIntoView之前的代码中,某处对CDisplayPointer的操作忘记了AddRef。
要找到这个地方只能通过补丁后的版本来跟踪。跟踪的方法和简单:首先,找个地方停下来,拍个快照,此举是为了保证堆地址不会变化;然后记录所有CDisplayPointer的构造函数,对比进入CDisplayPointer::ScrollIntoView时候的CDisplayPointer对象,得到我们需要的CDisplayPointer对象地址;接下来恢复快照,对这个对象+4的地方进行内存写入操作监视,对于IE的大部分对象来说,+4偏移处的含义是该对象的引用计数。在进入CDisplayPointer::ScrollIntoView之前的最后一次AddRef,也便是原来忘记添加的AddRef。
以下代码说明了这个补丁的原因以及修补方法:
8.00.6001.18702中CDisplayPointer对象的虚表:

对应的代码片段:

8.00.6001.23569中CDisplayPointer对象的虚表:

包含补丁的代码片段:

补丁后的代码在CHTMLEditor::SelectRangeInternal中增加了对AddRef的调用。可见,原来导致漏洞的原因就是因为在CHTMLEditor::SelectRangeInternal忘记对CDisplayPointer进行AddRef。如果把3C96DC4F的两句去掉,原来的POC还是会Crash掉IE,这也证明了漏洞的根源再次。
至于为什么会在这,恐怕得十分熟悉mshtml才能解释了。 More