MS06-040(CVE-2006-3439)静态分析

微软06年爆出的Server服务器栈溢出导致的远程代码执行漏洞,标记为严重,编号CVE-2006-3439

根据前辈们的总结,这个溢出漏洞发生在netapi32.dll的NetpwPathCanonicalize()导出函数中

Idapro载入netapi32.dll文件,来到缺陷函数处

Call sub_7517FC68就是存在缓冲区溢出的函数位置

首先这个函数中有2个局部变量,5个参数

程序首先比较参数source是否为0,然后将ebx赋值为0x411

当source不为0时,call wcslen获取source长度,此处长度为wcslen编码 unicode字符的长度,然后看是否为0,通常source是不为0的

之后比较cmp esi,ebx 其中ebx = 0x411,但是比较的是宽字符的0x411,也就是0x822字节长度,而分配的空间是0x414字节,所以source存在可能构造处0x822字节内的缓冲区,然后wscpy()拷贝操作来触发溢出

然而在call sub_7517FC68之前,source的长度被设置做了很大限制

ebx表示的就是source,作为参数lpWideCharStr被函数NetpwPathType调用

从汇编代码中可以看到,参数source(lpWideCharStr)赋值给esi,调用wcslen()计算宽字符unicode长度,然后cmp eax, 103h与103进行比较,因为是unicode编码,所以source的长度需要满足 len(source) <= 206,所以在之后call sub_7517FC68函数中,小于分配的空间0x414,不可能构造缓冲区来触发溢出,参数source出局

另一个参数str,依然wcslen()计算unicode长度,然后加上esi的值,此时esi的值为source的unicode长度加上拼接的路径连接符’\’后总的长度值,有个inc esi的操作,合到一起得到esi = len(source)+1+len(str),然后cmp eax, ebx而ebx = 0x411,也就是说宽字符小于等于0x411就可以,即通过拼接source和str可以控制的范围为0x822字节,大于0x414字节大小缓冲区,之后调用wcscat()字符串连接,这样可能存在缓冲区溢出的风险

这个函数在msdn上没有api介绍,根据前辈的总结,此函数的功能是格式化网络路径字符串,是个unicode字符串处理函数

int NetpwPathCanonicalize (
uint16  path[ ], // [in]  path name
uint8  can_path[ ],  // [out]  canonicalized path
uint32  maxbuf, //  [in]  max size of can_path
uint16  prefix[ ],  //  [in]  path prefix
uint32*  pathtype, //  [in out] path type
uint32  pathflags //  [in]  path flags, 0 or 1
);

大概功能就是如果 prefix 串非空,将 prefix 串与 path串用‘\’相连,并复制到输出串 can_path 中,输出串的容量为 maxbuf 字节大小:

prefix + ‘\’ + path => can_path [max_buf]

您可能还喜欢...