本文最后更新于300 天前,其中的信息可能已经过时,如有错误可以直接在文章下留言
这次内部赛出的没有上次那么难,总归能做出两道题目了,比上学期有进步只能说,但是进步的不多。
先用ExeinfoPe看一下可执行文件的信息,程序名提示应该考点是RC4加密,还发现加了壳,如图
那就脱壳,如图
再用IDA打开,很轻易的找到了主函数,而且很简短
想偷懒,用angr跑,发现确实能跑出来,但是一开始看起来有点奇怪,脚本如下
def Go():
path_to_binary = "C:\\Users\\Daki\\Desktop\\R44444.exe"
project = angr.Project(path_to_binary, auto_load_libs=False)
initial_state = project.factory.entry_state()
simulation = project.factory.simgr(initial_state)
print_good_address = 0x4018CA
simulation.explore(find=print_good_address)
if simulation.found:
solution_state = simulation.found[0]
solution = solution_state.posix.dumps(sys.stdin.fileno()) # 大概意思是dump出输入
print(solution)
else:
raise Exception('Could not find the solution')
if __name__ == "__main__":
Go()
#输出b'flag{fine_you_win_this_flag...\x00'
确实能跑出来,但是flag后面的字符我以为没跑出来,根据主函数,输入是30位,加上括号剩下两位,我就猜是感叹号,或者下划线加感叹号,都没成功,那就只能自己分析了。
之前有认真学过RC4加密算法,很明显最关键的函数是这两个,sub_401550和sub_4016C8
先看第一个函数
这里很明显是S盒和T表的初始化,还有一些置换啥的,并没有进行改动,这个a2就是密钥,是h0w_@b0ut_th1s_0ne?
再看第二个函数
这里是RC4的最后一步了,这里有个很明显的和0x66进行异或就是改动的部分,我们只用改一下脚本就可以出答案了,脚本如下。
import base64
def rc4_main(key="init_key", message="init_message"):
print("RC4解密主函数调用成功")
print('\n')
s_box = rc4_init_sbox(key)
crypt = rc4_excrypt(message, s_box)
return crypt
def rc4_init_sbox(key):
s_box = list(range(256))
print("原来的 s 盒:%s" % s_box)
print('\n')
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
print("混乱后的 s 盒:%s" % s_box)
print('\n')
return s_box
def rc4_excrypt(plain, box):
print("调用解密程序成功。")
print('\n')
plain = base64.b64decode(plain.encode('utf-8'))
plain = bytes.decode(plain)
res = []
i = j = 0
for s in plain:
i = (i + 1) % 256
j = (j + box[i]) % 256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j]) % 256
k = box[t]
res.append(chr(ord(s) ^ k^0x66))
print("res用于解密字符串,解密后是:%res" % res)
print('\n')
cipher = "".join(res)
print("解密后的字符串是:%s" % cipher)
print('\n')
print("解密后的输出(没经过任何编码):")
print('\n')
return cipher
a = [ 0xFB, 0x00, 0x3E, 0xA3, 0xC8, 0x7A, 0x7B, 0x67, 0xB9, 0x7E,
0x12, 0xD9, 0x5C, 0x7C, 0x67, 0x33, 0xFB, 0xA2, 0x6A, 0x17,
0xF8, 0xFA, 0x19, 0x0B, 0xEC, 0xCF, 0xA1, 0xA3, 0xCD, 0xD6,
0x40, 0x00] # cipher
key = "h0w_@b0ut_th1s_0ne?"
s = ""
for i in a:
s += chr(i)
s = str(base64.b64encode(s.encode('utf-8')), 'utf-8')
rc4_main(key, s)
#输出的flag是flag{fine_you_win_this_flag...}
好吧,原来真的是三个点。
flag就是flag{fine_you_win_this_flag…}