袁哥
由于GetName里面长度计算错误,可以向长度限制0x101的缓冲多覆盖(0x3f+1)/2+1=0x21字节,造成缓冲溢出,
ms04006代码逆向
。但因为调用GetName的代码的缓冲的问题,最多覆盖0x101+0x21=0x122字节,不能覆盖ebp和eip,所以微软认为不能利用,可以参见ms04-006的描述。04年研究别的漏洞的时候发现了此漏洞,但发觉已经被修补,看公告微软说不能写利用,稍加研究就成功的写出了完美和谐的利用。
后来构思写《溢出编写高级技巧---你能控制什么?》把ms04-006和ms08-067作为经典案例。但一直觉得还没到放这些东西的时候就一直没有写出来。
VOID GetName( IN OUT LPBYTE *pName,
IN OUT LPBYTE Name,
OUT LPDWORD NameLen
)
{
int Length;
int MaxLen = 0x101;
int nbtlen;
*NameLen = 0;
if (( *pName &0xc0) != 0) goto error;
Length = *pName &0x3f;
pName++;
nbtlen=(Length+1)/2;
while(nbtlen > 0 )
{
Length -= 2;
*Name++ =(((*pName ++- A)<< 4) | (*pName ++ - A));
(*NameLen)++;
nbtlen--;
}
MaxLen -= Length;
/*
bug!
Length=0 or Length=-1?
MaxLen -= (*NameLen);
*/
while(TRUE)
{
...
}
if (--MaxLen >= 0) {
*Name++ = 0;
} else {
goto error;
}
(*NameLen)++;
return;
error:
WinsEvtLogEvt(...);
RaiseException(...);
return;
}
0:000> uf NmsMsgfProcNbtReq
wins!NmsMsgfProcNbtReq:
01011abe 55 push ebp
01011abf 8bec mov ebp,esp
01011ac1 6aff push 0FFFFFFFFh
01011ac3 6850210001 push offset wins!`string+0x7c (01002150)
01011ac8 6880280101 push offset wins!_except_handler3 (01012880)
01011acd 64a100000000 mov eax,dword ptr fs:[00000000h]
01011ad3 50 push eax
01011ad4 64892500000000 mov dword ptr fs:[0],esp
01011adb 51 push ecx
01011adc 51 push ecx
01011add 81ec74020000 sub esp,274h
01011ae3 53 push ebx
01011ae4 56 push esi
01011ae5 57 push edi
01011ae6 8965e8 mov dword ptr [ebp-18h],esp
01011ae9 c785bcfeffff01000000 mov dword ptr [ebp-144h],1
01011af3 8365dc00 and dword ptr [ebp-24h],0
01011af7 8b7d0c mov edi,dword ptr [ebp+0Ch]
01011afa 897dd8 mov dword ptr [ebp-28h],edi
01011afd 8365fc00 and dword ptr [ebp-4],0
01011b01 8a5f02 mov bl,byte ptr [edi+2]
01011b04 c1eb03 shr ebx,3
01011b07 83e30f and ebx,0Fh
01011b0a 895de0 mov dword ptr [ebp-20h],ebx
01011b0d 8d470c lea eax,[edi+0Ch]
01011b10 8945d8 mov dword ptr [ebp-28h],eax
01011b13 8945c4 mov dword ptr [ebp-3Ch],eax
01011b16 8d45c8 lea eax,[ebp-38h]
01011b19 50 push eax
01011b1a 8d85c0feffff lea eax,[ebp-140h]
/*
buff, ebp-140
0x101+0x21=0x122
can not rewrite eip ?
*/
01011b20 50 push eax
01011b21 8d45d8 lea eax,[ebp-28h]
01011b24 50 push eax
01011b25 e815020000 call wins!GetName (01011d3f)