强网杯2017Misc-random

首先把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

你可能感兴趣的:(强网杯2017Misc-random)