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