首页
社区
课程
招聘
[原创][buuctf刷题记录][ZJCTF 2019]EasyHeap
发表于: 2025-11-26 14:37 3026

[原创][buuctf刷题记录][ZJCTF 2019]EasyHeap

2025-11-26 14:37
3026

先看程序开了哪些保护,开了canary和NX,没有pie,Partial RELRO表明可以修改got表。
图片描述

可以看到有一个menu函数

可以看到是一个菜单题,程序有三个功能,分别是进行创建,编辑,删除操作。

可以看到这个函数会依次遍历heaparray数组,看哪个元素没有分配chunk,找到后,分配一个chunk,chunk大小可以自定义,然后写入内容,注意:heaparray数组的元素存放的是chunk的数据部分的指针。

这个函数则根据用户输入的索引(从0开始),修改chunk的数据部分,特别的read_input(*(&heaparray + v1), v2);这里写入内容的大小竟然还是自定义的,所以这里可以覆盖其他chunk的内容

这里根据索引(从0开始)来free,没啥毛病

可以看到main函数里还可以设置menu的选项为4869,如果magic大于0x1305就可以执行l33t函数
图片描述
可以看到会运行cat /home/pwn/flag命令

最初我还以为只要让magic大于0x1305就可以得到flag了。。。结果给我来个该文件不存在,只能找其他方法了
图片描述

图片描述

首先我们先申请两个chunk
图片描述

接着free chunk1,chunk1会被放入fastbin中,可以看到此时这个chunk的fd指针是null
图片描述

接着我们就要覆盖chunk1的fd指针,使其指向bss段,为什么fd指针要设为0x6020ad呢,我们伪造chunk的目的是为了能够修改heaparray的数组元素,那伪造的chunk自然是要在heaparray数组的低地址方向了,可以看到这里magic和heaparray两个变量的地址相差0x20
图片描述
因为fastbin会对chunk的size检查,我们可以把0x7f当成chunk的size,也就是0x60大小,能够覆盖heaparray的内容
图片描述
这个地址是0x6020b5,但是fd指针指向的是chunk的首地址,因此还要减去0x8,也就得到了0x6020ad
图片描述
把fd指针指向了我们想要的地址
图片描述

接着我们两个malloc,分别得到chunk1和freak chunk,数组下标分别是1和2,使得cunk1的内容是/bin/sh\x00,再修改freak chunk使得heaparray[0]的内容是free@got
图片描述
图片描述

既然heaparray[0]已经被我们修改为free@got地址了,那我们可以edit_heap使得该地址内容为system@plt,才可以在调用free函数的时候,反而调用的是system函数
图片描述

最后就是顺理成章,得到shell了
图片描述

参考链接:101K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3K9r3q4H3M7s2W2F1L8%4W2Q4x3V1k6H3i4K6u0r3x3e0j5J5y4K6l9I4y4e0S2Q4x3X3g2Z5N6r3#2D9

int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  char buf[8]; // [rsp+0h] [rbp-10h] BYREF
  unsigned __int64 v5; // [rsp+8h] [rbp-8h]
 
  v5 = __readfsqword(0x28u);
  setvbuf(stdout, 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();
    }
  }
}
int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  char buf[8]; // [rsp+0h] [rbp-10h] BYREF
  unsigned __int64 v5; // [rsp+8h] [rbp-8h]
 
  v5 = __readfsqword(0x28u);
  setvbuf(stdout, 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();
    }
  }
}
int menu()
{
  puts("--------------------------------");
  puts("       Easy Heap Creator       ");
  puts("--------------------------------");
  puts(" 1. Create a Heap               ");
  puts(" 2. Edit a Heap                 ");
  puts(" 3. Delete a Heap               ");
  puts(" 4. Exit                        ");
  puts("--------------------------------");
  return printf("Your choice :");
}
int menu()
{
  puts("--------------------------------");
  puts("       Easy Heap Creator       ");
  puts("--------------------------------");
  puts(" 1. Create a Heap               ");
  puts(" 2. Edit a Heap                 ");
  puts(" 3. Delete a Heap               ");
  puts(" 4. Exit                        ");
  puts("--------------------------------");
  return printf("Your choice :");
}
unsigned __int64 create_heap()
{
  int i; // [rsp+4h] [rbp-1Ch]
  size_t size; // [rsp+8h] [rbp-18h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  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:");
      read_input(*(&heaparray + i), size);
      puts("SuccessFul");
      return __readfsqword(0x28u) ^ v4;
    }
  }
  return __readfsqword(0x28u) ^ v4;
}
unsigned __int64 create_heap()
{
  int i; // [rsp+4h] [rbp-1Ch]
  size_t size; // [rsp+8h] [rbp-18h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  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:");
      read_input(*(&heaparray + i), size);
      puts("SuccessFul");
      return __readfsqword(0x28u) ^ v4;
    }
  }
  return __readfsqword(0x28u) ^ v4;
}
unsigned __int64 edit_heap()
{
  int v1; // [rsp+4h] [rbp-1Ch]
  __int64 v2; // [rsp+8h] [rbp-18h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  unsigned __int64 v4; // [rsp+18h] [rbp-8h]
 
  v4 = __readfsqword(0x28u);
  printf("Index :");
  read(0, buf, 4uLL);
  v1 = atoi(buf);
  if ( (unsigned int)v1 >= 0xA )
  {
    puts("Out of bound!");
    _exit(0);
  }
  if ( *(&heaparray + v1) )
  {
    printf("Size of Heap : ");
    read(0, buf, 8uLL);
    v2 = atoi(buf);
    printf("Content of heap : ");
    read_input(*(&heaparray + v1), v2);
    puts("Done !");
  }
  else
  {
    puts("No such heap !");
  }
  return __readfsqword(0x28u) ^ v4;
}
unsigned __int64 edit_heap()
{
  int v1; // [rsp+4h] [rbp-1Ch]
  __int64 v2; // [rsp+8h] [rbp-18h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  unsigned __int64 v4; // [rsp+18h] [rbp-8h]
 
  v4 = __readfsqword(0x28u);
  printf("Index :");
  read(0, buf, 4uLL);
  v1 = atoi(buf);
  if ( (unsigned int)v1 >= 0xA )
  {
    puts("Out of bound!");

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-11-26 14:56 被G0t1T编辑 ,原因: 补充内容
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回