控制eip的方法

最近做了一些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 | 上一个栈帧的起始地址