当函数正在执行内部指令的过程中我们无法拿到程序的控制权,只有在发生函数调用或者结束函数调用时,程序的控制权会在函数状态之间发生跳转,这时才可以通过修改函数状态来实现攻击。
而控制程序执行指令最关键的寄存器就是 eip(还记得 eip 的用途吗?)
所以我们的目标就是让 eip 载入攻击指令的地址。
先来看看函数调用结束时,如果要让 eip 指向攻击指令,需要哪些准备?
首先,在退栈过程中,返回地址会被传给 eip,
所以我们只需要让溢出数据用攻击指令的地址来覆盖返回地址就可以了。
其次,我们可以在溢出数据内包含一段攻击指令,也可以在内存其他位置寻找可用的攻击指令。
核心目的是用攻击指令的地址来覆盖返回地址
再来看看函数调用发生时,如果要让 eip 指向攻击指令,需要哪些准备?
这时,eip 会指向原程序中某个指定的函数,我们没法通过改写返回地址来控制了,不过我们可以“偷梁换柱”--将原本指定的函数在调用时替换为其他函数。
- **修改返回地址,让其指向溢出数据中的一段指令(shellcode)
**
- **修改返回地址,让其指向内存中已有的某个函数(return2libc)
**
- **修改返回地址,让其指向内存中已有的一段指令(ROP)
**
- 修改某个被调用函数的地址,让其指向另一个函数(hijack GOT)
存在栈溢出的危险操作
strcat() 字符串的复制越界复制
gets() 无限制长度输入数据
scanf("%s") 无限制长度输入数据
read(0,buf,xx) xx的大小大于buf本身