栈平衡和栈转移(Stack

栈平衡和栈转移(Stack

栈平衡为什么要堆栈平衡因为要保持栈的大小,使ESP始终指向栈顶

概念函数如果要返回父程序,则在堆栈中进行操作的时候,一定要在RET指令之前,将ESP指向函数压入栈中时的地址如果通过堆栈传递参数了,那么在函数执行完毕后,要平衡参数导致的堆栈变化代码示意代码语言:javascript复制//ESP 为 NN

push p2 //ESP=NN-4

push p1 //ESP=NN-8

call test //ESP=NN-0C

{ //进入函数内

push ebp //ESP=NN-10

mov ebp, esp //EBP 指向 栈顶 EBP==当前ESP

mov eax, dword ptr [ebp+0ch] //eax = 参数2

mov ebx, dword ptr [ebp+08h] //ebx = 参数1

sub esp, 8 //ESP == NN-18

...

add esp, 8 //ESP== NN-10

pop ebp //ESP==NN - C

ret 8 //ESP==NN + 4 +8

}

//ESP = NN总结也就是说当函数在栈中操作时,需要先把ESP 转交给EBP ,然后继续操作,当操作完后,在ret之前,要先将ESP恢复成进入栈前的状态(进入栈后每次压入参数都会使栈空间一点点变小,而因为ESP要始终指向栈顶的原因,所以要把它恢复成原来的大小。)最后再将EBP移除栈,这样就是一个简单的栈平衡。

栈转移在栈空间不够存放paylaod的情况下,需要一个新的地址空间来存放payload。开启了 PIE保护,栈地址未知,我们可以将栈劫持到已知的区域。概念劫持栈的rsp(esp),使其指向其他位置,形成一个伪造的栈。这样栈也就被劫持到攻击者控制的内存上去,然后在该位置做ROP。

必要的Gadget pop EBP;ret : 释放EBP,并链接伪造的栈

leave;ret : 更改ESP,指向后续的payload

等价于 mov ESP,EBP; pop EBP; ret;原理栈转移的原理就是以 pop ebp;ret + 伪造的栈 让程序直接跳转到伪造的栈里面,然后为了保持栈平衡,从而执行leave; ret,最后继续执行伪造的栈内的payload

过程使用输入函数(如read)将后续的Payload加载到bss段内,也就是伪造的栈通过pop ebp;ret来调整EBP寄存器pop ebp;ret可以使用pop EBX;ret 来代替通过leave;ret来更改ESP,使其指向伪造的栈(bss)然后在伪造的栈中执行下一段ROP注意使用bss作为stack发动ROP攻击可能会失败这是因为(后续ROP使用的GOT等)必要的变量被破坏,以及跳到stack等原因因为read/write时,系统内的dl_fixup函数对stack做了很好的保护使用的bss段建议在中间区域,如bss+0x800左右参考链接:

https://darkwing.moe/2019/04/15/Pwn学习笔记14-stack-pivot与Off-by-one/

相关推荐

天下手游80弈剑套装如何选择 弈剑套装推荐
365bet安卓手机客户端

天下手游80弈剑套装如何选择 弈剑套装推荐

⌛ 2026-06-18 👁️ 3005
双色球买七加一要多少钱 - 彩票问问
365bet安卓手机客户端

双色球买七加一要多少钱 - 彩票问问

⌛ 2025-08-27 👁️ 3423
梧州旅游十大必吃美食 | 从纸包鸡到冰泉豆浆,寻味西江千年食脉
365bet安卓手机客户端

梧州旅游十大必吃美食 | 从纸包鸡到冰泉豆浆,寻味西江千年食脉

⌛ 2025-07-08 👁️ 1006