Skip to content

Commit 2a979bd

Browse files
committed
Add level6 code
1 parent 57adeaa commit 2a979bd

17 files changed

+369
-0
lines changed

flareon-2018/level6/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Writeup
2+
3+
[Full Writeup](http://ctfhacker.com/reverse/2018/09/16/flareon-2018-level6-angr.html)

flareon-2018/level6/magic000

95.6 KB
Binary file not shown.

flareon-2018/level6/magic001

95.6 KB
Binary file not shown.

flareon-2018/level6/magic002

95.6 KB
Binary file not shown.

flareon-2018/level6/magic003

95.6 KB
Binary file not shown.

flareon-2018/level6/magic004

95.6 KB
Binary file not shown.

flareon-2018/level6/magic005

95.6 KB
Binary file not shown.

flareon-2018/level6/magic006

95.6 KB
Binary file not shown.

flareon-2018/level6/magic007

95.6 KB
Binary file not shown.

flareon-2018/level6/magic008

95.6 KB
Binary file not shown.

flareon-2018/level6/magic009

95.6 KB
Binary file not shown.

flareon-2018/level6/reconstruct.py

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from binaryninja import *
2+
from collections import namedtuple
3+
import sys
4+
5+
Struct = namedtuple('Struct', ['function_addr', 'offset', 'length'])
6+
7+
def decrypt(filename):
8+
bv = BinaryViewType.get_view_of_file(filename)
9+
print(bv)
10+
# bv.add_analysis_option("linearsweep")
11+
# bv.update_analysis_and_wait()
12+
13+
code_addr = 0x605100
14+
len_addr = 0x605108
15+
key_addr = 0x605118
16+
17+
data = []
18+
19+
for x in range(33):
20+
curr_len = struct.unpack('<I', bv.read(len_addr, 4))[0]
21+
curr_code = struct.unpack('<I', bv.read(code_addr, 4))[0]
22+
curr_key = struct.unpack('<I', bv.read(key_addr, 4))[0]
23+
24+
# print(hex(curr_code))
25+
# print(hex(code_addr))
26+
curr_struct = [x for x in struct.unpack('<QIII', bv.read(code_addr, 4 * 5))]
27+
data.append(Struct(curr_struct[0], curr_struct[2], curr_struct[3]))
28+
29+
for i, (code, key) in enumerate(zip(bv.read(curr_code, curr_len), bv.read(curr_key, curr_len))):
30+
curr_char = chr(ord(code) ^ ord(key))
31+
bv.write(curr_code + i, curr_char)
32+
33+
code_addr += 288
34+
len_addr += 288
35+
key_addr += 288
36+
37+
bv.save('./magic_patched')
38+
39+
return data

flareon-2018/level6/small_win.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import angr
2+
import claripy
3+
from reconstruct import decrypt
4+
5+
result = '?' * 0x45
6+
global_addr = 0x605100
7+
n = 0
8+
9+
new_filename = './magic'
10+
data = decrypt(new_filename)
11+
12+
proj = angr.Project('./magic_patched', load_options={"auto_load_libs": False})
13+
14+
state = proj.factory.blank_state(addr=data[n].function_addr, add_options={angr.options.LAZY_SOLVES})
15+
16+
input_addr = 0x10000 * n
17+
key_len = data[n].length
18+
19+
input = claripy.BVS("input", 8*(key_len))
20+
for i in xrange(key_len):
21+
state.add_constraints(input.get_byte(i) != 0)
22+
23+
state.memory.store(input_addr, input)
24+
25+
key_addr = (0x605120 + n*0x120)
26+
state.regs.rdi = claripy.BVV(input_addr, 8*8)
27+
state.regs.rsi = claripy.BVV(key_len, 8*8)
28+
state.regs.rdx = claripy.BVV(key_addr, 8*8)
29+
print("Start {} - rdi: {} rsi: {} rdx: {}".format(state.regs.rip, state.regs.rdi, state.regs.rsi, state.regs.rdx))
30+
state.stack_push(0xdeadbeef)
31+
32+
simgr = proj.factory.simulation_manager(state)
33+
34+
def find_func(state):
35+
if state.regs.rip.args[0] == 0xdeadbeef:
36+
if state.regs.rax.args[0] == 1:
37+
global result
38+
ans = state.solver.eval(input, cast_to=str)
39+
print(ans)
40+
print(n, repr(ans))
41+
offset = data[n].offset
42+
ans_len = data[n].length
43+
result = result[:offset] + ans + result[offset+ans_len:]
44+
print(n, result)
45+
with open('status', 'a') as f:
46+
f.write('{} {}\n'.format(n, result))
47+
return True
48+
49+
def avoid_func(state):
50+
if state.regs.rip.args[0] == 0xdeadbeef and state.regs.rax.args[0] == 0:
51+
return True
52+
53+
simgr.explore(find=find_func, avoid=avoid_func)
54+
print(simgr)
55+
56+
print('RESULT', result)

flareon-2018/level6/small_win2.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import angr
2+
import claripy
3+
from reconstruct import decrypt
4+
5+
result = '?' * 0x45
6+
global_addr = 0x605100
7+
8+
new_filename = './magic'
9+
data = decrypt(new_filename)
10+
for n in xrange(33):
11+
proj = angr.Project('./magic_patched', load_options={"auto_load_libs": False})
12+
13+
state = proj.factory.blank_state(addr=data[n].function_addr, add_options={angr.options.LAZY_SOLVES})
14+
15+
input_addr = 0x10000 * n
16+
key_len = data[n].length
17+
18+
input = claripy.BVS("input", 8*(key_len))
19+
for i in xrange(key_len):
20+
state.add_constraints(input.get_byte(i) != 0)
21+
22+
state.memory.store(input_addr, input)
23+
24+
key_addr = (0x605120 + n*0x120)
25+
state.regs.rdi = claripy.BVV(input_addr, 8*8)
26+
state.regs.rsi = claripy.BVV(key_len, 8*8)
27+
state.regs.rdx = claripy.BVV(key_addr, 8*8)
28+
print("Start {} - rdi: {} rsi: {} rdx: {}".format(state.regs.rip, state.regs.rdi, state.regs.rsi, state.regs.rdx))
29+
state.stack_push(0xdeadbeef)
30+
31+
simgr = proj.factory.simulation_manager(state)
32+
33+
def find_func(state):
34+
if state.regs.rip.args[0] == 0xdeadbeef:
35+
if state.regs.rax.args[0] == 1:
36+
global result
37+
ans = state.solver.eval(input, cast_to=str)
38+
# print(ans)
39+
# print(n, repr(ans))
40+
offset = data[n].offset
41+
ans_len = data[n].length
42+
result = result[:offset] + ans + result[offset+ans_len:]
43+
print(n, result)
44+
with open('status', 'a') as f:
45+
f.write('{} {}\n'.format(n, result))
46+
return True
47+
48+
def avoid_func(state):
49+
if state.regs.rip.args[0] == 0xdeadbeef and state.regs.rax.args[0] == 0:
50+
return True
51+
52+
simgr.explore(find=find_func, avoid=avoid_func)
53+
# print(simgr)
54+
55+
print('RESULT', result)

flareon-2018/level6/small_win3.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import angr
2+
import claripy
3+
from reconstruct import decrypt
4+
5+
result = '?' * 0x45
6+
global_addr = 0x605100
7+
8+
new_filename = './magic'
9+
data = decrypt(new_filename)
10+
for n in xrange(33):
11+
n = 21
12+
proj = angr.Project('./magic_patched', load_options={"auto_load_libs": False})
13+
14+
state = proj.factory.blank_state(addr=data[n].function_addr, add_options={angr.options.LAZY_SOLVES})
15+
16+
input_addr = 0x10000 * n
17+
key_len = data[n].length
18+
19+
input = claripy.BVS("input", 8*(key_len))
20+
for i in xrange(key_len):
21+
state.add_constraints(input.get_byte(i) != 0)
22+
23+
state.memory.store(input_addr, input)
24+
25+
key_addr = (0x605120 + n*0x120)
26+
state.regs.rdi = claripy.BVV(input_addr, 8*8)
27+
state.regs.rsi = claripy.BVV(key_len, 8*8)
28+
state.regs.rdx = claripy.BVV(key_addr, 8*8)
29+
print("Start {} - rdi: {} rsi: {} rdx: {}".format(state.regs.rip, state.regs.rdi, state.regs.rsi, state.regs.rdx))
30+
state.stack_push(0xdeadbeef)
31+
32+
simgr = proj.factory.simulation_manager(state)
33+
34+
def find_func(state):
35+
if state.regs.rip.args[0] == 0xdeadbeef:
36+
if state.regs.rax.args[0] == 1:
37+
global result
38+
try:
39+
ans = state.solver.eval(input, cast_to=str)
40+
# print(ans)
41+
# print(n, repr(ans))
42+
offset = data[n].offset
43+
ans_len = data[n].length
44+
result = result[:offset] + ans + result[offset+ans_len:]
45+
# print(n, result)
46+
with open('status', 'a') as f:
47+
f.write('{} {}\n'.format(n, result))
48+
return True
49+
except:
50+
print('ERROR: n={}'.format(n))
51+
52+
53+
def avoid_func(state):
54+
if state.regs.rip.args[0] == 0xdeadbeef and state.regs.rax.args[0] == 0:
55+
return True
56+
57+
simgr.explore(find=find_func, avoid=avoid_func)
58+
# print(simgr)
59+
60+
# print('RESULT', result)

flareon-2018/level6/small_win4.py

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import angr
2+
import claripy
3+
from reconstruct import decrypt
4+
5+
def hook_mem_write(state):
6+
if not state.inspect.instruction:
7+
return
8+
print('{:x} [{}] = {}'.format(state.inspect.instruction,
9+
state.inspect.mem_write_address,
10+
state.inspect.mem_write_expr))
11+
12+
def hook_mem_read(state):
13+
if not state.inspect.instruction:
14+
return
15+
print('{:x} {} = [{}]'.format(state.inspect.instruction,
16+
state.inspect.mem_read_expr,
17+
state.inspect.mem_read_address))
18+
19+
result = '?' * 0x45
20+
global_addr = 0x605100
21+
22+
new_filename = './magic'
23+
data = decrypt(new_filename)
24+
import IPython; shell = IPython.terminal.embed.InteractiveShellEmbed(); shell.mainloop()
25+
for n in xrange(33):
26+
# n = 21
27+
proj = angr.Project('./magic_patched', load_options={"auto_load_libs": False})
28+
29+
state = proj.factory.blank_state(addr=data[n].function_addr, add_options={angr.options.LAZY_SOLVES,
30+
angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY})
31+
# state.inspect.b('mem_write', when=angr.BP_AFTER, action=hook_mem_write)
32+
# state.inspect.b('mem_read', when=angr.BP_AFTER, action=hook_mem_read)
33+
34+
input_addr = 0x10000 * n
35+
key_len = data[n].length
36+
37+
input = claripy.BVS("input", 8*(key_len))
38+
for i in xrange(key_len):
39+
state.add_constraints(input.get_byte(i) != 0)
40+
41+
state.memory.store(input_addr, input)
42+
43+
key_addr = (0x605120 + n*0x120)
44+
state.regs.rdi = claripy.BVV(input_addr, 8*8)
45+
state.regs.rsi = claripy.BVV(key_len, 8*8)
46+
state.regs.rdx = claripy.BVV(key_addr, 8*8)
47+
print("Start {} - rdi: {} rsi: {} rdx: {}".format(state.regs.rip, state.regs.rdi, state.regs.rsi, state.regs.rdx))
48+
state.stack_push(0xdeadbeef)
49+
50+
simgr = proj.factory.simulation_manager(state)
51+
52+
def find_func(state):
53+
if state.regs.rip.args[0] == 0xdeadbeef:
54+
if state.regs.rax.args[0] == 1:
55+
global result
56+
try:
57+
ans = state.solver.eval(input, cast_to=str)
58+
print(ans)
59+
print(n, repr(ans))
60+
offset = data[n].offset
61+
ans_len = data[n].length
62+
result = result[:offset] + ans + result[offset+ans_len:]
63+
print(n, result)
64+
with open('status', 'a') as f:
65+
f.write('{} {}\n'.format(n, result))
66+
return True
67+
except:
68+
print('ERROR: n={}'.format(n))
69+
70+
71+
def avoid_func(state):
72+
if state.regs.rip.args[0] == 0xdeadbeef and state.regs.rax.args[0] == 0:
73+
return True
74+
75+
simgr.explore(find=find_func, avoid=avoid_func)
76+
# print(simgr)
77+
78+
# print('RESULT', result)

flareon-2018/level6/small_win5.py

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import angr
2+
import claripy
3+
from reconstruct import decrypt
4+
5+
def hook_mem_write(state):
6+
if not state.inspect.instruction:
7+
return
8+
print('{:x} [{}] = {}'.format(state.inspect.instruction,
9+
state.inspect.mem_write_address,
10+
state.inspect.mem_write_expr))
11+
12+
def hook_mem_read(state):
13+
if not state.inspect.instruction:
14+
return
15+
print('{:x} {} = [{}]'.format(state.inspect.instruction,
16+
state.inspect.mem_read_expr,
17+
state.inspect.mem_read_address))
18+
19+
result = '?' * 0x45
20+
global_addr = 0x605100
21+
22+
new_filename = './magic'
23+
data = decrypt(new_filename)
24+
import IPython; shell = IPython.terminal.embed.InteractiveShellEmbed(); shell.mainloop()
25+
for n in xrange(33):
26+
# n = 21
27+
proj = angr.Project('./magic_patched', load_options={"auto_load_libs": False})
28+
29+
state = proj.factory.blank_state(addr=data[n].function_addr, add_options={angr.options.LAZY_SOLVES,
30+
angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY})
31+
# state.inspect.b('mem_write', when=angr.BP_AFTER, action=hook_mem_write)
32+
# state.inspect.b('mem_read', when=angr.BP_AFTER, action=hook_mem_read)
33+
34+
input_addr = 0x10000 * n
35+
key_len = data[n].length
36+
37+
input = claripy.BVS("input", 8*(key_len))
38+
for i in xrange(key_len):
39+
state.add_constraints(input.get_byte(i) != 0)
40+
41+
state.memory.store(input_addr, input)
42+
43+
key_addr = (0x605120 + n*0x120)
44+
state.regs.rdi = claripy.BVV(input_addr, 8*8)
45+
state.regs.rsi = claripy.BVV(key_len, 8*8)
46+
state.regs.rdx = claripy.BVV(key_addr, 8*8)
47+
print("Start {} - rdi: {} rsi: {} rdx: {}".format(state.regs.rip, state.regs.rdi, state.regs.rsi, state.regs.rdx))
48+
state.stack_push(0xdeadbeef)
49+
50+
simgr = proj.factory.simulation_manager(state)
51+
52+
def find_func(state):
53+
if state.regs.rip.args[0] == 0xdeadbeef:
54+
if state.regs.rax.args[0] == 1:
55+
global result
56+
try:
57+
ans = state.solver.eval(input, cast_to=str)
58+
print(ans)
59+
print(n, repr(ans))
60+
offset = data[n].offset
61+
ans_len = data[n].length
62+
result = result[:offset] + ans + result[offset+ans_len:]
63+
print(n, result)
64+
with open('status', 'a') as f:
65+
f.write('{} {}\n'.format(n, result))
66+
return True
67+
except:
68+
print('ERROR: n={}'.format(n))
69+
70+
71+
def avoid_func(state):
72+
if state.regs.rip.args[0] == 0xdeadbeef and state.regs.rax.args[0] == 0:
73+
return True
74+
75+
simgr.explore(find=find_func, avoid=avoid_func)
76+
# print(simgr)
77+
78+
# print('RESULT', result)

0 commit comments

Comments
 (0)