在复习月饼杯的时候遇到的,这道题主要考查lcg算法吧,因为这里的slit是4位字母去循环相加的,相当于lcg算法中b是在变的,所以这题得爆破出a,b的值,所以想记录一下。
题目:
# -*- coding:utf-8 -*-
#Author: Lazzaro
from itertools import *
from random import *
from string import *
def encrypt(m, a, si):
c=""
for i in range(len(m)):
c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2) #zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0
return c
if __name__ == "__main__":
m = '****************************************************flag{*************}'
assert(len(m)==71)
a = randint(50,100)
salt = ''.join(sample(ascii_uppercase, 4)) #随机取4为大写字母
si = cycle(salt.lower()) #cycle()函数重复循环一组值,可用它循环数据集标识符对数据集进行分组 lower()讲大写字母转为小写字母
c=encrypt(m, a, si)
print(c)
#3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a
题目中的函数我已经注释了用法,就是c中每两位为一个十六进制,转为十进制后就是lcg算法部分了,我这里写了一个简单的爆破
c='3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a'
c=list(c)
x=[]
for i in range(0,len(c),2):
x.append(c[i]+c[i+1])
b=[x[52],x[53],x[54],x[55],x[56]] #flag{ 加密后所对应的hex值
f=['f','l','a','g','{']
#爆破a和si 找到是正常的5个字母即可
for a in range(50,101):
z=''
for i in range(len(f)):
z+=chr((eval('0x' + b[i])-ord(f[i])*a)%128)
print(z,a)
这里爆破出来的z和a有很多组
我们挑中jesqj这一组,因为只有这一组是循环的,其他都没有规律,那么就可以确定salt=JESQ,a=67了。那么剩下的就很简单了,一个个循环解密即可
a=67
si=cycle('jesq')
flag=''
for i in range(len(x)):
flag+=chr((eval('0x'+x[i])-ord(next(si)))*inverse(a,128)%128)
print(flag)
循环出来是:now_is_7fad9fcb-d361-4964-821c-177c906b8d20_flag_is_flag{md5(now-salt)}
这一段的意思是,now是7fad9fcb-d361-4964-821c-177c906b8d20
flag是now-salt 的md5加密
那么只需将7fad9fcb-d361-4964-821c-177c906b8d20-JESQ去md5加密即可
加密后为1efce62ee0a96e39149e2179db1dd04c