跳过正文
  1. 随笔/

Heap Exploitation

·1181 字·3 分钟·
CTF Pwn
Saurlax
作者
Saurlax
Web, Cloud, AI, IoT, Blockchain, Quantum, and more!
目录

堆概述
#

malloc_chunk 数据结构

allocated chunkfree chunk
prev_size (if previous chunk is free)part of previous chunk
chunk size | N | M | P
user datafd: pointer to next chunk
bk: pointer to previous chunk
unused space

因为 chunk 的大小都是 8 字节对齐的,所以 chunk size 的最低 3 位被用于标志位。

  • N:PREV_INUSE,表示前一个 chunk 是否被分配
  • M:IS_MMAPPED,表示是否是通过 mmap 分配的
  • P:NON_MAIN_ARENA,表示是否是通过非主 arena 分配的

Off-By-One
#

off-by-one 指单字节缓冲区溢出,是一种特殊的缓冲区溢出,通常发生在字符串处理函数中,例如 strcpystrcatgets 等。当输入的字符串长度等于缓冲区长度时,这些函数会将字符串的结尾符 \0 写入缓冲区的末尾,但是由于字符串的长度已经等于缓冲区的长度,所以 \0 将会被写入缓冲区之外的内存,导致缓冲区溢出。

Asis CTF 2016 b00ks

Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      PIE enabled

题目是一个选单图书管理系统,可以创建、删除、编辑、打印图书信息。

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  struct _IO_FILE *v3; // rdi
  int v5; // [rsp+1Ch] [rbp-4h]

  setvbuf(stdout, 0LL, 2, 0LL);
  v3 = stdin;
  setvbuf(stdin, 0LL, 1, 0LL);
  welcome(v3);
  change_name(v3);
  while ( 1 )
  {
    v5 = menu(v3);
    if ( v5 == 6 )
      break;
    switch ( v5 )
    {
      case 1:
        create_book(v3);
        break;
      case 2:
        delete_book(v3);
        break;
      case 3:
        edit_book(v3);
        break;
      case 4:
        print_books(v3);
        break;
      case 5:
        change_name(v3);
        break;
      default:
        v3 = (struct _IO_FILE *)"Wrong option";
        puts("Wrong option");
        break;
    }
  }
  puts("Thanks to use our library software");
  return 0LL;
}

漏洞在于其中自定义的 my_read 函数会在输入的最后多加一个 \0。此时如果后续地址被其他内容填充,会导致 \0 被覆盖。

__int64 __fastcall my_read(_BYTE *ptr, int len)
{
  int i; // [rsp+14h] [rbp-Ch]

  if ( len <= 0 )
    return 0LL;
  for ( i = 0; ; ++i )
  {
    if ( (unsigned int)read(0, ptr, 1uLL) != 1 )
      return 1LL;
    if ( *ptr == 10 )
      break;
    ++ptr;
    if ( i == len )
      break;
  }
  *ptr = 0; // off-by-one
  return 0LL;
}

book 的结构

struct book
{
  int id;
  char *name;
  char *description;
  int size;
}

.bss 段上的结构为

char author name[0x20]
struct book books[]

所以第一次写入 name 后再创建 book,会导致 name 最后的 \0 被覆盖,此时会连带后面的 book 指针信息一并输出。此外如果使用 change_name 功能会使得 book1 的指针最低位被覆盖为 0,这样刚好会导致原本指向 book1 的指针指向 book1 的 description,而我们可以通过 edit_book 功能修改 description,也就能够实现伪造 book。

我们可以伪造一个 book1,他的 description 指向 book2 的 description,这样就可以通过 print_books 和 edit_book 来实现任意地址读写。

Chunk Extend & Overlapping
#

如果我们能够控制一个 chunk 的 size,那么就可以通过修改 size 来实现 chunk 的扩展。此时会导致 chunk 的重叠,在进行 free 操作时会导致后续的 chunk 被一起释放。之后如果再次分配到这个 chunk,就可以对第二块 chunk 的内容进行修改。

HITCON Training heapcreator

程序是一个选单式的堆管理程序,可以创建、删除、修改、查看堆块。

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

  v5 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  while ( 1 )
  {
    menu();
    read(0, buf, 4uLL);
    switch ( atoi(buf) )
    {
      case 1:
        create_heap();
        break;
      case 2:
        edit_heap();
        break;
      case 3:
        show_heap();
        break;
      case 4:
        delete_heap();
        break;
      case 5:
        exit(0);
      default:
        puts("Invalid Choice");
        break;
    }
  }
}

程序有一个 heap 结构体,结构为

struct heap
{
  unsigned __int64 size;
  char *content;
}

heaparray 为 heap 的指针数组,最多有 10 个堆块。

创建 heap 时会从堆中分配一个 heap 结构体,然后再分配一个 content 的内存块。而 edit_heap 中存在 off-by-one 漏洞,读取时会多读一个字节。

unsigned __int64 edit_heap()
{
  int id; // [rsp+Ch] [rbp-14h]
  char buf[8]; // [rsp+10h] [rbp-10h] BYREF
  unsigned __int64 v3; // [rsp+18h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  printf("Index :");
  read(0, buf, 4uLL);
  id = atoi(buf);
  if ( id < 0 || id > 9 )
  {
    puts("Out of bound!");
    _exit(0);
  }
  if ( *(&heaparray + id) )
  {
    printf("Content of heap : ");
    read_input(*((void **)*(&heaparray + id) + 1), *(_QWORD *)*(&heaparray + id) + 1LL); // off-by-one
    puts("Done !");
  }
  else
  {
    puts("No such heap !");
  }
  return __readfsqword(0x28u) ^ v3;
}

Unlink#

Use After Free
#

Fastbin Attack
#

相关文章

patchelf 与 glibc-all-in-one
·763 字·2 分钟
CTF Pwn
Stack Overflow
·1990 字·4 分钟
CTF Pwn
SSSCTF 2024 Writeup
·3053 字·7 分钟
CTF