專家解析Adobe Flash零時差漏洞攻擊技術(shù)
幾個星期前,網(wǎng)絡(luò)上有人發(fā)現(xiàn)了一個新的Adobe Acrobat/Reader零時差漏洞,沒多久就立刻出現(xiàn)專門利用此漏洞的攻擊。從技術(shù)角度來看,此一攻擊最引人注目的地方,在于它運用了返回指標(biāo)漏洞攻擊(Return-Oriented Exploitation,簡稱 ROP)技巧來規(guī)避Windows的數(shù)據(jù)執(zhí)行防止(DEP)安全機制。此外,它還使用了二階段的攻擊程序代碼(shellcode)來執(zhí)行惡意軟件。其第一階段運用 ROP 技巧來加載第二階段的程序。第二階段才是惡意行為真正執(zhí)行的地方,而且是透過JavaScript來將.PDF檔案內(nèi)的程序代碼加載內(nèi)存。
從這類威脅我們可以看出,專門攻擊漏洞的惡意軟件真是越來越精密。盡管Microsoft等廠商已盡量加入一些新的技術(shù)來防止漏洞攻擊,但看來黑客也不是省油的燈,使用者的日子也不會太好過。
靜態(tài)分析
當(dāng)我們在分析.PDF檔案時,我們在內(nèi)部發(fā)現(xiàn)了一個很可疑的FontDescriptor(字型描述)對象。(FontDescriptor 對象用來描述.PDF檔案內(nèi)所用到的字型。)
這筆字型數(shù)據(jù)采用FlateDecode方式編碼。當(dāng)我們將它解碼之后,我們看到一個SING表,并且立刻發(fā)現(xiàn)了可疑的內(nèi)容。其uniqueName(獨特名稱)字段應(yīng)該是一個采用7位ASCII編碼且用NULL字符結(jié)尾的27字符字符串。
但是,此處的數(shù)據(jù)卻超過28個字符。這就是典型的緩沖區(qū)溢出。
除錯
我們從靜態(tài)分析得知此漏洞攻擊使用了.PDF檔案中的哪一部分?jǐn)?shù)據(jù)。接下來,我們要運用程序除錯器(debugger)來驗證我們的看法,并且看看它實際上如何運作。當(dāng)這個惡意.PDF檔案在Adobe Reader中開啟時,會呼叫strcat函式。讓我們來看看此函數(shù)調(diào)用的來源緩沖區(qū)內(nèi)容。
我們已看過「A8AAAAAA…」這段內(nèi)容。這就是先前uniqueName字段的實際內(nèi)容。而目的地緩沖區(qū)則是一個固定大小的堆棧。正是因此才會造成緩沖區(qū)溢出。
在緩沖區(qū)溢出之后,堆棧上的一個函式指標(biāo)就會被覆寫成0x4a80cb38。接著后面會呼叫這個函式指標(biāo),攻擊者就因此獲得程序執(zhí)行控制權(quán)。
返回指標(biāo)漏洞攻擊
其實緩沖區(qū)溢出本身并不是太嚴(yán)重或太不尋常的問題。但是,這項攻擊利用了ROP技巧來避開Windows用來防止漏洞攻擊的DEP機制。DEP機制可以防止系統(tǒng)執(zhí)行非可執(zhí)行內(nèi)存分頁中的內(nèi)容。
但ROP技巧會覆蓋已加載的可執(zhí)行碼來讓自己的程序執(zhí)行,巧妙地避開了DEP機制。ROP背后的邏輯是,只要程序夠大,就能讓攻擊程序運用現(xiàn)有的程序代碼來組成一個程序代碼“串行”。
此攻擊的作者選擇了Adobe Reader的icucnv36.dll組件為目標(biāo)。此組件并未設(shè)定使用地址空間配置隨機化(Address Space Layout Randomization,簡稱ASLR)功能,因此才會輕易成為 ROP 攻擊的目標(biāo)。前述的地址(0x4a80cb38)就是icucnv36.dll內(nèi)以下這段攻擊程序代碼的起點。
4a80cb38 81c594070000 add ebp,794h 4a80cb3e c9 leave 4a80cb3f c3 ret |
只要修改一下堆棧指針,這段程序代碼就會變成 ROP 串行的起點。后面接著的程序代碼則指向用來做為ROP串行的堆棧數(shù)據(jù)。堆棧數(shù)據(jù)內(nèi)容則是使用惡意.PDF檔案內(nèi)的JavaScript來加載內(nèi)存內(nèi)。以下是一段這項攻擊所用到的程序代碼:
框出來的部分經(jīng)過一些置換和反跳位運算之后,最后在內(nèi)存內(nèi)是一個雙字組(double word)大小的數(shù)值:0x4a801064。
真正具備惡意行為的第二階段攻擊程序代碼一開始也是先由JavaScript加載內(nèi)存內(nèi)。在經(jīng)過解碼之后,真正的程序代碼應(yīng)該像下面這樣:
%u52e8%u0002%u5400%u7265%u696d%u616e%u6574%u7250 %u636f%u7365%u0073%u6f4c%u6461%u694c%u7262%u7261 %u4179%u5300%u7465%u6946 |
這是原生 x86 機器碼,用來執(zhí)行真正的惡意攻擊。
回到堆棧指針調(diào)整好后的第一階段ROP程序,其程序代碼會搜尋icucnv36.dll的某些部分,并且呼叫幾個API函式:
呼叫CreateFileA來建立一個名為“iso88591”的檔案(檔名不重要)。
呼叫CreateFileMappingA,指定flProtect=0×40(讓檔案可執(zhí)行)。
呼叫MapViewOfFile來映像剛才建立的檔案。
呼叫memcpy來將第二階段的程序代碼復(fù)制到緩沖區(qū),也就是此映射共享檔案的開頭。
接著,程序跳到映像檔案所在的緩沖區(qū)開頭來執(zhí)行。由于此區(qū)為可執(zhí)行的內(nèi)存,因此就能避開DEP保護機制。
【編輯推薦】