Windows是微软发布的非常流行的操作系统。 Windows的srv.sys驱动处理畸形WRITE_ANDX SMB报文的方式存在内核拒绝服务漏洞,如果未经认证的远程攻击者能够向使用命名管道端点的接口发送WRITE_ANDX报文的话,就可以触发这个漏洞。 Srv.sys是用于处理SMB报文的驱动。报文被解析后,会通过合适的驱动路由。以下是srv.sys解析报文某些重要字段的方式: Módulo: srv.sys Vista SP1 PAGE:00048583 movzx ecx, word ptr [ebx+17h] ; Packet. DataOffset PAGE:00048587 mov [ebp+var_50], ecx PAGE:0004858A mov eax, [esi+78h]; Packet PAGE:0004858D add eax, ecx; Packet.Data[] PAGE:0004858F mov [ebp+VirtualAddress], eax PAGE:00048592 mov eax, [esi+6Ch] PAGE:00048595 mov eax, [eax+10h] PAGE:00048598 sub eax, ecx; Real packet len - DataOffset PAGE:0004859A movzx edi, word ptr [ebx+15h]; Packet.DataLen PAGE:0004859E cmp edi, eax PAGE:000485A0 jbshort loc_485A4 PAGE:000485A2 mov edi, eax 在这部份代码中,驱动应添加检查,以防在偏移与报文真实大小不一致时仍然继续。之后srv.sys构建(或重新使用)FILESYSTE_CONTROL IRP(0xD),其IOCTL为0x119FF8(FSCTL_PIPE_INTERNAL_WRITE, METHOD_BUFFERED),然后通过调用IofCallDriver将这个IRP发送给正确的驱动。IRP包含有报文,但如果考虑到报文的内部字段,这并不意味IRP在内存使用方面保持一致。 Módulo: srv.sys Vista SP1 PAGE:00048C90 pushebx ; int...
Windows是微软发布的非常流行的操作系统。 Windows的srv.sys驱动处理畸形WRITE_ANDX SMB报文的方式存在内核拒绝服务漏洞,如果未经认证的远程攻击者能够向使用命名管道端点的接口发送WRITE_ANDX报文的话,就可以触发这个漏洞。 Srv.sys是用于处理SMB报文的驱动。报文被解析后,会通过合适的驱动路由。以下是srv.sys解析报文某些重要字段的方式: Módulo: srv.sys Vista SP1 PAGE:00048583 movzx ecx, word ptr [ebx+17h] ; Packet. DataOffset PAGE:00048587 mov [ebp+var_50], ecx PAGE:0004858A mov eax, [esi+78h]; Packet PAGE:0004858D add eax, ecx; Packet.Data[] PAGE:0004858F mov [ebp+VirtualAddress], eax PAGE:00048592 mov eax, [esi+6Ch] PAGE:00048595 mov eax, [eax+10h] PAGE:00048598 sub eax, ecx; Real packet len - DataOffset PAGE:0004859A movzx edi, word ptr [ebx+15h]; Packet.DataLen PAGE:0004859E cmp edi, eax PAGE:000485A0 jbshort loc_485A4 PAGE:000485A2 mov edi, eax 在这部份代码中,驱动应添加检查,以防在偏移与报文真实大小不一致时仍然继续。之后srv.sys构建(或重新使用)FILESYSTE_CONTROL IRP(0xD),其IOCTL为0x119FF8(FSCTL_PIPE_INTERNAL_WRITE, METHOD_BUFFERED),然后通过调用IofCallDriver将这个IRP发送给正确的驱动。IRP包含有报文,但如果考虑到报文的内部字段,这并不意味IRP在内存使用方面保持一致。 Módulo: srv.sys Vista SP1 PAGE:00048C90 pushebx ; int PAGE:00048C91 pushebx ; int PAGE:00048C92 pushebx ; int PAGE:00048C93 pushebx ; int PAGE:00048C94 pushedi ; int PAGE:00048C95 push[ebp+VirtualAddress] ; int PAGE:00048C98 push119FF8h ; int PAGE:00048C9D push0Dh ; char PAGE:00048C9F pushesi ; int PAGE:00048CA0 mov eax, [ebp+FileInformation] PAGE:00048CA3 pushdword ptr [eax+38h] ; FileObject PAGE:00048CA6 pushdword ptr [esi+80h] ; Irp PAGE:00048CAC call_SrvBuildIoControlRequest@44 ; SrvBuildIoControlRequest(x,x,x,x,x,x,x,x,x,x,x) PAGE:00048D23 mov edx, [esi+80h] PAGE:00048D29 mov ecx, [ebp+var_44] PAGE:00048D2C callds:__imp_@IofCallDriver@8 ; IofCallDriver 这个IRP由npfs!NpCommonFileSystemControl处理。 Módulo: npfs.sys Vista SP1 PAGE:0001885C loc_1885C:; CODE XREF: NpCommonFileSystemControl(x,x)+E7 j PAGE:0001885C cmp eax, 119FF8h PAGE:00018861 jzshort loc_18896 PAGE:00018896 loc_18896:; CODE XREF: NpCommonFileSystemControl(x,x)+139 j PAGE:00018896 lea eax, [ebp+var_C] PAGE:00018899 pusheax PAGE:0001889A pushedx PAGE:0001889B push[ebp+Irp] PAGE:0001889E call_NpInternalWrite@12 ; NpInternalWrite(x,x,x) 在这个例程中,到达npfs!NpWriteDataQueue可能触发bug。 Npfs从列表获得包含有某些与连接相关的尚未完成IRP的项。 Módulo: npfs.sys Vista SP1 PAGE:0001A187 pushesi PAGE:0001A188 push[ebp+arg_0] PAGE:0001A18B call_NpGetNextRealDataQueueEntry@8 ; NpGetNextRealDataQueueEntry(x,x) 驱动对检索到的项执行检查。由于这个检查,无法在memcpy调用中触发溢出: Módulo: npfs.sys Vista SP1 loc_1A1F6:; CODE XREF: NpWriteDataQueue(x,x,x,x,x,x,x,x,x,x)+92 j PAGE:0001A1F6 mov ecx, [ebx]; Packet.DataLen PAGE:0001A1F8 cmp ecx, edi;Entry.BufferLen ( 0x400 ) PAGE:0001A1FA jnb short loc_1A1FE PAGE:0001A1FC mov edi, ecx PAGE:0001A1FE PAGE:0001A1FE loc_1A1FE:; CODE XREF: NpWriteDataQueue(x,x,x,x,x,x,x,x,x,x)+A0 j PAGE:0001A1FE cmp dword ptr [eax+10h], 1 PAGE:0001A202 jzshort loc_1A22D PAGE:0001A204 testedi, edi PAGE:0001A206 jbe short loc_1A22D PAGE:0001A208 push5246704Eh ; Tag PAGE:0001A20D pushedi ; NumberOfBytes PAGE:0001A20E push0 ; PoolType PAGE:0001A210 call ds:__imp__ExAllocatePoolWithTag@12 ; ExAllocatePoolWithTag(x,x,x) 换句话说,对于任何memcpy可能拷贝的字节数,都会动态分配相同数量的字节数。因此,无法强制溢出的情况。 最后是触发bug的代码段: PAGE:0001A23E push edi ; size_t PAGE:0001A23F mov eax, [ebp+arg_8] ; &Packet + Packet.DataOffset PAGE:0001A242 sub eax, [ebx] ; (&Packet + Packet.DataOffset) Packet.DataLength PAGE:0001A244 add eax, [ebp+arg_C] ; &Packet + (Curr