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