最近做了一些pwnable上的题,得到了一些微小的结论,特意与大家分享一下。
1、控制eip能够做什么
一般而言,作为pwn手小白,最希望的就是控制eip了,而控制eip究竟能做什么呢?
控制eip,相当于就控制了程序的执行流程,从而获得了程序的最高权限,甚至能够绕过操作系统上的安全限制,直接获取用户shell或进行破坏性操作。
而如果我们能够控制ctf题目中的eip,我们会进行怎样的操作呢?
- 如果程序有shell地址,直接跳转至shell地址处,获得shell
- 如果程序没有shell,我们能够构造rop链,一步步地更改寄存器、填充栈中值。最后也是获取shell
- 如果程序NX保护没开,就可以直接跳转至栈中进行shellcode执行
- 如果某个具有可执行地址段被写入了shellcode,我们也可以跳转至此获取shell
2、如何控制eip
2.1 通过修改返回地址控制eip
一般通过栈溢出的方式、堆溢出造成的任意地址写功能、程序自身逻辑造成的任意地址写等错误来修改返回地址
retn指令本来就是pop eip,如果能够在函数返回之前,将ret_addr替换为你想其执行的地址,就能够控制eip
0xffffffe4| ebp |
0xffffffe8| ret_addr |
2.2 通过栈迁移的方式控制eip
所谓栈迁移,就是由于程序中有ebp,进而可以在程序返回后进入上一个栈帧中。
如果我们能够控制ebp中的值(也即控制[\$ebp]),那么在栈帧迁移的时候(也就是在leave ret指令执行的时候),我们就控制了[[\$ebp]+0x4]的值,而这个值实际上是上一个栈帧的返回地址。然后上一个栈帧在返回的时候,就控制了eip
0xfffffee4 | 0xffffffe4 |
0xfffffee8 | ret_addr | 此栈帧
……
0xffffffe0 | | 上一个栈帧
0xffffffe4 | ebp | 上一个栈帧的起始地址