KCTFQ3-heap

point

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
__int64 __fastcall read_content(__int64 a1, int a2)
{
__int64 result; // rax
int i; // [rsp+1Ch] [rbp-14h]
char s; // [rsp+20h] [rbp-10h]
unsigned __int64 v5; // [rsp+28h] [rbp-8h]

v5 = __readfsqword(0x28u);
memset(&s, 0, 8uLL);
for ( i = 0; i < a2; ++i )
{
if ( read(0, &s, 1uLL) <= 0 )
exit(1);
if ( s == 10 )
break;
*(_BYTE *)(a1 + i) = s;
}
result = (unsigned int)i;
if ( i == a2 )
{
result = i + a1; // null off by one
*(_BYTE *)result = 0;
}
return result;
}

null off by one没什么好说的,正常思路Overlapping 然后直接uaf就行。但是这题我没有动手很久。因为没地方leak libc_base。

只有泄露堆的地址,但是这题保护全力开,pie也开了。主要还是没有理解__malloc_hook的weak_variable这是个弱类型。前面的那长段hook的操作其实并没有改变libc上__malloc_hook的指向。所以这里libc上的__malloc_hook不为NULL还是_malloc_ini,所以这里是可以直接写低字节的。

但是这里我还是出问题了,本地测试我用的是debug的libc,在关键的偏移上存在偏差。

如果拿unsortedbin地址写到fastbin上去。写低1字节,但这个我debug libc.2.23不行。12位的差异,要写2字节,开了aslr只能保证低12位的。这里需要爆破。 概率是1/16,可能它给的libc不需要爆破。

也可以在main_arena结构上伪造chunk。把unsortbin 写掉。这里可以避免爆破。也可能不能避免。

但是万万没想到的是 把mallo_ini如果写成one_gadget, 你知道吗? 至少要写2字节 20位的偏移。你确定,只能保证12位的正确 8位的爆破? 0xff。 那这样其实也是可以的 :)