64位



buf 到栈底(ebp)的距离是:0xA,64 位程序加上 8 字节的栈底(rbp)
backdoor函数地址:0x400657
对于 32 位程序来说,现在就能打通了
但是这里是 64 位程序,需要处理堆栈平衡
#堆栈平衡:当我们在堆栈中进行堆栈的操作的时候,一定要保证在ret这条指令之前,esp指向的是我们压入栈中的地址,函数执行到ret执行之前,堆栈栈顶的地址一定要是call指令的下一个地址。
因此我们还需要找一个地址: lev 的地址或者该函数结束的地址(即 retn 的地址)
直接看 backdoor 函数的汇编代码:
lev 的地址:0x40065B
retn 的地址:0x40066D
特别注意:构造 payload 时将该地址放在该函数开始地址之前
from pwn import * |

p64(0x40065B)→ 覆盖返回地址为0x40065Bp64(0x400657)→ 在栈上放置后门函数地址
执行流程
当函数返回时:
- 跳转到
0x40065B(跳过函数开头的push rbp; mov rbp, rsp) - 执行
lea rdi, command→ 设置好system的参数 - 执行
call _system→ 调用system("/bin/sh") - 执行
pop rbp→ 弹出栈顶值到RBP(此时栈顶是0x400657) - 执行
retn→ 弹出栈顶值0x400657到RIP,跳转到后门函数开头
为什么要这样跳转两次?
- 避免栈对齐问题:64位系统要求调用函数时栈指针16字节对齐
- 直接跳转到
0x40065B时,栈指针可能未对齐 - 第二次跳转到函数开头(
0x400657)会执行push rbp,使栈对齐
- 直接跳转到
- 确保参数正确设置:
- 第一次跳转确保
rdi正确设置为"/bin/sh" - 第二次跳转执行完整的
system调用
- 第一次跳转确保
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Rhea's Blog!
评论
