缓冲区溢出攻击 缓冲区溢出图解
1.C++程序运行时栈分析
网上关于C++程序运行时的栈解析文章有很多,在这里简单介绍一下,方便后续操作的理解与学习。
运行时栈
从网上盗了个图,画的还是比较生动的。。上图中EBP代表栈底指针,ESP代表栈顶指针,EIP代表程序执行的下一个位置,我们可以用一个例子来解释一下这几个东西东西都是干什么的,比如程序
示例程序
首先运行程序,程序运行后,我们定义了两个变量a和b,这时a与b变量的指针被压入栈,a和b变量的语句定义完后,下面改调用方法fun()了,这时候需要把下一条指令的地址提前入栈,就是上面说的EIP,也就是说此时的EIP 等价于图片中的"return 0"语句的地址,这样当方法fun执行完后,就可以继续运行了。
调用方法fun后,EBP从main方法的首地址变更为fun方法的首地址,ESP同理指向EBP,而后开启了fun方法的新栈,fun方法执行完栈顶元素即为EIP,直接执行EIP地址的指令即可完成程序运行。
2.缓冲区溢出攻击原理
上面说了一下C++指令的执行栈,这和本文要说的溢出攻击有什么关系呢?此时提醒大家应该特别注意EIP,因为当方法执行完以后,弹出的数据会交给EIP,也就是下一条要执行的指令,如果EIP的值可以被修改成我们想要执行的指令地址,比如说想要拿到这台机器的ROOT权限,然后你懂的。。
NO ONE IS SAFE
那么问题来了,怎么覆盖EIP??
哦,不小心说出来了,没错,就是覆盖EIP。怎么覆盖?
BUG 程序实例
如上图所示,定义一个16字节空间的buffer数组,那么入栈16字节,strcpy就是把str指针指向的数组空间copy到buffer中,那如果str太多了呢?超过16字节呢?那么也要copy过来(win32),那多了copy到哪里?往高地址copy,为了达到我们的目的,一直让他copy到EIP那里就好了,然后最后修改EIP让它在方法退出以后执行我们想要做的事,这就是缓冲区溢出的攻击原理