23R3F's Blog

offbyone2

字数统计: 325阅读时长: 1 min
2018/11/03 Share

这题是当时xman的个人排位赛的一题,一直说着要复现一直推到现在才搞,太真实了

这题可以说是很骚很细节的一题,于是专门开一篇来记录一下这种很骚又很有代表性的题

1538306230871

保护机制开得还有点小恶心

题目逻辑很简单,同时功能也少,就创建chunk,删除chunk,打印chunk三个功能,创建chunk的时候只能创建0x80 ~ 0x10000 范围内的 chunk

漏洞点也只有一个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
unsigned __int64 __fastcall read2chunk(__int64 a1, unsigned int a2)
{
char buf; // [rsp+13h] [rbp-Dh]
unsigned int i; // [rsp+14h] [rbp-Ch]
unsigned __int64 v5; // [rsp+18h] [rbp-8h]

v5 = __readfsqword(0x28u);
for ( i = 0; i < a2; ++i )
{
buf = 0;
if ( read(0, &buf, 1uLL) < 0 )
{
puts("Read error.");
exit(-2);
}
if ( buf == '\n' )
{
*(_BYTE *)(i + a1) = 0; // 遇到\n时0截断
return __readfsqword(0x28u) ^ v5;
}
*(_BYTE *)(a1 + i) = buf;
}
*(_BYTE *)(i + a1) = 0; // 循环结束后仍然++i,这就会造成offbynull,使得多一个字节变成0
return __readfsqword(0x28u) ^ v5;
}

简单的说,就是读入的字节等于所申请的chunk大小时,会造成多一个0字节读入,配合pre_size空间复用机制,可以造成下一个chunk的size位的最低的那个字节为0x00

1541167021998

这题主要参考了xman某个大佬写的wp,tql,

CATALOG