首先把pyo反编译成py文件
pyo文件,是python编译优化后的字节码文件
可以用uncompyle这个工具来反编译
有pip的情况下直接pip install uncompyle6就可以下载好
然后输入 uncompyle6 in.pyo out.py 可以得到反编译结果
# uncompyle6 version 2.11.5
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.12 (default, Nov 19 2016, 06:48:10)
# [GCC 5.4.0 20160609]
# Embedded file name: encrypt.py
# Compiled at: 2017-07-11 02:19:27
from random import randint
from math import floor, sqrt
_ = ''
__ = '_'
____ = [ ord(___) for ___ in __ ]
_____ = randint(65, max(____)) * 255
for ___ in range(len(__)):
_ += str(int(floor(float(_____ + ____[___]) / 2 + sqrt(_____ * ____[___])) % 255)) + ' '
print _
# okay decompiling encrypt.pyo
File 'encrypt.py' doesn't exist. Skipped
#
# Successfully decompiled file
为了代码的可读性把变量名标识成容易理解的单词:
from random import randint
from math import floor, sqrt
ciphertext = ''
plaintext = 'abcde'
array = [ ord(x) for x in plaintext ]
key = randint(65, max(array)) * 255 #65-127
for x in range(len(plaintext)):
ciphertext += str(int(floor(float(key + array[x]) / 2 + sqrt(key * array[x])) % 255)) + ' '
print ciphertext
观察发现,虽然Key随机生成,但是它的生成范围为(65, max(array)),而array为可显明文的十进制ASCII值,也就是说key的最大生成范围为(65, 127),而以上代码是逐个字符进行加密,且每次都是使用同一个密钥key,在已知密文的情况下我们可以考虑使用蛮力攻击爆破明文。计算次数为:
19 (明文长度) * (127 - 65)(可能明文) * (127 - 65)(可能密钥) = 70360
--(参考官方wp)
爆破脚本↓
from random import randint
from math import floor, sqrt
import string
data=[208,140,149,236,189,77,193,104,202,184,97,236,148,202,244,199,77,122,113]
prints = string.printable
for key in range(65,128):
flag=''
key = key * 255
for i in range(19):
for char in prints:
if ord(char) > 64:
a = int(floor(float(key + ord(char)) / 2 + sqrt( key * ord(char))) % 255)
if a == data[i]:
flag+=char
if len(flag)==19:
print flag