下载附件后,得到了一个py脚本与一个的文本,如下:
problem.py:
import sys
import re
"""
key = '****CENSORED***************'
flag = 'TWCTF{*******CENSORED********}'
if len(key) % 2 == 1:
print("Key Length Error")
sys.exit(1)
n = len(key) / 2
encrypted = ''
for c in flag:
c = ord(c)
for a, b in zip(key[0:n], key[n:2*n]):#每个字符都会经过这里
c = (ord(a) * c + ord(b)) % 251#每个字符都仿射加密n次
encrypted += '%02x' % c#转换为16进制
print(encrypted)
encryted:
805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9
算法大致如下:
①将key分成等份的两组,并用zip打包成为一个元组
②将flag中的每一个元素c*key[0:n]+key[n:2n]
③将得到的数值转化为十六进制,形成字符串
一开始以为要把key通过暴力方式破解出来,但发现几乎不可能!看了下writeup(>^<)!说算法实质是仿射加密,仔细分析发现确实是这样。虽然flag的每个元素读会经过很多次处理,但每个元素每次都进行了相同的处理,每次处理都是在群251下的仿射加密!因此,可以直接看为进行了一次仿射加密,写出解密算法即可得出flag.
from libnum import invmod
import re
enflag='805eed80cbbccb94c36413275780ec94a857dfec8da8ca94a8c313a8ccf9'
enflag=re.findall('.{2}',enflag)
table=[]
for i in enflag:
x=int('0x'+i,16)
table.append(x)
lenflag=len(enflag)
print(lenflag,'\n',enflag)
print(table)
a=0
b=0
for i in range(252):
for j in range(252):
c1=(ord('T')*i + j)%251
c2=(ord('W')*i + j)%251
c3=(ord('C')*i + j)%251
if c1==table[0] and c2==table[1] and c3==table[2]:
a=i
b=j
print("a:",a,"\tb:",b)
inva=invmod(a,251)
flag=[]
for n in table:
x=((n-b)*inva)%251
flag.append(chr(x))
print(''.join(flag))
运算结果:
来源:oschina
链接:https://my.oschina.net/u/4267970/blog/4458307