网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > windows > 系统安全 > 漏洞补丁 > 对Windows XP SP2溢出漏洞进行保护(上)  

对Windows XP SP2溢出漏洞进行保护(上)

2004-12-28  作者:BitsCN整理  来源:中国网管联盟  点评 投稿 收藏


  我们知道在我们对溢出漏洞进行eXP的时候,经常要利用全局性的指针,利用异常处理。那么XP的SP2对此作了处理。使得我们无法运用以前的技巧来完成我们的工作。例如,对全局性的指针都作了编码处理。
  
  那么具体来讲,本文主要谈到以下:
  
  1、映射给PEB管理结构的起始地址做了随机处理。后面我们会看到这种随机是很弱的,但已经足够让eXP无法完成或者说是稳定的工作。
  
  2、对TOP SEH的保护
  
  3、VEH链表指针_RtlpCalloutEntryList的保护
  
  4、堆块结构的cookie保护
  
  不涉及内容:
  
  1、如何绕过保护机制
  
  2、堆管理的细节,其实没有太大的变化
  
  主题开始:
  
  1、PEB的地址的随机
  
  XP系统下,创建进程使用的是_NtCreateProcessEx函数,而不是_NtCreateProcess函数。_NtCreateProcess主要调用_PspCreateProcess@36函数来完成进程的创建工作
  
  PAGE:004B4649 call _PspCreateProcess@36 ; PspCreateProcess(x,x,x,x,x,x,x,x,x)
  
  进程的创建主要包括设置EPROCESS,创建初始进程地址空间等。这里就不罗嗦了。PEB的设置通过调用_MmCreatePeb.

网管u家u.bitsCN.com


  
  PAGE:004B428E push eax
  PAGE:004B428F push ebx
  PAGE:004B4290 push dword ptr [ebp-60h]
  PAGE:004B4293 call MmCreateProcessAddressSpace@12 ; MmCreateProcessAddressSpace(x,x,x)
  
  PAGE:004B43E5 lea eax, [ebx+1B0h]
  PAGE:004B43EB push eax
  PAGE:004B43EC lea eax, [ebp-40h]
  PAGE:004B43EF push eax
  PAGE:004B43F0 push ebx
  PAGE:004B43F1 call MmCreatePeb@12 ; MmCreatePeb(x,x,x)
  
  而MmCreatePeb又主要通过调用_MiCreatePebOrTeb
  
  PAGE:004B4A61 ; __stdcall MmCreatePeb(x,x,x)
  PAGE:004B4A61 ">_MmCreatePeb@12 proc near ; CODE XREF: PspCreateProcess(x,x,x,x,x,x,x,x,x)+303p
  PAGE:004B4A61
  PAGE:004B4A61 ; FUNCTION CHUNK AT PAGE:005267FF SIZE 000000DC BYTES
  PAGE:004B4A61
  PAGE:004B4A61 push 3Ch
  PAGE:004B4A63 push offset dword_42DAA8
  PAGE:004B4A68 call __SEH_prolog
  PAGE:004B4A6D xor ebx, ebx
  PAGE:004B4A6F mov [ebp-20h], ebx
  PAGE:004B4A72 mov [ebp-4Ch], ebx
  PAGE:004B4A75 mov [ebp-48h], ebx

网管论坛bbs_bitsCN_com


  PAGE:004B4A78 mov [ebp-2Ch], ebx
  PAGE:004B4A7B mov esi, [ebp+8]
  PAGE:004B4A7E push esi
  PAGE:004B4A7F call _KeAttachProcess@4 ; KeAttachProcess(x)
  PAGE:004B4A84 push 2
  PAGE:004B4A86 pop edi
  PAGE:004B4A87 push edi
  PAGE:004B4A88 push (offset loc_4FFFFE+2)
  PAGE:004B4A8D push 1
  PAGE:004B4A8F lea eax, [ebp-2Ch]
  PAGE:004B4A92 push eax
  PAGE:004B4A93 lea eax, [ebp-4Ch]
  PAGE:004B4A96 push eax
  PAGE:004B4A97 push ebx
  PAGE:004B4A98 push ebx
  PAGE:004B4A99 lea eax, [ebp-20h]
  PAGE:004B4A9C push eax
  PAGE:004B4A9D push esi
  PAGE:004B4A9E push ds:_InitNlsSectionPointer
  PAGE:004B4AA4 call _MmMapViewOfSection@40 ; MmMapViewOfSection(x,x,x,x,x,x,x,x,x,x)
  PAGE:004B4AA9 mov [ebp-24h], eax
  PAGE:004B4AAC cmp eax, ebx
  PAGE:004B4AAE jl loc_5267FF
  PAGE:004B4AB4 lea eax, [ebp-1Ch]
  
  注意下面这个210参数,类似一个Flag。在后面你会发现,如果该参数不等于210,那么映射的PEB地址将不会产生随机值,而是会跟以前的一样,始终在7FFDF000位置。

网管bitscn_com


  
  PAGE:004B4AB7 push eax
  PAGE:004B4AB8 push 210h
  ;注意这个参数!
  PAGE:004B4ABD push esi
  PAGE:004B4ABE call ">_MiCreatePebOrTeb@12 ; MiCreatePebOrTeb(x,x,x)
  
  真正完成工作
  
  MiCreatePebOrTeb@12 函数
  
  PAGE:004B01AE call ExAllocatePoolWithTag@12 ; ExAllocatePoolWithTag(x,x,x)
  PAGE:004B01B3 mov esi, eax
  
  PAGE:004B01B5 test esi, esi
  PAGE:004B01B7 jz loc_52678E
  PAGE:004B01BD mov eax, [ebp+arg_8]
  PAGE:004B01C0 mov ecx, [ebp+arg_8]
  PAGE:004B01C3 and eax, 0FFFh
  PAGE:004B01C8 neg eax
  PAGE:004B01CA sbb eax, eax
  PAGE:004B01CC neg eax
  PAGE:004B01CE shr ecx, 0Ch
  
  PAGE:004B01FB cmp [ebp+arg_8], 210h
  PAGE:004B0202 jz loc_4B4A0A
  ;这里将210与压栈的参数比较,如果压入栈的不是210呢
  
  
  PAGE:004B0208 loc_4B0208: ; CODE XREF: MiCreatePebOrTeb(x,x,x)+48ADj
  PAGE:004B0208 mov edi, [ebp+arg_C]
  PAGE:004B020B mov eax, _MmHighestUserAddress
网管论坛bbs_bitsCN_com

  PAGE:004B0210 push edi
  PAGE:004B0211 push dword ptr [ebx+11Ch]
  PAGE:004B0217 add eax, 0FFFF0001h
  PAGE:004B021C push 1000h
  PAGE:004B0221 push eax
  PAGE:004B0222 mov eax, [ebp+arg_8]
  PAGE:004B0225 add eax, 0FFFh
  PAGE:004B022A and eax, 0FFFFF000h
  PAGE:004B022F push eax
  PAGE:004B0230 call ">_MiFindEmptyAddressRangeDownTree@20 ; MiFindEmptyAddressRangeDownTree(x,x,x,x,x)
  PAGE:004B0235 test eax, eax
  PAGE:004B0237 mov [ebp+arg_C], eax
  PAGE:004B023A jl loc_5267A5
  
  关键是这里
  PAGE:004B4A0A loc_4B4A0A: ; CODE XREF: MiCreatePebOrTeb(x,x,x)+66j
  PAGE:004B4A0A mov edi, _MmHighestUserAddress
  ;总是7FFEFFFF
  PAGE:004B4A10 lea eax, [ebp+var_C]
  PAGE:004B4A13 push eax
  PAGE:004B4A14 add edi, 0FFFF0001h
  ;此时edi为7FFE0000
  PAGE:004B4A1A call _KeQueryTickCount@4 ; KeQueryTickCount(x)
  PAGE:004B4A1F mov eax, [ebp+var_C]
  PAGE:004B4A22 and eax, 0Fh
  ;只取最后一个字节的值,比如此时为0C 网管联盟bitsCN_com
  PAGE:004B4A25 cmp eax, 1
  ;看eax此时是不是为01
  PAGE:004B4A28 mov [ebp+var_C], eax
  PAGE:004B4A2B jbe loc_4B4928
  ;如果是就跳到去处理
  
  PAGE:004B4A31 loc_4B4A31: ; CODE XREF: MiCreatePebOrTeb(x,x,x)+4792j
  PAGE:004B4A31 shl eax, 0Ch
  PAGE:004B4A34 sub edi, eax
  PAGE:004B4A36 lea eax, [edi+0FFFh]
  PAGE:004B4A3C push eax
  PAGE:004B4A3D push edi
  PAGE:004B4A3E push ebx
  PAGE:004B4A3F mov [ebp+var_4], edi
  
  PAGE:004B4928 loc_4B4928: ; CODE XREF: MiCreatePebOrTeb(x,x,x)+488Fj
  如果eax为1,那么就更改为2.这样避免最后计算出来为7FFDF000.而是为7FFDE000
  PAGE:004B4928 push 2
  PAGE:004B492A pop eax
  PAGE:004B492B mov [ebp+var_C], eax
  PAGE:004B492E jmp loc_4B4A31
  
  因为KeTickCount是进程的一个时间计数,所以无法预测。
  
  .text:0041CAA8 mov edi, edi
  .text:0041CAAA push ebp
  .text:0041CAAB mov ebp, esp
  .text:0041CAAD mov ecx, _KeTickCount.High1Time
  .text:0041CAB3 mov eax, [ebp+arg_4] 中国网管联盟bitsCN.com
  .text:0041CAB6 mov [eax+4], ecx
  .text:0041CAB9 mov edx, _KeTickCount.LowPart
  .text:0041CABF mov [eax], edx
  
  经过上面的分析我们知道,如果如果eax随机出来是1,2,那么最后分配的PEB的地址都是7FFDE000,这是为了避免以前的7FFDF000地址的出现,使得以前的堆利用代码都失效。
  
  1,2 7FFDE000
  3 7FFDD000
  4 7FFDC000
  5 7FFDB000
  6 7FFDA000
  7 7FFD9000
  8 7FFD8000
  9 7FFD7000
  A 7FFD6000
  B 7FFD5000
  C 7FFD4000
  D 7FFD3000
  E 7FFD2000
  F 7FFD1000
  0 7FFDE000
  
  上面列出了可以看到PEB的所有可能值,可以看到7FFDE000的概率最高,1/8,其他都是1/16。:),但即使这样,也没法稳定利用了。
  
  2、对TOP SEH的保护
  
  微软对函数SetUnhandledExceptionFilter的代码进行了重大的调整。SetUnhandledExceptionFilter是kernel32.dll中导出的一个函数,用来设置一个筛选器异常处理回掉函数,这个回掉函数不替换系统默认的异常处理程序,而只是在它前面进行了一些预处理,操作的结果还是会送到系统默认的异常处理程序中去,这个过程就相当于对异常进行了一次筛选。

网管联盟bitsCN_com


  
  函数的SetUnhandledExceptionFilter调用方式为:
  LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(
  LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
  );
  
  这个函数唯一的一个参数就是需要设置的回调函数的地址,返回值为上一次设置的回掉函数的地址。该函数不是在原来的回掉函数前再挂一个回掉函数,而是用这个新的回掉函数替换原来的那个回掉函数。如果地址参数被指定为NULL,那么系统将去掉这个“筛子”而直接将异常送往默认的异常处理程序。winXP SP2对这个函数做了重大的改变,在替换原来的回掉函数之前,首先会先对新的回掉函数的地址进行

TAGs进行   保护   漏洞   溢出   函数   eax   ebp   地址   处理   ebx    
 上一篇:对Windows XP SP2溢出漏洞进行保护(下)   下一篇:WINXP系统安全漏洞大搜索
对Windows XP SP2溢出漏洞进行保护(上) 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: