题目下载到手三个文件
优先查看exe,是个游戏。
32位PE文件以及.net编写的,用dnSpy打开。
读取了gamemessage文件存放到Program.memory里。
接下来都是一些键盘控件的处理,按Enter会进入俩个分支,有一个地方不同的是Escape处:
这里点击一下,跟到函数的地方。
会紧跟着调用一个goldFunc的函数,再跟过去,
从这里一直看下去,直到再次看到Program.memory
这里很明显做了一个异或34的处理,之后赋给AchivePoint1
中间的加减大概就是分数,一直到这里flag39,可能会调用函数genCode。这个函数在dll中,先不管。
这里又是对Program.memory进行了一个加密,用了ECB加密模式,填充方式是PaddingMode.Zeors,这是一个典型的AES加密。这里也是给到了AchivePoint2。
这里就是AchivePoint3了,进行了一个反序列化的操作,但是没有对文件进行处理。不明所以。
大概这个exe就看完了,下面也不太清楚都做了什么,可以明白的是gamemessage是可以解密的。
解密脚本:
from Crypto.Cipher import AES
with open("gamemessage","rb") as f:
data = f.read()
dataArr = [t for t in data]
for i in range(len(dataArr)):
dataArr[i] ^= 34
data = bytes(dataArr)
key = [66,114,97,105,110,115,116,111,114,109,105,110,103,33,33,33]
key = bytes(key)
cipher = AES.new(key, AES.MODE_ECB)
p = cipher.decrypt(data)
# print(p)
filename = "decrypt"
with open(filename, 'wb') as f:
f.write(p)
之后可以得到一个decrypt文件。
发现并不是一个exe或dll文件。用Winhex打开,搜索MZ,将其前面所有内容删掉
保存,再用dnSpy打开。
给了俩组密文,依次解密,第一组用z3求解。可以得到x,y,z。三个数据根据ParseKey可以得到长度为12的array4,已知array5,俩者异或就可以得到flag。
EXP:
from z3 import *
sol = Solver()
xorkey = [60, 100, 36, 86, 51, 251, 167, 108, 116, 245, 207, 223, 40, 103, 34, 62, 22, 251, 227]
cmp = [101, 5, 80, 213, 163, 26, 59, 38, 19, 6, 173, 189, 198, 166, 140, 183, 42, 247, 223, 24, 106, 20, 145, 37, 24, 7,
22, 191, 110, 179, 227, 5, 62, 9, 13, 17, 65, 22, 37, 5]
x = BitVec('x', 63)
y = BitVec('y', 63)
z = BitVec('z', 63)
dup = [x, y, z]
arr = [BitVecVal(0, 63) for i in range(len(cmp))]
num = -1
for i in range(320):
x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1) | x << 1)
y = (((y >> 30 ^ y >> 27) & 1) | y << 1)
z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1) | z << 1)
if i % 8 == 0:
num = num + 1
arr[num] = ((arr[num] << 1) | (
((z >> 32 & 1 & (x >> 30 & 1)) ^ (((z >> 32 & 1) ^ 1) & (y >> 31 & 1))) & 0xffffffff) & 0xff)
for i in range(len(cmp)):
sol.add(cmp[i] == arr[i])
assert sol.check() == sat
sol = sol.model()
fake = [sol.eval(i).as_long() & 0xffffffff for i in dup]
Key = [0] * 12
for i in range(3):
for j in range(4):
Key[i * 4 + j] = fake[i] >> j * 8 & 255
print(bytearray([(xorkey[i] ^ Key[i % len(Key)]) & 255 for i in range(len(xorkey))]))