# -*- coding:utf-8 -*-
import A,SALT
from itertools 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)
return c
if __name__ == "__main__":
m = 'flag{********************************}'
a = A
salt = SALT
assert(len(salt)==3)
assert(salt.isalpha())
si = cycle(salt.lower())
print("鏄庢枃鍐呭涓猴細")
print(m)
print("鍔犲瘑鍚庣殑瀵嗘枃涓猴細")
c=encrypt(m, a, si)
print(c)
#鍔犲瘑鍚庣殑瀵嗘枃涓猴細
#177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d
一开始真的没看懂这是什么加密,复现题目时发现与仿射加密很像,还是自己太菜了
这里就是 c = ax + salt (mod 128) ,而salt是有周期的,flag的格式我们是知道的,于是可以先根据 ‘f’,'g’来求出a和salt的前一位,就是简单的解方程,随便写出几行代码解出 a = 57
flag = 0
for i in range(128):
for j in range(128):
m = (102 * i + j)%128
n = (103 * i + j)%128
if m == 23 and n == 80:
flag = 1
print(i,j)
break
if flag == 1:
break
再根据解出的a,用 ‘l’,'a’去解出salt的剩下两位,求出salt = ‘ahh’,接下来进行解码
flag = a-1(c - salt) mod 128
from Crypto.Util.number import *
import gmpy2
c = "177401504b0125272c122743171e2c250a602e3a7c206e014a012703273a3c0160173a73753d".decode('hex')
a = 57
salt = 'ahh'
flag = ''
n = 0
for i in c:
b = ord(salt[n%3])
n += 1
flag += chr(gmpy2.invert(a,128)*(ord(i) - b) % 128)
print flag
from Crypto.Util.number import*
from secret import flag
class LCG:
def __init__(self):
self.a = getRandomNBitInteger(32)
self.b = getRandomNBitInteger(32)
self.m = getPrime(32)
self.seed = getRandomNBitInteger(32)
def next(self):
self.seed = (self.a*self.seed+self.b) % self.m
return self.seed >> 16
def output(self):
print("a = {}nb = {}nm = {}".format(self.a, self.b, self.m))
print("state1 = {}".format(self.next()))
print("state2 = {}".format(self.next()))
class DH:
def __init__(self):
self.lcg = LCG()
self.lcg.output()
self.g = getRandomNBitInteger(128)
self.m = getPrime(256)
self.A, self.a = self.gen_AB()
self.B, self.b = self.gen_AB()
self.key = pow(self.A, self.b, self.m)
def gen_AB(self):
x = ''
for _ in range(64):
x += '1' if self.lcg.next() % 2 else '0'
return pow(self.g, int(x, 2), self.m), int(x, 2)
DH = DH()
flag = bytes_to_long(flag)
print("g = {}nA = {}nB = {}nM = {}".format(DH.g, DH.A, DH.B, DH.m))
print("Cipher = {}".format(flag ^ DH.key))
'''
a = 3844066521
b = 3316005024
m = 2249804527
state1 = 16269
state2 = 4249
g = 183096451267674849541594370111199688704
A = 102248652770540219619953045171664636108622486775480799200725530949685509093530
B = 74913924633988481450801262607456437193056607965094613549273335198280176291445
M = 102752586316294557951738800745394456033378966059875498971396396583576430992701
Cipher = 13040004482819935755130996285494678592830702618071750116744173145400949521388647864913527703
'''
首先观察到有很多的随机数,并且其中a,b,m,g,m均已知,而随机数种子数seed还未知,根据LCG()函数,写出脚本爆出seed
a = 3844066521
b = 3316005024
m = 2249804527
seed = 1
def next(a,b,m,seed):
seed = (a*seed+b)%m
return seed >> 16
def next1(a,b,m,seed):
seed = (a*seed+b)%m
seedd = (a*seed+b)%m
return seedd >> 16
while(1):
seed1 = next(a,b,m,seed)
if seed1 == 16269:
seed2 = next1(a,b,m,seed)
if seed2 == 4249:
print seed
break
seed += 1
#714405490
接着把所有已知量带入,可以在最后解出明文
from Crypto.Util.number import*
class LCG:
def __init__(self):
self.a = 3844066521
self.b = 3316005024
self.m = 2249804527
self.seed = 714405490
def next(self):
self.seed = (self.a*self.seed+self.b) % self.m
return self.seed >> 16
def output(self):
print("a = {}nb = {}nm = {}".format(self.a, self.b, self.m))
print("state1 = {}".format(self.next()))
print("state2 = {}".format(self.next()))
class DH:
def __init__(self):
self.lcg = LCG()
self.lcg.output()
self.g = 183096451267674849541594370111199688704
self.m = 102752586316294557951738800745394456033378966059875498971396396583576430992701
self.A, self.a = self.gen_AB()
self.B, self.b = self.gen_AB()
self.key = pow(self.A, self.b, self.m)
def gen_AB(self):
x = ''
for _ in range(64):
x += '1' if self.lcg.next() % 2 else '0'
return pow(self.g, int(x, 2), self.m), int(x, 2)
DH = DH()
Cipher = 13040004482819935755130996285494678592830702618071750116744173145400949521388647864913527703
#flag = bytes_to_long(flag)
#print("g = {}nA = {}nB = {}nM = {}".format(DH.g, DH.A, DH.B, DH.m))
print("flag = {}".format(long_to_bytes(Cipher ^ DH.key)))