return(NULL);
}
//……
}
在实际程序中的反汇编代码如下:
nt!IopAllocateErrorLogEntry:
8081b4a8 8bff mov edi,edi
8081b4aa 55 push ebp
8081b4ab 8bec mov ebp,esp
8081b4ad 53 push ebx
8081b4ae 33db xor ebx,ebx
8081b4b0 8a5d10 mov bl,byte ptr [ebp+10h]
8081b4b3 80fb30 cmp bl,30h ;30h是 IO_ERROR_LOG_PACKET的大小
8081b4b6 56 push esi
8081b4b7 57 push edi
8081b4b8 723e jb nt!IopAllocateErrorLogEntry+0x50 (8081b4f8)
8081b4ba 80fb98 cmp bl,98h ; ERROR_LOG_MAXMUM_SIZE 的大小
8081b4bd 7739 ja nt!IopAllocateErrorLogEntry+0x50 (8081b4f8)
……
(退出部分)
8081b4f8 33c0 xor eax,eax
8081b4fa 5f pop edi
8081b4fb 5e pop esi
8081b4fc 5b pop ebx
8081b4fd 5d pop ebp
8081b4fe c20c00 ret 0Ch
所以这里就说明,IoAllocateErrorLogEntry 的最大空间只能是 98h,另外 98h 的大小
中,有 28h 的是属于ERROR_LOG_ENTRY结构(不过这个和 WRK 中描述有点差异,这里不关心
它,也不重要),70h属于存储错误宽字符串的结构..
这里的 70h 就是死限了,攻击者就是利用这个 70h 的大小限制实行攻击的。先看
mrxsmb!BowserWriteErrorLogEntry的一段汇编代码:
(与两个宽字符串总长度经过修正的值相比较,长度大于的时候)
f9373b0e 8b45fc mov eax,dword ptr [ebp-4]
f9373b11 d1e8 shr eax,1
f9373b13 48 dec eax ;计算剩余空间(以 CHAR 计算)减去结束
符"\x00"之后的长度
(与两个宽字符串总长度经过修正的值相比较,长度小于的时候)
f9373b14 85c0 test eax,eax
f9373b16 7639 jbe mrxsmb!BowserWriteErrorLogEntry+0x1a5
(f9373b51);处理的长度小于0 也会跳转
(长度小于且不为零,否则会跳转到失败)
[注意,这就是问题,条件判断不等于0 的时候,此时就有可能值是负数,也是漏洞利
用的地方]
f9373b18 8d0c00 lea ecx,[eax+eax] ;仅仅计算宽字符数据长度,不
计算上"\x00\x00"长度的时候
f9373b1b 8bd1 mov edx,ecx
f9373b1d c1e902 shr ecx,2
f9373b20 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
f9373b22 8bca mov ecx,edx |