经典栈溢出利用详解一例—Notepad++插件CCompletion

Posted Tishion

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典栈溢出利用详解一例—Notepad++插件CCompletion相关的知识,希望对你有一定的参考价值。

标 题: 经典栈溢出利用详解一例—Notepad++插件CCompletion
时 间: 2014-02-23,21:08:51

回顾
  上篇文章介绍了Noetpad++程序中的一个插件CCompletion存在的一个因使用不安全的lstrcpyW函数拷贝字符串造成的栈溢出漏洞,并且确定了漏洞的大致利用入口,已经找到了可控EIP数据在整个输入数据中的精确位置,但是如果要写出可以利用的Shell Code还需是需要费一番功夫去调试和修正的。这篇文章就按照前面所说的那个漏洞的利用入口来详细的介绍一个可用Shell Code的构造过程。

Shell Code框架构造
  首先要回想一下我们已知的漏洞情况,还记得可控EIP的精确位置么?
我们构造的数据的0x00000430个字节处的一个DWORD值就是我们可控EIP的值。
这里利用一个简单的数据布局图来说明一下:
  Name:  image001.pngViews: 1Size:  100 KB
  P1:静态数据布局

上图中整个数据块就是我们将要输入到Notepad中的数据,其中在偏移0x430处的一个四字节DWORD值在漏洞触发时候将会被程序通过ret指令取出来弹入EIP寄存器,这时候程序流程就会转向到EIP的值,而ESP的值会变成内存中对应于0x00000434处偏移的栈地址,然后程序会从0xXXXXXXXX处开始执行。

知道这个过程之后我们就可以开始构建Shell Code的框架了。首先考虑一点上图中0xXXXXXXXX值我们应该设置为什么值?这个是一般栈溢出利用的一个敲门砖,非常重要,我们的目的是让程序的执行流程进入我们构造的Shell Code并且正确执行,所以很容易想到,这个值就直接设置成我们的Shell Code所在的地址不就行了么,比如把Shell code的真正内容防止在上图中的0x00000434处开始,然后直接把EipValue设置成0x00000434,这个错误就太明显了……因为栈的内存地址并不一定是永远不变的,虽然有些程序每次运行的时候栈地址都相同,所以我们写Shell Code的时候应该尽量避免这种于Shell Code自身地址的HardCode。所以我们应该像一个更好的方法来让程序流程进入我们的ShellCode中。稍微学习过这方面的知识的同学应该都知道jmp esp方法,这种方法相对HardCode EIP值的方法确实优雅了不少。这种方法可以用下图来展示:
 
Click image for larger versionName:	image002.pngViews:	21Size:	280 KBID:	87434
P2:通过JMP ESP方法跳转

上图应该很清楚的说明了JMP ESP的用法了,所以我们要做的就是在偏移0x430处放置一个地址,这个地址所指向的内存中存在一条jmp esp指令,那这个地址放什么?一般的做法是在系统自带的且进程必须的几个dll中搜索出包含这条指令的地址,比如Kernle32.dll,ntdll.dll等。比如我们可以在Kernel32.dll中搜索: