微軟爆出2008年最嚴重漏洞 用戶可用瑞星卡卡打好補丁
2009-08-27 07:51:00MS08-067漏洞分析
netapi32.dll!NetpwPathCanonicalize在解析路徑名時存在堆棧上溢的漏洞,攻擊者可以傳入精心構造的路徑參數來覆蓋掉函數的返回地址,從而執行遠程代碼。攻擊者可以通過RPC發起請求,該請求的處理在svchost.exe中實現,導致svchost.exe發生遠程溢出。
下面以 5.1.2600.2180 版本為例分析該漏洞的成因:
.text:5B86A259 NetpwPathCanonicalize proc near
...
.text:5B86A2AF push edi ; int
.text:5B86A2B0 push [ebp arg_8] ; int
.text:5B86A2B3 mov [esi], di
.text:5B86A2B6 push esi ; int
.text:5B86A2B7 push [ebp pPolicyChain] ; pathname
.text:5B86A2BA push ebx ; int
.text:5B86A2BB call CanonicalizePathName
.text:5B86A2C0 cmp eax, edi
.text:5B86A2C2 jnz short @@Return
...
.text:5B86A2D2 NetpwPathCanonicalize endp
.text:5B86A2E0 CanonicalizePathName proc near
...
.text:5B86A37D push eax ; str
.text:5B86A37E call DoCanonicalizePathName
.text:5B86A383 test eax, eax
.text:5B86A385 jz short @@Return_0x7B
...
.text:5B86A3C7 CanonicalizePathName endp
Netapi32.dll!NetpwPathCanonicalize函數通過內部函數CanonicalizePathName來處理傳入的路徑。該函數又調用內部函數DoCanonicalizePathName來實現真正的處理過程,該漏洞的溢出點則是出現在DoCanonicalizePathName函數中:
該函數首先把路徑中的’/’全部轉成’\’,然后試圖修改傳入的路徑緩沖區來得到相對路徑。比如:
.\\abc\123\..\a\..\b\.\c
將被處理成:
\abc\b\c
該函數在處理相對路徑時,使用兩個指針分別保存前一個斜杠(后面用’\’表示)和當前’\’的指針,如下所示:
\abc\a\..\b
^ ^
| |
| --- 當前’\’指針(后文表示為CurrentSlash)
----- 前一個’\’指針(后文表示為PrevSlash)
當該函數掃描到’..\’時,會把CurrentSlash開始的數據復制到PrevSlash開始的內存空間處,然后(!漏洞就在這里!)從當前的PrevSlash指針減1的位置開始向前(低地址處)搜索’\’來重新定位PrevSlash,搜索截止條件為PrevSlash等于路徑緩沖區的起始地址。
下面是該函數的處理過程:
.text:5B87879C @@LoopSearchSlash:
.text:5B87879C mov [ebp PrevSlash], edi
.text:5B87879F mov esi, edi
.text:5B8787A1 lea eax, [edi-2]
.text:5B8787A4 jmp short @@IsSlash?
.text:5B8787A6
.text:5B8787A6 @@LoopSearchBack:
.text:5B8787A6 cmp eax, [ebp BufferStart]
.text:5B8787A9 jz short @@EndOfSearch
.text:5B8787AB dec eax
.text:5B8787AC dec eax
.text:5B8787AD
.text:5B8787AD @@IsSlash?:
.text:5B8787AD cmp word ptr [eax], '\'
.text:5B8787B1 jnz short @@LoopSearchBack
.text:5B8787B3
.text:5B8787B3 @@EndOfSearch:
考慮下面的情況:
\..\a
^ ^
| |
| --- CurrentSlash
------ PrevSlash
當完成對’..\’的替換后,緩沖區的內容為:’\a’。這時,按照該函數的算法,把PrevSlash減1并開始向前搜索’\’,此時PrevSlash已經向前越過了路徑緩沖區的起始地址,所以該函數的截止條件失效,導致該函數會一直向堆棧的低地址空間搜索(上溢出)。如果在低地址處正好搜到一個’\’,則會把CurrentSlash之后的數據復制到堆棧中’\’開始的地方,并覆蓋掉堆棧中的正常數據。攻擊者可以通過傳入精心構造的路徑數據來覆蓋掉函數的返回地址來執行代碼。


