发布于

栈对齐

作者

在进行 64-bit 系统上的攻击时,你可能会遇到一个小问题,即使你的攻击脚本看似没问题,但就是不能 get shell。这一问题的根源在于栈对齐。

本质上,x86-64 ABI(应用程序二进制接口)保证了在调用指令上的 16-bits 对齐。libc 利用了这一点,并使用 SSE 数据传输指令来优化执行;特别是在 system 中会使用诸如 movaps 等指令。

这意味着如果栈不是 16-bits 对齐的(即 RSP 不是 16 的倍数),那么在执行 system 时会失败。

修复方法很简单,在你调用 system 之前,插入一个单独的 ret

ret = elf.address + 0x2439

[...]
rop.raw(POP_RDI)
rop.raw(0x4)        # first parameter
rop.raw(ret)        # align the stack
rop.raw(system)

这样做会使 RSP 出栈,向前移动 8-bits,从而实现对齐。

或者你也可以通过给返回地址 +0x1 或更多,跳过一些栈操作指令来对齐栈。

最后:

  • 使用 XMM 寄存器时,需要 16 字节对齐
  • 使用 YMM 寄存器时,需要 32 字节对齐
  • 使用 ZMM 寄存器时,需要 64 字节对齐