標(biāo) 題: 【原創(chuàng)】【技術(shù)專題】軟件漏洞分析入門_9_案例_微軟ANI光標(biāo)文件漏洞徹底分析利用 作 者: shineast 時(shí) 間: 2008-01-10,10:41:38 鏈 接: http://bbs./showthread.php?t=58026 為支持老大failwest的新書《0day安全:軟件漏洞分析與利用》的發(fā)行,響應(yīng)看雪在漏洞分析領(lǐng)域的雄起,上期獻(xiàn)上一篇《Microsoft TIFF圖像文件處理?xiàng)R绯雎┒矗∕S07-055)》,本期繼續(xù)貢獻(xiàn)我在《黑客防線》上發(fā)表過得漏洞案例實(shí)戰(zhàn)分析文章。希望通過這兩篇文章,使大家對文件格式漏洞有一個(gè)初步的認(rèn)識。 漏洞概述 2007年3月30日,ph4nt0m和milw0rm先后公布了今年目前為止危害性最大的windows漏洞——user32.dll的ANI文件處理漏洞。我寫這篇文章已是漏洞爆出的第5天了,事實(shí)上,30號公布的漏洞,30號晚上利用這個(gè)漏洞的網(wǎng)馬生成器已經(jīng)在網(wǎng)上散播了,而且微軟遲遲沒有發(fā)布相關(guān)補(bǔ)丁。這給利用這個(gè)漏洞的病毒、蠕蟲、木馬、惡意軟件等,一個(gè)很難得的機(jī)會。漏洞就像一把鑰匙,打開了它們侵入互聯(lián)網(wǎng)的大門。 雖然eEye推出了一款非官方的補(bǔ)丁,可以攔截一部分遠(yuǎn)程攻擊、網(wǎng)絡(luò)木馬,但是4月1日,milw0rm上又公布了一個(gè)能夠繞過eEye補(bǔ)丁的exploit。看來又是一場互聯(lián)網(wǎng)血雨腥風(fēng)的到來! 漏洞分析 既然這個(gè)漏洞是和ANI文件有關(guān)的,那么我們在分析漏洞之前,首先需要對ANI文件格式有一定的了解。關(guān)于ANI文件格式的詳細(xì)說明請讀者參閱光盤中的附件。 ANI(APPlicedon Startins Hour Glass)文件是MS Windows的動畫光標(biāo)文件,可以作為鼠標(biāo)指針,其文件擴(kuò)展名為“.ani”。ANI文件由“塊”(chunk)構(gòu)成。它一般由五部分構(gòu)成:標(biāo)志區(qū)、文字說明區(qū)、信息區(qū)、時(shí)間控制區(qū)和數(shù)據(jù)區(qū),即RIFF—ACON,LIST—INFO,anih,rate,LIST—fram。ANI文件在播放時(shí)所形成的動畫效果,其實(shí)就是一張張的光標(biāo)或圖標(biāo)圖像按一定的順序繪制到屏幕上,并保留指定的時(shí)間(見時(shí)間控制區(qū)說明)依序循環(huán)顯示的結(jié)果。一個(gè)ANI文件的開頭12個(gè)字節(jié)中,頭4個(gè)字節(jié)為RIFF,后4個(gè)字節(jié)為ACON,中間4個(gè)字節(jié)是該ANI文件的長度(字節(jié)數(shù))。有了RIFF和ACON,就可斷定該文件是一個(gè)ANI文件,也就是說,ACON是一個(gè)動畫光標(biāo)文件的標(biāo)志。 在一個(gè)ANI文件中,必須有的塊標(biāo)識有以下幾個(gè): RIFF—多媒體文件識別碼 ACON—ANI文件識別碼 anih—ANI文件信息區(qū)識別碼 LIST—LIST列表形式(窗體形式fccType=“fram”) icon—icon識別碼 在一個(gè)ANI文件中,還可能有以下幾個(gè)塊標(biāo)識中的一個(gè)或多個(gè): INAM—ANI文件標(biāo)題區(qū)識別碼 IART—ANI文件說明信息區(qū)識別碼 rate—ANI文件時(shí)間控制數(shù)據(jù)區(qū)識別碼 seq —ANI文件圖像顯示幀順序控制區(qū)識別碼 這些塊之間的邏輯層次關(guān)系可以如下表示: "RIFF" {Length of File} "ACON" "LIST" {Length of List} "INAM" {Length of Title} {Data} "IART" {Length of Author} {Data} "fram" "icon" {Length of Icon} {Data} ; 1st in list ... "icon" {Length of Icon} {Data} ; Last in list (1 to cFrames) "anih" {Length of ANI header (36 bytes)} {Data} ; (see ANI Header TypeDef ) "rate" {Length of rate block} {Data} ; ea. rate is a long (length is 1 to cSteps) "seq " {Length of sequence block} {Data} ; ea. seq is a long (length is 1 to cSteps) -END- 以上僅是對ANI文件格式的結(jié)論性描述,要完全明白這些塊的作用和意義,以及塊與塊之間的邏輯關(guān)系,確實(shí)需要下一番功夫。另外僅研讀我給的資料是完全不夠的,一定會有理解起來模糊的地方,因此還需要?jiǎng)邮肿鰧?shí)驗(yàn),自己跟蹤user32.dll對ANI文件的處理過程,從實(shí)驗(yàn)中得到結(jié)論。這樣做有兩個(gè)好處,一是可以更加深刻的理解漏洞的根源;二是由此可以啟發(fā)新漏洞的挖掘思想。 如果你對ANI文件格式已有一定了解,那我們就可以開始分析造成最終user32.dll棧溢出的這個(gè)畸形.ani文件了,為了理解,我把這個(gè)ANI文件(exp.ani)用十六進(jìn)制的方式打開,并示意如下: 這是一個(gè)精心構(gòu)造的1k大小的.ani文件(在XP SP2全補(bǔ)丁下測試通過),其各個(gè)部分解釋如下表所示: 偏移地址 內(nèi)容 含義 塊 0000-0003h “RIFF” 多媒體文件識別碼 RIFF 0004-0007h 0000 0400h 文件大?。?k) 0008-000Bh “ACON” ANI文件識別碼ACON 000C-000Fh “anih” anih識別碼(ckID),信息區(qū)開始的標(biāo)志 anih 0010-0013h 0000 0024h anih塊的大?。╟kSize,36個(gè)字節(jié)) 0014-0037h anih塊內(nèi)容 0038-003Bh “LIST” LIST識別碼,數(shù)據(jù)區(qū)開始的標(biāo)志 LIST 003C-003Fh 0000 0003 LIST塊的大小(3個(gè)字節(jié)) 0040-0043h LIST塊內(nèi)容 0044-0047h “LIST” LIST識別碼,數(shù)據(jù)區(qū)開始的標(biāo)志 LIST 0048-004Bh 0000 0003 LIST塊的大?。?個(gè)字節(jié)) 004C-004Fh LIST塊內(nèi)容 0050-0053h “anih” anih識別碼(ckID),信息區(qū)開始的標(biāo)志 anih 0054-0057h 0000 03A8h anih塊的大?。╟kSize,936個(gè)字節(jié)) 0058-03F0h anih塊內(nèi)容 為什么這個(gè)文件能使user32.dll棧溢出?據(jù)我分析,是因?yàn)閡ser32.dll對這個(gè).ani文件中的第二個(gè)anih塊處理時(shí),未對這個(gè)塊的長度進(jìn)行檢查,最終導(dǎo)致棧溢出,控制了程序的EIP。通常來說任何一個(gè)正常的anih塊的長度應(yīng)該是36個(gè)字節(jié),為什么這樣說呢?因?yàn)閍nih塊內(nèi)容是有自己的數(shù)據(jù)結(jié)構(gòu)的,用一個(gè)結(jié)構(gòu)體來表示: typedef DWORD JIF,*PJIF; typedef struct tagANIHEADER{ DWORD cbSizeof; //數(shù)據(jù)塊大小,應(yīng)該是36字節(jié) DWORD cFrames; //ANI文件保存的圖象楨數(shù) DWORD cSteps; //完成一次動畫過程要顯示的圖象數(shù) DWORD cx; //圖象寬度 DWORD cy; //圖象高度 DWORD cBitCount; //顏色位數(shù) DWORD cPlanes; //顏色位面數(shù) JIF jifRate; //JIF速率 DWORD fl; //AF_ICON/AF_SEQUENCE設(shè)置標(biāo)記 }ANIHEADER,*PANIHEADER; 可見,這個(gè)anih塊內(nèi)容是一個(gè)9個(gè)雙字的結(jié)構(gòu)體,所以說它的長度應(yīng)該是9×4=36字節(jié)。然而這個(gè)畸形的.ani文件中第二個(gè)anih塊內(nèi)容的長度偏偏不為36字節(jié),而是936個(gè)字節(jié),若程序中把這個(gè)塊的內(nèi)容復(fù)制到棧中,你說這能不溢出嗎? 下面我們用ollyDBG跟蹤一下這個(gè)溢出過程,看看根本原因是不是如上所說。 //user32.dll中的ReadChunk(x,x,x)函數(shù) 77D53AC7 8BFF MOV EDI,EDI 77D53AC9 55 PUSH EBP 77D53ACA 8BEC MOV EBP,ESP 77D53ACC 56 PUSH ESI 77D53ACD 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8] 77D53AD0 57 PUSH EDI 77D53AD1 8B7D 0C MOV EDI,DWORD PTR SS:[EBP+C] 77D53AD4 FF77 04 PUSH DWORD PTR DS:[EDI+4] ;anih塊內(nèi)容的長度 77D53AD7 FF75 10 PUSH DWORD PTR SS:[EBP+10] 77D53ADA 56 PUSH ESI 77D53ADB E8 7AFFFFFF CALL USER32.77D53A5A ;調(diào)用ReadFileCopy函數(shù) 77D53AE0 85C0 TEST EAX,EAX //user32.dll中的ReadFileCopy(x,x,x)函數(shù) 77D53A5A 8BFF MOV EDI,EDI 77D53A5C 55 PUSH EBP 77D53A5D 8BEC MOV EBP,ESP 77D53A5F 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] 77D53A62 8B55 10 MOV EDX,DWORD PTR SS:[EBP+10] 77D53A65 56 PUSH ESI 77D53A66 8B70 04 MOV ESI,DWORD PTR DS:[EAX+4] ;讓ESI指向堆中的anih塊內(nèi)容 77D53A69 8D0C16 LEA ECX,DWORD PTR DS:[ESI+EDX] 77D53A6C 3BCE CMP ECX,ESI 77D53A6E 72 28 JB SHORT USER32.77D53A98 77D53A70 3BCA CMP ECX,EDX 77D53A72 72 24 JB SHORT USER32.77D53A98 77D53A74 3B48 08 CMP ECX,DWORD PTR DS:[EAX+8] 77D53A77 77 1F JA SHORT USER32.77D53A98 77D53A79 53 PUSH EBX 77D53A7A 57 PUSH EDI 77D53A7B 8B7D 0C MOV EDI,DWORD PTR SS:[EBP+C] ;讓EDI指向棧幀中的一個(gè)內(nèi)存單元 77D53A7E 8BCA MOV ECX,EDX 77D53A80 8BD9 MOV EBX,ECX 77D53A82 C1E9 02 SHR ECX,2 ; 讓ECX為.ani文件中第二個(gè)anih塊的塊內(nèi)容大小的1/4 ;一次復(fù)制一個(gè)雙字,所以下面REP指令的循環(huán)次數(shù)應(yīng)該為字節(jié)數(shù)的四分之一 77D53A85 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI] 77D53A87 8BCB MOV ECX,EBX 77D53A89 83E1 03 AND ECX,3 77D53A8C F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 77D53A8E 0150 04 ADD DWORD PTR DS:[EAX+4],EDX 77D53A91 33C0 XOR EAX,EAX 77D53A93 5F POP EDI 77D53A94 40 INC EAX 77D53A95 5B POP EBX 77D53A96 EB 02 JMP SHORT USER32.77D53A9A 77D53A98 33C0 XOR EAX,EAX 77D53A9A 5E POP ESI 77D53A9B 5D POP EBP 77D53A9C C2 0C00 RETN 0C 上面是對溢出過程的動態(tài)跟蹤分析,如果用IDA進(jìn)行靜態(tài)分析同樣也會得到上面的提到的漏洞原因,這里不再贅述! 漏洞利用 提到利用,大家就笑了!想想多少東西在使用user32.dll???! 首當(dāng)其沖的就是IE了,IE6,IE7已被測試通過,全部中招,也就是說寫個(gè)網(wǎng)絡(luò)木馬是很容易了,只要有人敢上你的網(wǎng)站,那說都不說了,想干啥就干啥嘍! 其次,Windows的Explorer在打開這個(gè).ani文件所在的目錄時(shí)也會調(diào)用user32.dll中的LoadAniIcon函數(shù),從而觸發(fā)溢出。因此電子郵件、QQ、ftp、U盤等都可以用來傳播利用這個(gè)漏洞的病毒、蠕蟲、木馬、惡意軟件。 另外,還可以利用一些使用user32.dll中LoadAniIcon函數(shù)的軟件,用這些軟件打開這些畸形.ani文件,同樣也會中招。譬如,WinHex、IrfanView、Firework、Photoshop等。 本文主要演示網(wǎng)絡(luò)木馬生成和一次成功的攻擊過程。 網(wǎng)上已經(jīng)流傳了很多木馬生成器,使用很簡單,輸入網(wǎng)頁木馬遠(yuǎn)程存放地址和木馬程序存放地址即可。 我使用了我的IP地址(202.117.7.209)作為測試,然后啟動web服務(wù)(IIS5.1),把生成的那三個(gè)文件(index.htm,z1.jpg,z2.jpg),還有木馬程序(a.exe)放到web跟目錄下。 然后把鏈接(http://202.117.7.209)給幾個(gè)朋友,發(fā)現(xiàn)他們?nèi)恐姓辛?,哈哈,好在我沒有下毒手,那個(gè)木馬程序僅僅是彈出個(gè)框框而已! 漏洞防范 這個(gè)漏洞危害這么大,不防不行啊,廣大網(wǎng)民豈不是要遭殃??!因?yàn)槲覍戇@篇文章時(shí)還沒有微軟的官方補(bǔ)丁,首推的防范措施是下載eEye的非官方補(bǔ)丁,補(bǔ)丁已放在光盤附件中。 另外如果你的C盤是NTFS格式的,那么還可以使用如下措施: 1. “開始”菜單“運(yùn)行”里輸入"gpedit.msc" 2. 然后在“本地計(jì)算機(jī)”策略 => 用戶配置 => 管理模板 => 系統(tǒng) => 停止命令提示符 設(shè)置為“啟用” 3. 把“他停用命令提示符腳本處理嗎”選為“是”,再按確定! 4. C:\Documents and Settings\xxxxxx\Local Settings目錄的權(quán)限設(shè)置為不能運(yùn)行! xxxxxx是你的用戶名 總結(jié) 這個(gè)漏洞的根本原因是,user32.dll中的ReadChunk()函數(shù)未對.ani文件中的anih塊內(nèi)容長度進(jìn)行檢查,就直接調(diào)用ReadFilePtrCopy()函數(shù)把堆中的anih塊內(nèi)容復(fù)制到棧幀中。 無論利用這個(gè)漏洞的病毒、蠕蟲、木馬、惡意軟件、網(wǎng)馬對互聯(lián)網(wǎng)的沖擊有多大,我們都有理由相信,互聯(lián)網(wǎng)及我們的PC能頂過這07年的第一次危機(jī)! 值得一提的是,如果您是搞漏洞挖掘方面的,通過這次uesr32.dll爆出的漏洞,您是否體會到漏洞的真正含義呢?不光是那些一般水平程序員寫的程序容易出問題,爆漏洞;事實(shí)上,高級程序員也會有考慮不周的時(shí)候。因此漏洞是一個(gè)很微妙的東西,不是說編程經(jīng)驗(yàn)豐富、實(shí)現(xiàn)能力強(qiáng)的程序員寫的程序就不會有漏洞,任何程序員只要編程時(shí)考慮不周,都有可能爆出漏洞!本漏洞就是一個(gè)很好的例子。 |
|