运行win.pyc,要求输出’You Win’代表成功。
先用软件反编译win.pyc。
用编译器打开:
# Embedded file name: d:/idf.py
def encrypt(key, seed, string):
rst = []
for v in string:
rst.append((ord(v) + seed ^ ord(key[seed])) % 255)
seed = (seed + 1) % len(key)
return rst
if __name__ == '__main__':
print("Welcome to idf's python crackme")
flag = input('Enter the Flag: ')
KEY1 = 'Maybe you are good at decryptint Byte Code, have a try!'
KEY2 = [124,
48,
52,
59,
164,
50,
37,
62,
67,
52,
48,
6,
1,
122,
3,
22,
72,
1,
1,
14,
46,
27,
232]
en_out = encrypt(KEY1, 5, flag)
if KEY2 == en_out:
print ('You Win')
else:
print ('Try Again !')
源代码就是一个输入字符串加密,当加密后的结果等于KEY2时输出“You win!”
那我们就需要反向破解密码。
但是破解过程中出现了问题,这是刚开始第一次的破解方法:
直接将算法反向解密:
破解出了正确字符串的8位256以内的ascii码,但是输入到win.py源代码中却失败了!
后来我思考了一下,ascii码在128~256中的字符是扩展ascii码,有些似乎是无法打印的。有可能是这导致了出错,我得找128以内的ascii码来代替。
于是有了接下来的第二种破解方法:
通过穷举,在128以内找到能够计算出正确KEY2的值:
将新的flag输入源代码win.py,结果正确,成功输出“You win!”
我再比较了来两次的字符串:
第一次:W°Ë½{Æ«ÔÊφ‹HµŽŽ’·}
第二次:WCTF{ILOVEPYTHONSOMUCH}
在256以内的ascii码中有些字符是无法打印的,而在128以内所有的字符都可以打印。
这是正确解密的源代码:
#KEY1的长度是55
KEY1 = 'Maybe you are good at decryptint Byte Code, have a try!'
#KEY2的长度是23
KEY2 = [124,48,52,59,164,50,37,62,67,52,48,6,1,122,3,22,72,1,1,14,46,27,232]
#KEY1字符串转换成int数组
key1 = []
for v in KEY1:
key1.append(ord(v))
#结果字符串对应的ascii码数组
result = []
#k2
k2 = 0
#k1是key1的下标
for k1 in range(5,28):
#查找128以内符合正确结果的ascii码
for i in range(128):
if KEY2[k2] == (i + k1 ^ key1[k1]) % 255:
result.append(i)
k2 = k2 + 1
flag = ""
for i in range(23):
flag = flag + chr(result[i])
print("flag的值为:",flag)