MS06-040

MS06-040

跟着https://bbs.pediy.com/thread-73878-1.htm上的深入浅出ms60-040学习

分析环境

  • Windows2K sp4补丁前 NETAPI32.DLL
  • IDA7.0

分析过程

把NETAPI32.DLL丢进IDA,在Exports中找到NetpwPathCanonicalize,双进后进入IDA-View A,按空格以流程图形式显示

IDA流程图中有线的部分代表有比较,以不同颜色区分

  • 红-No
  • 绿-Yes
  • 蓝-顺序执行

代码执行顺序NetpwPathCanonicalize->NetpwPathType->CanonicalizePathName

在NetpwPathType中

会有cmp eax,103h,而ja跳转的条件为zf=0&cf=0,即若eax>103h则发生跳转,即字符串不超过103h才能正常运行。

后面分析CanonicalizePathName()函数,地址在.text:7517F856 call sub_7517FC68处,接下来在7517FC68处

.text:7517FC68
.text:7517FC68 ; =============== S U B R O U T I N E =======================================
.text:7517FC68
.text:7517FC68 ; Attributes: bp-based frame
.text:7517FC68
.text:7517FC68 ; int __stdcall sub_7517FC68(wchar_t *Str, wchar_t *Source, wchar_t *, int, int)
.text:7517FC68 sub_7517FC68    proc near               ; CODE XREF: NetpwPathCanonicalize+74↑p
.text:7517FC68
.text:7517FC68 var_416         = word ptr -416h
.text:7517FC68 Dest            = word ptr -414h
.text:7517FC68 Str             = dword ptr  8
.text:7517FC68 Source          = dword ptr  0Ch
.text:7517FC68 arg_8           = dword ptr  10h
.text:7517FC68 arg_C           = dword ptr  14h
.text:7517FC68 arg_10          = dword ptr  18h
.text:7517FC68
.text:7517FC68                 push    ebp
.text:7517FC69                 mov     ebp, esp
.text:7517FC6B                 sub     esp, 414h	;	开辟栈内空间,用于暂存生存的字符串
.text:7517FC71                 push    ebx
.text:7517FC72                 push    esi
.text:7517FC73                 xor     esi, esi
.text:7517FC75                 push    edi
.text:7517FC76                 cmp     [ebp+Str], esi	//比较4号串地址是否为空
.text:7517FC79                 mov     edi, ds:__imp_wcslen
.text:7517FC7F                 mov     ebx, 411h
.text:7517FC84                 jz      short loc_7517FCED
.text:7517FC86                 push    [ebp+Str]       ; Str	//	压入4号串
.text:7517FC89                 call    edi ; __imp_wcslen	//,	计算4号串的Unicode长度,注意为字节长度
																													;  的一半这是导致边界检查被突破的主要原因
																													;即用Unicode检查边界,而栈空间是按字节开的
																													;wcslen()求宽字符集长度
.text:7517FC8B                 mov     esi, eax
.text:7517FC8D                 pop     ecx
.text:7517FC8E                 test    esi, esi
.text:7517FC90                 jz      short loc_7517FCF4
.text:7517FC92                 cmp     esi, ebx
.text:7517FC94                 ja      loc_7517FD3E	;若程序越界则退出程序
.text:7517FC9A                 push    [ebp+Str]       ; Source
.text:7517FC9D                 lea     eax, [ebp+Dest]
.text:7517FCA3                 push    eax             ; Dest
.text:7517FCA4                 call    ds:__imp_wcscpy	;将4号串拷入栈中暂存串。虽然前面的边界检查有
																												;缺陷乎传入的4号串可以到0x822字节,但是4																											;号串在传入本函数被NetpwPathType()提前检查过,按
																											;照前面的分析知道4号串长度不超过0x206字节,所以
																											;光靠这里的检查缺陷不足以通过4号串制造栈溢出
.text:7517FCAA                 mov     ax, [ebp+esi*2+var_416]	;	取出4号串的最后两个字节,检查是否																																	;是斜杠
.text:7517FCB2                 pop     ecx
.text:7517FCB3                 cmp     ax, 5Ch ; '\'
.text:7517FCB7                 pop     ecx
.text:7517FCB8                 jz      short loc_7517FCD5
.text:7517FCBA                 cmp     ax, 2Fh ; '/'
.text:7517FCBE                 jz      short loc_7517FCD5
.text:7517FCC0                 lea     eax, [ebp+Dest]
.text:7517FCC6                 push    offset asc_751717B8 ; "\\"
.text:7517FCCB                 push    eax             ; Dest
.text:7517FCCC                 call    ds:__imp_wcscat
.text:7517FCD2                 pop     ecx
.text:7517FCD3                 inc     esi
.text:7517FCD4                 pop     ecx
.text:7517FCD5
.text:7517FCD5 loc_7517FCD5:                           ; CODE XREF: sub_7517FC68+50↑j
.text:7517FCD5                                         ; sub_7517FC68+56↑j
.text:7517FCD5                 mov     eax, [ebp+Source]
.text:7517FCD8                 mov     ax, [eax]
.text:7517FCDB                 cmp     ax, 5Ch ; '\'
.text:7517FCDF                 jz      short loc_7517FCE7
.text:7517FCE1                 cmp     ax, 2Fh ; '/'
.text:7517FCE5                 jnz     short loc_7517FCF4
.text:7517FCE7
.text:7517FCE7 loc_7517FCE7:                           ; CODE XREF: sub_7517FC68+77↑j
.text:7517FCE7                 add     [ebp+Source], 2
.text:7517FCEB                 jmp     short loc_7517FCF4
.text:7517FCED ; ---------------------------------------------------------------------------
.text:7517FCED
.text:7517FCED loc_7517FCED:                           ; CODE XREF: sub_7517FC68+1C↑j
.text:7517FCED                 mov     [ebp+Dest], si
.text:7517FCF4
.text:7517FCF4 loc_7517FCF4:                           ; CODE XREF: sub_7517FC68+28↑j
.text:7517FCF4                                         ; sub_7517FC68+7D↑j ...
.text:7517FCF4                 push    [ebp+Source]    ; Str1号串地址
.text:7517FCF7                 call    edi ; __imp_wcslen
.text:7517FCF9                 add     eax, esi
.text:7517FCFB                 pop     ecx
.text:7517FCFC                 cmp     eax, ebx
.text:7517FCFE                 ja      short loc_7517FD3E ;一号串没有做边界检查,可以做栈溢出
.text:7517FD00                 push    [ebp+Source]    ; Source
.text:7517FD03                 lea     eax, [ebp+Dest]
.text:7517FD09                 push    eax             ; Dest
.text:7517FD0A                 call    ds:__imp_wcscat
.text:7517FD10                 pop     ecx

总结原因

漏洞产生原因在于1号串没有做边界检查,造成的栈溢出,前面各种检查都是针对的四号串

整个函数作用在于将1号串与4号串,用'\'等字符串连接

posted @ 2020-04-19 11:10  v1ce0ye  阅读(310)  评论(0编辑  收藏  举报