leak 记录今天的一个小题
先看题,
- add没有大小限制,
- 这里edit可以溢出8字节,也就是可以改后边的size,可以调用4次
- free没有调用函数只是把指针置0,
- show可以用一次.
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{init_0(a1, a2, a3);while ( 1 ){menu();switch ( read_n() ){case 1LL:m1add();break;case 2LL:m2edit(); // 溢出8字节 4次break;case 3LL:m3show(); // 1break;case 4LL:m4free(); // 无freebreak;case 5LL:exit(0);default:puts("Unknown");break;}}
}
其实这个题没啥说的,在libc-2.27当把top_chunk改小后建大于top_chunk的块大会把新块建在top的后边,因为这个块还没用完.原块会放入largebin
解题思路:
- 先建个块0,利用溢出修改top_chunk 原来是20d91改为d91(尾部需要对齐,所以最好保持原样)
- 建个1000的块1,由于这个块比d91大会在现有top后新开辟空间(相邻)原块进入largebin(有指向main_arena+xxx的指针和堆指针)
- 建小块2这块会占用原largebin里的空间(旧top_chunk)这时show得到libc地址,如果改0x10字节再show还可以得到堆地址,不过这题只能show一次得到不到
- 改1利用溢出8字节修改新top_chunk长度为0xfffffffffffffff 64位全1
- 建大块 -22020 #3 当前块地址就是22010,这样建就会把块一直建到堆空间的头,下一块与tcache重合
- 建与tcache重合的块4(不通太小,原来的top_chunk后边还有个挺大的largebin没用呢)
- 编辑块4,写入一个0x20块的tcache项,再建块就会建到这,所这这里指到哪就能建到哪.这里指malloc_hook-8=realloc_hook 因为没有free,所以要在malloc_hook写one,one又有条件限制可能需要用realloc调栈(对应2.27版本 偏移有0,2,4,6,8,9,10)
- 建块,写入one
看似板子题,但是这有个问题,赛方给了一个很难见到的libc版本 libc-2.27-3ubuntu1.4-amd64
后来看了打通人的EXP, 他用的 3u1.5
对于泄露main_arena的题来说,main_arena在大版本相同的情况下是完全相同的.根本不可能确定小版本,但是对于需要用one的题又必需确定小版本,现在出题都这么卷吗.