vsCTF ezorange writeup

vsCTF ezorange writeup

前言

最近都在做程序分析和写kernel, 好久没玩pwn了, 周日晚上回宿舍刚好看到有一个vsCTF的比赛, 就顺手做了个glibc 2.32的堆题. 题目本身比较简单, 不过考察了一些高版本的libc的特性, 在这里记录一下作为备忘.

初步分析

首先看一下保护:

$ checksec --file=ezorange
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x3ff000)

Partial RELRO + No PIE, 强烈暗示修改.got.plt.

IDA打开看一眼, 只提供了malloc和edit+show, 没有free, 结合题目名字, 必然是要用House of Orange了.

漏洞点在Modify函数里, 有一个堆上的OOB:

__int64 __fastcall Modify(_BYTE **orange_list)
{
  unsigned int v2; // [rsp+10h] [rbp-10h] BYREF
  unsigned int v3; // [rsp+14h] [rbp-Ch] BYREF
  _BYTE *cur_ptr; // [rsp+18h] [rbp-8h]

  printf("Orange number: ");
  __isoc99_scanf("%u", &v2);
  if ( v2 > 1 || !orange_list[v2] )
  {
    printf("Not allowed!");
    exit(0);
  }
  cur_ptr = orange_list[v2];
  printf("Total %u cell in this orange\n", *((_DWORD *)orange_list[v2] - 2) & 0xFFFFFFF0);
  printf("Cell index: ");
  __isoc99_scanf("%u", &v3);
  printf("Current value: %hhu\n", (unsigned __int8)cur_ptr[v3]);// OOB
  printf("New value: ");
  return __isoc99_scanf("%hhu", &cur_ptr[v3]);
}

限制条件: 只能同时保有两个chunk pointer, malloc参数不能超过0x1000.

题解

太长不看版:

  1. 利用OOB+House of Orange来把top chunk送进unsorted bin, 从而leak libc和heap的基址
  2. 同上, 但是在House of Orange的最后一步之前, 将top chunk的大小缩减到tcache的范围, 这样新的top chunk就会被丢到tcache里
  3. 重复2, 拿到第2个tcache, 然后利用OOB构造fake chunk, malloc两次拿到fake chunk
  4. 覆写exit@got.plt为one gadget, 然后给一个非法输入触发get shell

逐步分析

继续阅读“vsCTF ezorange writeup”