Windows XP 核心驅動 AFD.sys 本地權限提升漏洞分析(ms08066)

Author: Polymorphours
Email: [email][email protected][/email]
Homepage:[url]http://www.whitecell.org[/url]
Date: 2008-10-15

漏洞模塊: AFD.sys
漏洞類型: 任意內核地址可寫
這個漏洞又是一個可以寫任意內核地址的漏洞,產生這個漏洞的原因是 ProbeForWrite 函數因爲檢查長度爲 0 的Buffer被繞過。下面看下具體漏洞的情況,這個漏洞出現在函數AfdGetRemoteAddress 中,當傳入的第7個參數爲 0 的時候,ProbeForWrite的檢查形同虛設了。
注意第六個參數 PVOID Address, 它是由 Irp->UserBuffer 傳入的,而 SIZE_T Length 爲OutputBufferLength,那麼如果在 DeviceIoControl 中的 OutputBuffer 設置成內核需要寫的地址,OutputBufferLength 設置爲 0,並設置正確的 IoDeviceCode 即可觸發這個漏洞.

PAGE:00017D17 ; int __stdcall AfdGetRemoteAddress(int,int,char,int,int,PVOID Address,SIZE_T Length,int)
PAGE:00017D17 __stdcall AfdGetRemoteAddress(x, x, x, x, x, x, x, x) proc near
PAGE:00017D17 ; DATA XREF: .data:0001230Co
PAGE:00017D17
PAGE:00017D17 var_24 = dword ptr -24h
PAGE:00017D17 var_20 = dword ptr -20h
PAGE:00017D17 var_1C = dword ptr -1Ch
PAGE:00017D17 ms_exc = CPPEH_RECORD ptr -18h
PAGE:00017D17 arg_0 = dword ptr 8
PAGE:00017D17 arg_8 = byte ptr 10h
PAGE:00017D17 Address = dword ptr 1Ch
PAGE:00017D17 Length = dword ptr 20h
PAGE:00017D17 arg_1C = dword ptr 24h
PAGE:00017D17
PAGE:00017D17 push 14h
PAGE:00017D19 push offset unk_11B00
PAGE:00017D1E call __SEH_prolog
PAGE:00017D1E
PAGE:00017D23 mov eax, [ebp+arg_0]
PAGE:00017D26 mov ebx, [eax+0Ch]
PAGE:00017D29 mov [ebp+var_24], ebx
PAGE:00017D2C xor esi, esi
PAGE:00017D2E mov eax, [ebp+arg_1C]
PAGE:00017D31 mov [eax], esi
PAGE:00017D33 push ebx
PAGE:00017D34 call AfdLockEndpointContext(x)
PAGE:00017D34
PAGE:00017D39 mov [ebp+var_20], eax
PAGE:00017D3C cmp eax, esi
PAGE:00017D3E jz loc_17DE0
PAGE:00017D3E
PAGE:00017D44 cmp word ptr [ebx], 0AFD2h
PAGE:00017D49 jnz loc_17DE0
PAGE:00017D49
PAGE:00017D4F cmp byte ptr [ebx+2], 3
PAGE:00017D53 jnz loc_17DE0
PAGE:00017D53
PAGE:00017D59 movzx eax, word ptr [ebx+5Ah]
PAGE:00017D5D movzx ecx, word ptr [ebx+58h]
PAGE:00017D61 add ecx, eax
PAGE:00017D63 cmp ecx, [ebx+74h]
PAGE:00017D66 ja short loc_17DE0
PAGE:00017D66
PAGE:00017D68 cmp [ebp+Length], eax
<----這裏檢查Buffer大小,如果Buffer大於規定的大小就有默認的大小來代替
PAGE:00017D6B jnb short loc_17D76
PAGE:00017D6B
PAGE:00017D6D mov [ebp+var_1C], 80000005h
PAGE:00017D74 jmp short loc_17D7C
<----最終導致問題點: 如果BufferLength小於的話,居然還能繼續運行它向下運行
PAGE:00017D74
PAGE:00017D76 ; ---------------------------------------------------------------------------
PAGE:00017D76
PAGE:00017D76 loc_17D76: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+54j
PAGE:00017D76 mov [ebp+Length], eax
<---用規定的長度代替
PAGE:00017D79 mov [ebp+var_1C], esi
PAGE:00017D79
PAGE:00017D7C
PAGE:00017D7C loc_17D7C: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+5Dj
PAGE:00017D7C mov [ebp+ms_exc.disabled], esi
PAGE:00017D7F cmp [ebp+arg_8], 0
PAGE:00017D83 jz short loc_17D93
PAGE:00017D83
PAGE:00017D85 push 1 ; Alignment
PAGE:00017D87 push [ebp+Length] ; Length
PAGE:00017D8A push [ebp+Address] ; Address
PAGE:00017D8D call ds:ProbeForWrite(x,x,x)
<---如果 ebp+Length爲0,那麼檢查被繞過
PAGE:00017D8D
PAGE:00017D93
PAGE:00017D93 loc_17D93: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+6Cj
PAGE:00017D93 movzx ecx, word ptr [ebx+5Ah]
PAGE:00017D97 movzx esi, word ptr [ebx+58h]
PAGE:00017D9B add esi, [ebp+var_20]
PAGE:00017D9E mov edi, [ebp+Address]
<--- memcpy的代碼,拷貝數據到UserBuffer中
PAGE:00017DA1 mov eax, ecx
PAGE:00017DA3 shr ecx, 2
PAGE:00017DA6 rep movsd
PAGE:00017DA8 mov ecx, eax
PAGE:00017DAA and ecx, 3
PAGE:00017DAD rep movsb
PAGE:00017DAF mov eax, [ebx+74h]
PAGE:00017DB2 mov ecx, [ebp+arg_1C]
PAGE:00017DB5 mov [ecx], eax
PAGE:00017DB7 or [ebp+ms_exc.disabled], 0FFFFFFFFh
PAGE:00017DBB jmp short loc_17DE7
PAGE:00017DBB
PAGE:00017DBB ; ---------------------------------------------------------------------------
PAGE:00017DBD align 10h
PAGE:00017DC0 db 2 dup(90h)
PAGE:00017DC2 ; ---------------------------------------------------------------------------
PAGE:00017DC2
PAGE:00017DC2 loc_17DC2: ; DATA XREF: .rdata:00011B04o
PAGE:00017DC2 lea eax, [ebp-1Ch]
PAGE:00017DC5 push eax
PAGE:00017DC6 push dword ptr [ebp-14h]
PAGE:00017DC9 call AfdExceptionFilter(x,x)
PAGE:00017DC9
PAGE:00017DCE retn
在看看補丁的情況
PAGE:00017D17 ; int __stdcall AfdGetRemoteAddress(int,int,char,int,int,PVOID Address,int,int)
PAGE:00017D17 __stdcall AfdGetRemoteAddress(x, x, x, x, x, x, x, x) proc near
PAGE:00017D17 ; DATA XREF: .data:0001230Co
PAGE:00017D17
PAGE:00017D17 var_24 = dword ptr -24h
PAGE:00017D17 var_20 = dword ptr -20h
PAGE:00017D17 var_1C = dword ptr -1Ch
PAGE:00017D17 ms_exc = CPPEH_RECORD ptr -18h
PAGE:00017D17 arg_0 = dword ptr 8
PAGE:00017D17 arg_8 = byte ptr 10h
PAGE:00017D17 Address = dword ptr 1Ch
PAGE:00017D17 arg_18 = dword ptr 20h
PAGE:00017D17 arg_1C = dword ptr 24h
PAGE:00017D17
PAGE:00017D17 push 14h
PAGE:00017D19 push offset unk_11B00
PAGE:00017D1E call __SEH_prolog
PAGE:00017D1E
PAGE:00017D23 mov eax, [ebp+arg_0]
PAGE:00017D26 mov ebx, [eax+0Ch]
PAGE:00017D29 mov [ebp+var_24], ebx
PAGE:00017D2C xor esi, esi
PAGE:00017D2E mov eax, [ebp+arg_1C]
PAGE:00017D31 mov [eax], esi
PAGE:00017D33 push ebx
PAGE:00017D34 call AfdLockEndpointContext(x)
PAGE:00017D34
PAGE:00017D39 mov [ebp+var_20], eax
PAGE:00017D3C cmp eax, esi
PAGE:00017D3E jz loc_17DDB
PAGE:00017D3E
PAGE:00017D44 cmp word ptr [ebx], 0AFD2h
PAGE:00017D49 jnz loc_17DDB
PAGE:00017D49
PAGE:00017D4F cmp byte ptr [ebx+2], 3
PAGE:00017D53 jnz loc_17DDB
PAGE:00017D53
PAGE:00017D59 movzx eax, word ptr [ebx+5Ah]
PAGE:00017D5D movzx ecx, word ptr [ebx+58h]
PAGE:00017D61 add ecx, eax
PAGE:00017D63 cmp ecx, [ebx+74h]
PAGE:00017D66 ja short loc_17DDB
PAGE:00017D66
PAGE:00017D68 cmp [ebp+arg_18], eax
PAGE:00017D6B jnb short loc_17D76
PAGE:00017D6B
PAGE:00017D6D mov [ebp+var_1C], 80000005h
PAGE:00017D74 jmp short loc_17DE2
<---補丁就是在這裏,如果訪問的BufferLength小於規定的大小,那麼直接返回錯誤
PAGE:00017D74
PAGE:00017D76 ; ---------------------------------------------------------------------------
PAGE:00017D76
PAGE:00017D76 loc_17D76: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+54j
PAGE:00017D76 mov [ebp+var_1C], esi
PAGE:00017D79 mov [ebp+ms_exc.disabled], esi
PAGE:00017D7C cmp [ebp+arg_8], 0
PAGE:00017D80 jz short loc_17D8E
PAGE:00017D80
PAGE:00017D82 push 1 ; Alignment
PAGE:00017D84 push eax ; Length
PAGE:00017D85 push [ebp+Address] ; Address
PAGE:00017D88 call ds:ProbeForWrite(x,x,x)
PAGE:00017D88
PAGE:00017D8E
PAGE:00017D8E loc_17D8E: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+69j
PAGE:00017D8E movzx ecx, word ptr [ebx+5Ah]
PAGE:00017D92 movzx esi, word ptr [ebx+58h]
PAGE:00017D96 add esi, [ebp+var_20]
PAGE:00017D99 mov edi, [ebp+Address]
PAGE:00017D9C mov eax, ecx
PAGE:00017D9E shr ecx, 2
PAGE:00017DA1 rep movsd
PAGE:00017DA3 mov ecx, eax
PAGE:00017DA5 and ecx, 3
PAGE:00017DA8 rep movsb
PAGE:00017DAA mov eax, [ebx+74h]
PAGE:00017DAD mov ecx, [ebp+arg_1C]
PAGE:00017DB0 mov [ecx], eax
PAGE:00017DB2 or [ebp+ms_exc.disabled], 0FFFFFFFFh
PAGE:00017DB6 jmp short loc_17DE2
PAGE:00017DB6
PAGE:00017DB6 ; ---------------------------------------------------------------------------
PAGE:00017DB8 dd 90909090h
PAGE:00017DBC db 90h
PAGE:00017DBD ; ---------------------------------------------------------------------------
PAGE:00017DBD
PAGE:00017DBD loc_17DBD: ; DATA XREF: .rdata:00011B04o
PAGE:00017DBD lea eax, [ebp-1Ch]
PAGE:00017DC0 push eax
PAGE:00017DC1 push dword ptr [ebp-14h]
PAGE:00017DC4 call AfdExceptionFilter(x,x)
PAGE:00017DC4
PAGE:00017DC9 retn
PAGE:00017DC9
PAGE:00017DC9 ; ---------------------------------------------------------------------------
PAGE:00017DCA align 4
PAGE:00017DCC db 3 dup(90h)
PAGE:00017DCF ; ---------------------------------------------------------------------------
PAGE:00017DCF
PAGE:00017DCF loc_17DCF: ; DATA XREF: .rdata:00011B08o
PAGE:00017DCF mov esp, [ebp-18h]
PAGE:00017DD2 or dword ptr [ebp-4], 0FFFFFFFFh
PAGE:00017DD6 mov ebx, [ebp-24h]
PAGE:00017DD9 jmp short loc_17DE2
PAGE:00017DD9
PAGE:00017DDB ; ---------------------------------------------------------------------------
PAGE:00017DDB
PAGE:00017DDB loc_17DDB: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+27j
PAGE:00017DDB ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+32j
PAGE:00017DDB ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+3Cj
PAGE:00017DDB ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+4Fj
PAGE:00017DDB mov [ebp+var_1C], 0C0000140h
PAGE:00017DDB
PAGE:00017DE2
PAGE:00017DE2 loc_17DE2: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+5Dj
PAGE:00017DE2 ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+9Fj
PAGE:00017DE2 ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+C2j
PAGE:00017DE2 push [ebp+var_20]
PAGE:00017DE5 push ebx
PAGE:00017DE6 call AfdUnlockEndpointContext(x,x)
PAGE:00017DE6
PAGE:00017DEB mov eax, [ebp+var_1C]
PAGE:00017DEE call __SEH_epilog
PAGE:00017DEE
PAGE:00017DF3 retn 20h
剩下的就是exploit它了,具體的方法也很簡單,可以參照以前在 [url]www.whitecell.org[/url] 上的代碼。
WSS(Whitecell Security Systems),一個非營利性民間技術組織,致力於各種系統安全技術的研究。堅持傳統的hacker精神,追求技術的精純。
WSS 主頁:[url]http://www.whitecell.org/[/url]
WSS 論壇:[url]http://www.whitecell.org/forums/[/url]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章