MS08_067漏洞学习研究

p197 MS08-067漏洞渗透攻击

按照书上的设置做,exploit得到错误信息:

Exploit failed [unreachable]: Rex::ConnectionRefused The connection was refused by the remote host (10.10.10.130:445).

在2k3下输入netstat -an看到445端口是开着的,而且也没有设置防火墙。

可是在kali 上用nmap 也扫不到445这个端口,奇怪!

(补充:后来就成功了,我也没弄过什么啊。。有点莫名其妙)

 

p205 MS08-067漏洞机理分析:

(每次运行堆栈中的地址会不同,但各函数的地址一样)

首先通过IDA Pro打开c:\windows\system32\netapi32.dll,找到漏洞所在的NetpwPathCanonicalize函数并双击。

书上说通过观察其流程图CFG可知,此函数并没有直接进行输入路径和规范化,而是调用了下级函数CanonicalizePathName。(我并不太会看)

 

打开OllyDbg,点击file->attach,附着到svchost.exe进程上(通过wmic查看命令行参数为svchost.exe -k netsvcs的进程pid)

 

 

view->executable modules双击netapi32,在cpu指令窗口右键选Search for,找到函数NetpwPathCanonicalize,地址为71C44A3E

按照书上说的在此处下了断点,然后点F9运行,从攻击机那里通过metasploit进行exploit。

回到OllyDbg中程序运行到断点,即NetpwPathCanonicalize函数入口处。

查看栈中的参数,结合网上查阅的NetpwPathCanonicalize函数信息可知每个参数的意义。

结合IDA Pro分析可知,NetpwPathCanonicalize函数将在地址0x71C44A9E处调用下级函数CanonicalizePathName。在此处下断点。

按F9继续运行至此断点,然后按F7跟踪函数。查看当前esp内的参数:

esp    [esp]

其意义依次为:

  指向prefix,值为\x5c\x00,即unicode '\'
  指向待整理路径
  指向输出路径的buffer
  输出buffer的长度
  WORD Flag保留字,值为0

从这些参数的意义可以大概知道,CanonicalizePathName函数就是将路径整理后,输出到预先分配的buffer上 。

于是我们研究它对路径做了哪些处理。

在待整理路径000C0F50处下断点。(待整理路径的形如:"\**********\..\..\***")

按F9运行,会中断3次,第三次是在调用msvcrt.dll模块中的wcscat函数。

分析栈中两个参数

第一个是目的地址,指向一段以\x5c\x00开头的内存空间;第二个是源地址,指向上述待整理路径前两字节\x5c\x00后的内容。

因此,程序把待整理路径全部复制到strDestination即0x001572F6处。在此4字节设断点,类型选择"Hardware, on access"Word。

按F9运行,中断多次后停在内存0x77bd4d36处,通过栈可知此处属于wcscpy函数。此处调用该函数进行第一次路径规范化。

这是wcscpy函数的代码:

分析代码可知,此时wcscpy源地址在edx寄存器中:

指向"\..\***"

目的地址在ecx寄存器中:

指向待整理路径第一个字符"\"

可知此次规范化即把待整理路径中第一个字符"\"和第一个"\..\"相对路径之间的内容抛弃。

 

第一次规范化后,待整理路径形如:"\..\***"

由于还有"\..\",还需进行一次规范化。这第二次规范化才是玄机所在。

 

接下来移除0x00F0F4DC处4字节的硬件断点,直接在wcscpy入口地址处下断点。

 

(以下为后续补充,内存地址有所改变)

运行中断后,停在wcscpy函数开头处,栈中为

 

 而栈顶指针ESP为0x00CBF4A8,指向返回地址0x71C52FD4。

 

这就是栈溢出的地方:ESP到dest只有0x14字节,通过向dest写入0x64字节的字符串,则栈上的返回地址会被覆盖掉,变成0x0100129E:

 

 从而跳转到我们构造的字符串上

  

 进而执行shellcode,成功利用漏洞。

 

在攻击中重要的一步是在待整理路径复制到的目的地址前写入一个'\'(0x5c),从而在路径规范化时向前溢出。所以接下来研究这个'\'是怎么写入的。

 

通过断点将程序中断在wcscat函数处,从栈中获得目的地址0x00F0F4DC。

从上文我们分析出最终wcscpy的目的地址,也就是写入'\'的地方,在0x00F0F4DC前0x48的位置处。我们对该内存下写入断点:

 

 关注往此内存写入0x5c的操作,有2处,在同一函数中,如下图所示:

通过Execute till return (Ctrl+F9),可以倒推出函数调用关系:

 

 

 然后我们查阅这些函数的相关信息,从而得知是函数RtlIsDosDeviceName_Ustr函数检查DOS设备,并将设备部分字符串的长度保存到一个局部变量中。

所以通过构造出0x5C的长度,可以达到向指定内存写入'\'的目的。

 

总结

漏洞原理

路径规范化中,会把 "\AB\CD\..\EF" 规范为 "\AB\EF"。

所以若构造出"\(缓冲区之外)\..\**"的路径,则会覆盖掉缓冲区之外的数据,造成向前溢出。

这主要是在复制字符串时缺乏正确的边界检查造成的。

漏洞利用

  1. 构造出以 "\..\" 开头的待整理路径,可以绕过边界检查。
  2. 在缓冲区前面的内存中写入一个 "\" ,从而在路径规范化时覆盖掉这个 "\" 到缓冲区间的内容。
posted @ 2016-03-03 20:20  燃烧少年的心  阅读(8143)  评论(1编辑  收藏  举报