栈迁移
1.为什么需要栈转移?
- 在栈空间不够存放payload的情况下,需要一个新的地址空间存放payload
- 开启PIE保护,栈地址未知,我们可以将栈劫持到已知的区域
2.概念
- 劫持栈的rsp(ESP),使其指向其他位置,形成一个伪造的栈,在此栈中做ROP
3.必要的gadget
- pop ebp;ret 释放EBP,并连接伪造的栈
- leave;ret 更改ESP,指向后续的payload
4.原理
- 通过 pop ebp;ret + 伪造的栈让程序直接跳转到伪造的栈里面,然后为了保持栈平衡,从而执行 leave ;ret,最后继续执行伪造栈内的payload
5.图示
1. 函数调用以及恢复的汇编代码
- 程序在调用函数时,会通过栈进行现场保护的工作,在调用函数时,会将当前的基址压入栈,再将基址ebp 改为 当前esp的地址,而程序在返回的时候,需要通过leave retn指令恢复现场,也就是恢复调用者的esp以及ebp
2. 利用方法
- 利用leave ret 指令,将栈转移到fake stack
- paylaod = padding (溢出到ebp之前)+ fake ebp(覆盖原本的ebp) + leave retn(执行栈的迁移)
5.过程
- 使用输入函数(如read),将后续的payload加载到bss段内,也就是伪造的栈
- 通过 pop ebp;ret | pop ebx;ret 来调整EBP寄存器
- 通过 leave ret; 来更改 ESP,使其指向伪造的栈
- 然后在伪造的栈中执行下一段ROP