前言

本周参加了两个比赛,一个是de1CTF,另一个是网鼎杯,把这两场比赛全部总结一下。

在de1CTF中,只有一道常规的x64题目,其他题目。。。。。。。

反正挺好玩的,我就把aeg的mips,总结一下吧

关键字: CTF pwn baby aeg de1ctf

题目描述

这个题目和以前出的aeg题目也挺像的,一大堆检查,最后让你输入一个shellcode

思路

前面检查的部分,用angr解决了,后面直接输入mips的shellcode

题目中大多数的函数都是可以用angr直接求解的,但是有一个例外:

就是形如这个的函数:

image-20200511142112134

在这个函数中,angr跑起来非常吃力,所以,我们需要将这个函数单独解析。

这个函数的大小是固定的444,所以定位起来也是比较容易,解析里面的参数,主要就是解析if语句中的符号和param_1数组的下标,位置也相对固定,直接从机器码中取,除了这个函数以外的函数,一律用angr跑。

那么这个当前由于自己比较懒,没有适配多个这种函数的情况,所以,需要自己跑一下,跑出只要一个这种函数的情况。

比如以下情况就不行:

image-20200511142433295

这里的上述函数有2个,所以我直接退出了,感兴趣的小伙伴,直接适配一下就好,很简单的。

那么当程序中上述的函数就一个的时候,就得到结果了:

image-20200511142651849

最后那个shellcode没写,懒得写了。

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
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
#start analyses binary
filename = "h"
proj = angr.Project(filename,load_options={'auto_load_libs': False})
# find main function
cfg = proj.analyses.CFGFast()
for addr,b in cfg.kb.functions.items():
if (b.name == "main"):
main_address = addr
print(b)
print("[+] main_address: "+hex(main_address))
break
# binary has a hard function to solve by symbolic execution
# we need to find it
# we can find it's size always is 444
before_address = 0
bb_address = 0
next_address = 0

num =0
for addr,b in cfg.kb.functions.items():
if (addr > main_address):
break
if addr - before_address == 444:
hard_function_address = before_address
next_address = bb_address
print("[+] hard_function_address: "+hex(before_address))
print("[+] next_function_address: "+hex(next_address))
num += 1
else:
bb_address = before_address
before_address = addr

if num !=1:
print("[-] hard function's num is not equal 1")
exit(0)
# before the hard function
# we use symbolic execution to solve the problem
target_address = hard_function_address

state = proj.factory.entry_state()
simgr = proj.factory.simgr(state)
simgr.explore(find=target_address)
tmp_result = simgr.found[0].posix.dumps(0)
#print(tmp_result)
tmp_result = tmp_result.split(b'\x00'*10)[0]
print(tmp_result)
# now we get the solve of the binary before hard function
# the we need to analyse the hard function,we define the function: hard_function_solve()
def count_num(function_content,num):
one = function_content[num]
if one == 0:
two_num = num+28
three_num = num+84
four_num = three_num + 36
else:
two_num = num+36
if function_content[two_num] == 0:
three_num = num+84
four_num = three_num + 36
else:
three_num = num+92
if function_content[three_num] == 0:
four_num = three_num + 28
else:
four_num = three_num + 36
return [function_content[num],function_content[two_num],function_content[three_num],function_content[four_num]]

def hard_function_analyse(hard_address):
f_b = open(filename,"rb")
function_content = f_b.read()[hard_address-0x400000:hard_address-0x400000+444]
print("content_len:"+str(len(function_content)))
#1 step
if function_content[199] == 0x10:
difference_1 = 1
elif function_content[199] == 0x14:
difference_1 = 0
else:
print("[-] 1 step can not get option")
#2 step
if function_content[383] == 0x10:
difference_2 = 1
elif function_content[383] == 0x14:
difference_2 = 0
else:
print("[-] 2 step can not get option")

one = count_num(function_content,24)
two = count_num(function_content,208)
print(one)
print(two)
for i in range(255):
for j in range(255):
for n in range(255):
for m in range(255):
int_arr = [i,j,n,m]
v1_1 = abs(int_arr[one[0]] ** 2 - int_arr[one[1]] ** 2)
v1_2 = abs(int_arr[one[2]] ** 2 - int_arr[one[3]] ** 2)
if (v1_2 > v1_1) != difference_1:
continue
else:
v2_1 = abs(int_arr[two[0]] ** 2 - int_arr[two[1]] ** 2)
v2_2 = abs(int_arr[two[2]] ** 2 - int_arr[two[3]] ** 2)
if (v2_2 > v2_1) == difference_2:
print(int_arr)
return bytes((i,j,n,m))



hard_string = hard_function_analyse(hard_function_address)
print(hard_string)

final_address = 0x00400b30
start_address = next_address
#state = proj.factory.entry_state()
st = proj.factory.blank_state(addr=next_address)
tmp_key = claripy.BVS('tmp_key', 8*64)
for i in range(64):
st.memory.store(st.regs.sp+0x60+i,tmp_key.get_byte(i))
st.regs.a0 = st.regs.sp+0x60
#sm = proj.factory.simulation_manager(st)
#print(type(tmp_key))
simgr_2 = proj.factory.simgr(st)
simgr_2.explore(find=final_address)
key = simgr_2.found[0].solver.eval(tmp_key,cast_to=bytes)
print(key)
result = tmp_result+hard_string+key
print(result)
f_r = open(filename+"_out","wb")
f_r.write(result)
p.recvuntil("Faster > \n")
p.sendline(result)
print (p.recvuntil(">"))
p.sendline("\x00XYNM")
print(p.recvuntil("Your time comes.\n>

写在最后

如有错误欢迎指正:sofr@foxmail.com

Comments

⬆︎TOP