首页 -> 安全研究

安全研究

绿盟月刊
绿盟安全月刊->第7期->技术专题
期刊号: 类型: 关键词:
句柄范围检测漏洞

作者:袁哥 yuange@163.net
日期:2000-05-23

WIN95、WIN98共享服务是通过SMB协议实现的,其程序实现中有很多处漏洞。服务端有我原来分析的共享密
码校验漏洞、NMPI攻击死机等,客户端有文件驱动错误死机、当前用户密码泄露等多处漏洞,现在又发现服务端
接收客户端的文件句柄没有很好的检测范围,可以导致死机甚至可能恶意用户获得整个文件系统的控制权等。
下面是文件vserver.vxd相关处理模块分析。

13AC0 00000000 data_0483 dd 00000h
13AC4 0FFC[00] db 4092 dup (0)
14AC0 00 data_0484 db 0
14AC1 03FF[00] db 1023 dup (0)
14EC0 sub_0350 proc near
14EC0 55 push ebp
14EC1 8B EC mov ebp,esp
14EC3 53 push ebx
14EC4 56 push esi
14EC5 57 push edi
14EC6 8B 75 10 mov esi,dword ptr [ebp+PARAMETER_3]
14EC9 0B F6 or esi,esi
14ECB 7F 0B jg short loc_2057
14ECD B8 FFFFFFFF mov eax,0FFFFFFFFh
14ED2 5F pop edi
14ED3 5E pop esi
14ED4 5B pop ebx
14ED5 C9 leave
14ED6 C3 retn
data_0483是接收客户端的文件句柄与系统真实的文件句柄数据的转换指针,一个变量为四字节,data_484是
这文件句柄的分配情况还是什么。后面显然不是数据已经是程序了。这儿大致就相当于:
dword file_handle[0x400];
bye file_handle_flg[0x400];
所以能接收客户端的的文件句柄范围是0-0x3ff,其实vserver.vxd中有程序可以看出这范围,下面程序的018c6
就是在比较范围大于等于0x400就跳到loc_0186返回错误60001h,否则相应处理。

018B8 sub_0008 proc near
018B8 C1 E0 10 shl eax,10h
018BB 83 7E 2C 00 cmp dword ptr [esi+2Ch],0
018BF 74 05 je short loc_0180
018C1 8B 4E 2C mov ecx,dword ptr [esi+2Ch]
018C4 EB 14 jmp short loc_0181
018C6 loc_0180:
018C6 81 F9 00000400 cmp ecx,400h
018CC 73 57 jae short loc_0186
018CE 8B 0C 8D 00013AC0 mov ecx,dword ptr data_0483[ecx*4]
018D5 89 4E 2C mov dword ptr [esi+2Ch],ecx
018D8 E3 4B jecxz short loc_0186
018DA loc_0181:
018DA 80 79 19 01 cmp byte ptr [ecx+19h],1
018DE 75 45 jne short loc_0186
018E0 66| 8B 42 18 mov ax,word ptr [edx+18h]
018E4 66| 39 41 14 cmp word ptr [ecx+14h],ax
018E8 75 2D jne short loc_0185
018EA 39 79 0C cmp dword ptr [ecx+0Ch],edi
018ED 75 28 jne short loc_0185
018EF 8A 41 18 mov al,byte ptr [ecx+18h]
018F2 A8 02 test al,2
018F4 74 36 jz short loc_0188
018F6 A8 80 test al,80h
018F8 75 46 jnz short loc_0189
018FA 80 79 33 00 cmp byte ptr [ecx+33h],0
018FE 75 01 jne short loc_0182
01900 C3 retn
01901 loc_0182:
01901 C1 E0 0F shl eax,0Fh
01904 78 10 js short loc_ret_0184
01906 0F B6 41 33 movzx eax,byte ptr [ecx+33h]
0190A 72 04 jc short loc_0183
0190C C6 41 33 00 mov byte ptr [ecx+33h],0
01910 loc_0183:
01910 C1 E0 10 shl eax,10h
01913 B0 01 mov al,1
01915 F9 stc
01916 loc_ret_0184:
01916 C3 retn
01917 loc_0185:
01917 A9 00020000 test eax,20000h
0191C 75 07 jnz short loc_0186
0191E E8 00000049 call sub_0010
01923 72 06 jc short loc_ret_0187
01925 loc_0186:
01925 B8 00060001 mov eax,60001h
0192A F9 stc
0192B loc_ret_0187:
0192B C3 retn


可是此文件中很多地方接收客户端的文件句柄的范围检查却有点让人摸不着头脑。下面是处理SMBfindclose的一段程序:

;SMB COMMAND 34H SMBfindclose Terminate a TRANSACT2_FINDFIRST  
0D19C loc_1574:
  0D19C 8B 4E 24  mov ecx,dword ptr [esi+24h]
0D19F 0F B7 59 01  movzx ebx,word ptr [ecx+1] ;
;客户端发过来的文件句柄
0D1A3 80 E7 1F  and bh,1Fh
;范围处理,那么ebx<=1fffh,不知道为什么?应该是 and bh,3h ? 
;BUG .THE FILE HANDLE MUST < 400H

0D1A6 66| 8B 6A 18  mov bp,word ptr [edx+18h]
0D1AA 8A 93 00014AC0  mov dl,byte ptr data_0484[ebx] ; (14AC0=0)
0D1B0 8B 1C 9D 00013AC0 mov ebx,dword ptr data_0483[ebx*4] ; (13AC0=0)
;得到句柄转换指针
0D1B7 85 DB test ebx,ebx
0D1B9 74 77 jz short loc_1577 ; Jump if zero
0D1BB 39 7B 0C cmp dword ptr [ebx+0Ch],edi
;ebx+0ch是此句柄拥有者数据结构的指针,edi是当前用户的数据结构指针。
;判断这句柄是不是当前用户拥有,不是转错误,是就做关闭处理。
;前面由于句柄超出范围,所以得到的句柄指针就可能指向不知道什么地方,如果指向地方无内存读权限,
;那么这儿就会出来WINDOWS中常见的非法错误。如果有此内存读权限,一般会因为内容不等于edi
;而转错误返回。但如果那刚好等于edi(可能不太好让这条件满足),那么后面将会关闭句柄,会在
;data_0483[ebx*4]写入0等,所以可能利用这达到更多的目的.
0D1BE 75 72 jne short loc_1577
0D1C0 8A 71 02 mov dh,byte ptr [ecx+2]
0D1C3 C0 EE 05 shr dh,5
0D1C6 80 E2 07 and dl,7
0D1C9 3A F2 cmp dh,dl
0D1CB 75 65 jne short loc_1577
0D1CD 66| 39 6B 14 cmp word ptr [ebx+14h],bp
0D1D1 75 5F jne short loc_1577
0D1D3 80 7B 19 02 cmp byte ptr [ebx+19h],2
0D1D7 75 59 jne short loc_1577
0D1D9 8B CB mov ecx,ebx
0D1DB 8B 51 1C mov edx,dword ptr [ecx+1Ch]
0D1DE 80 61 18 80 and byte ptr [ecx+18h],80h
0D1E2 E8 FFFF49A5 call sub_0014
0D1E7 80 79 18 00 cmp byte ptr [ecx+18h],0
0D1EB 75 2E jne short loc_1576
0D1ED 8B 41 48 mov eax,dword ptr [ecx+48h]
0D1F0 85 C0 test eax,eax
0D1F2 74 0B jz short loc_1575
0D1F4 51 push ecx
0D1F5 52 push edx
0D1F6 50 push eax
0D1F7 E8 FFFFBB15 call sub_0144 
0D1FC 5A pop edx
0D1FD 5A pop edx
0D1FE 59 pop ecx
0D1FF loc_1575:
0D1FF E8 FFFF48B0 call sub_0012
;关闭句柄,会在data_483[ebx*4]写入0等
0D204 8B C2 mov eax,edx
0D206 57 push edi
0D207 2B FF sub edi,edi
0D209 E8 FFFFFA10 call sub_0243 
0D20E 5F pop edi
0D20F 8B 35 000128B8 mov esi,dword ptr data_0379
0D215 0F 82 FFFF2E11 jc loc_0004
0D21B loc_1576:
0D21B 8B 5E 28 mov ebx,dword ptr [esi+28h]
0D21E C6 03 00 mov byte ptr [ebx],0
0D221 66 C7 43 01 0000 mov word ptr [ebx+1],0
0D227 8D 43 03 lea eax,dword ptr [ebx+3]
0D22A 89 46 28 mov dword ptr [esi+28h],eax
0D22D E9 FFFF2F02 jmp loc_0021
0D232 loc_1577:
0D232 B8 00060001 mov eax,60001h
;设置错误返回码
0D237 E9 FFFF2DF7 jmp loc_0005
;跳到错误处理模块


   其实WINNT、WIN2000系统的共享服务服务端、客户端也有很多漏洞,以后再慢慢分析吧。


版权所有,未经许可,不得转载