探索黑客技术攻防,实战研究与安全创新

导航菜单

CVE2011-2140 flash漏洞分析

一、漏洞的公开信息:查询

图片26.png

得知该漏洞允许远程攻击者在装有Adobe Flash Player的机器上执行恶意代码。通过访问一个恶意页面或者恶意文件这中用户交互方式来进行漏洞的溢出。漏洞存在于flash player解析流媒体的sequenceParameterSetNALUnit组件,由于num ref frames_ in pic_order_cnt_cycle设置了无效的数值造成解析进程没有检查就将用户提供的数据(通过offset_for_ref_frame)拷贝到堆栈上一段固定长度的缓冲区造成溢出。因此,攻击者可以在浏览器中通过此漏洞来执行恶意代码。

二、漏洞触发原因分析:

分析工具:IDA pr0 5.5+Ollylce l.1英文版分析环境:windows xp SP3英文版+ IE6+ Adobe Flash Player 10 ActiveX 10.2.159.1拿到POC之后,将POC放到一个搭建好的Web服务器指定目录下。用分析环境中的IE6访问POC所在的网址,比如本例中/raw. swf。产生异常.EIP此时为ODODODOD,堆栈ESP所指的内存区域如下图所示:

图片27.png

很显然,堆栈在触发异常时被特定的数据所覆盖,如图含有ODODODOD的二进制数据。通过栈回溯,我们找到最临近的调用函数:

图片28.png

在函数调用处设置断点,重启调试器加载IE6,打开指定网页(仍是http://xxx. com/raw. swf)。调试期果然断在断在指定断点处。(注意:flashlOp. ocx基址变化,可能是OxXXXX9675)通过一步步的跟踪,最后定位到距离异常最近的一个call上,我们设置这个函数为EvilTrigger。如下图所示:

图片29.png

在此,我们记录下函数返回地址保存的位置,稍后我们会发现,返回地址会被覆盖。

图片30.png

根据公开信息的提示,我们会猜测稍后在此函数中可能有内存拷贝操作会覆盖这个地址,我们在Ox0013e570处设置内存写入断点。调试器果然断下来了。

图片31.png

图5中的注释已经很明白,每次拷贝时,通过call 021eafed这个函数来设置eax,也就是拷贝的源数据。从esp+14地址处获取拷贝目的地址并保存到ecx中去,ebp作为counter,拷贝长度保存在esi+4c中,每次拷贝一个DWORD,然后拷贝目的地址加4。

既然拷贝目地地址到了函数返回地址保存的位置,本例中是Ox0013e570。那么说明这个往堆栈拷贝数据的操作中,拷贝长度过长。也就是本例中的[esi+4c]=Ox200。我们重启调试器,重点关注拷贝长度是如何获取的。

通过公开信息的提示,这个拷贝长度很可能是num ref frames_ in pic_order_cnt_cycle这个值,num ref frames_ in pic_order_cnt_cycle在解码过程中被用来计算图像顺序值。num ref frames_ in pic_order_cnt_cycle在0到255之间取值,包括边界值。Ox200显然远大于这个值,造成了函数返回地址的覆盖,在函数执行返回时,EIP指向了拷贝的DWORD从而获得了执行控制权。

我们重启调试器让其加载IE6,观察拷贝长度的来源。在调试中我们发现拷贝长度保存的地址是固定的Ox0013e114。我在其上设置内存访问断点。果然,在相关地方断下来了。

021EBAIB    8946 50    mOv    dword ptr[esi+50], eax

、    ‘’

021EBA23    8946 4C    mov    dword ptr[esi+4C], eax

021EBA26    85CO    test    eax,  eax

021EBA28    76 1F    jbe    short 021EBA49

上面红色标记的汇编指令call 021eafbe就是设置eax,下一句指令将eax赋值给[esi+4c],而这个正是拷贝长度所在内存地址。我们打开IDA,反汇编flashlOp. ocx,定位到函数021eafbe,通过F5翻译为C代码。如下所示:

unsigned int    fastcall  sub_ 1005AFBE (int  al)

{

int vl;//
edi@l

unsigned irit nESI;  //
esi@l

vl=al:

nESI=0:

while  (  !(unsigned    int8)sub_1005AEF4(al) && nESI < Ox20 )

{

++nESI:    al=vl:

)

return sub_1005AF23(vl, nESI)  +(1<<nESI) -1:

)

此函数最终设置了拷贝长度为Ox200,在拷贝过后,相关的堆栈内存状态如下所示:从Ox0013E120开始,拷贝到Ox0013e91c结束。此时查看Ox0013e91c处的内存状态:

图片32.png

  函数EvilTrigger在返回时:

unsigned int    fastcall  sub_ 1005AFBE (int  al)

{

int vl;//
edi@l

unsigned irit nESI;  //
esi@l

vl=al:

nESI=0:

while  (  !(unsigned    int8)sub_1005AEF4(al) && nESI < Ox20 )

{

++nESI:    al=vl:

)

return sub_1005AF23(vl, nESI)  +(1<<nESI) -1:

)

此时堆栈的状态如下图所示:

图片33.png

最终程序流程跳转到OxOdOdOdOd上去执行。

三、漏洞利用技术分析:

本例中没有找到稳定的IE8、IE9利用,由于该漏洞能控制EIP指向,只需要通过堆喷射来设置指定地址的堆内容数据,填充shellcode即可利用。但是如果开通了DEP/ASLR,则目前没有稳定的利用。

目前堆喷射有两种模式,一种为在网页中通过进行喷射,另外一种是基于flash的ActionScript喷射。目前比较流行第二种。

四、shellcode分析:

在Ox021E3D8A处设置断点,去除掉所有其他断点。重新启动调试器加载IE并打开指定网页。在断点处成功断下后单步跟踪,EIP指向了OdOdOdOd。由于喷射已然完成,成功跳转到shellcode上执行:

ODOD3F34    /EB 10    jmp    short ODOD3F46

ODOD3F36    5B    pop    ebx

ODOD3F37    4B    dec    ebx

ODOD3F38    33C9    xor    ecx,  ecx

ODOD3F3A    66:B9 9904    mov    cx, 499

ODOD3F3E    80340B E2    xor    byte ptr  [ebx+ecx], OE2

ODOD3F42  -IE2 FA    loopd    short ODOD3F3E

ODOD3F44    EB 05    jmp    short ODOD3F4B

ODOD3F46    \E8 EBFFFFFF    call    ODOD3F36

上面是一段解密程序,将OxOdOd3f34开始的数据逐字节与OxOE2异或。我们查看异或后shellcode尾部,发现了端倪:

图片34.png

出于安全性的考虑,事例中已经将exe地址全部修改为http://127.0.0.1/calc. exe。以防止出现不必要的麻烦。接下来就是获取相关需要的函数,然后下载恶意exe到本地并执行。就不赘言分析了。有兴趣者可以自行分析。

本文为网络安全技术研究记录,文中技术研究环境为本地搭建或经过目标主体授权测试研究,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,在挖掘、提交相关漏洞的过程中,应严格遵守相关法律法规。