#!/usr/bin/python3 from secret import flag from Crypto.Util.number import * from random import randrange
p = 64999433139797068147576269731948390094958654326970231465808792590598519729077
a = randrange(2, p) b = randrange(2, p) x = bytes_to_long(flag) menu = ''' Random as a Service with LCG backend Enter your option 1. Reset 2. Get 3. Exit '''
defGetRandom(): global x nx = (a*x + b) % p print(nx) x = nx whileTrue: print(menu) opt = input('> ') try: opt = int(opt) if opt == 1: x = bytes_to_long(flag) elif opt == 2: GetRandom() elif opt == 3: break else: print('invalid option') except Exception as e: print('oh no, something wrong!') print(e)
这道题提供了靶机,可以通过靶机得出三个连续加密后数据,解密代码如下:
import pwn from Crypto.Util.number import * import gmpy2 x = [] p = 64999433139797068147576269731948390094958654326970231465808792590598519729077 io = pwn.remote("node4.buuoj.cn",25624) io.recv() io.sendline(b'1') io.recv() for _ inrange(3): io.sendline(b'2') data = io.recvline() io.recv() x.append(int(data)) io.sendline(b'3') a = (x[2]-x[1])*gmpy2.invert(x[1]-x[0],p)%p b = (x[1]-a*x[0])%p x = (x[0]-b)*gmpy2.invert(a,p)%p print(long_to_bytes(x))
运行可得flag:
flag{lcg_1s_n0t_s3cur3#fb528ba5}
三.求参数a,b,p后求逆
与上一种形式相似,但是多了个p要求,我们假设一个数列:
其满足:
假设有一个数列 有:
所以:
也就是说:
同理,有:
所以:
求出p后我们就可以由上种类型继续求解。
但是要注意,上面求出的p不一定就是实际要求的p,所以需要综合多组数据求解。
例:[PCTF2023]cgl
加密代码:
from Crypto.Util.number import * import base64 from random import * from secrets import flag,hint,key_number
hint=bytes_to_long(hint)
a = getPrime(256) b = getPrime(256) n = getPrime(256)
state = hint result = [] for _ inrange(5): state = (state * a + b) % n result.append(state)
from Crypto.Util.number import * import gmpy2 x = [64808739969023370119048821688797617211776674130654821075486774236651303382814, 79259085906502785899793009961165414442137337544515472474317826031734962148580, 47572752582229256276978761367590954300620113464013293239765792280017260371290, 38491979589561565391093783861378040494484383004914878495301417593240442882761, 58955289126482266943455593731576872529828229203595014577711629479455475819111] t = [] for i inrange(4): t.append(x[i+1]-x[i]) for i inrange(1,2): p = gmpy2.gcd(t[i+2]*t[i]-t[i+1]*t[i+1],t[i+1]*t[i-1]-t[i]*t[i]) a = (x[2]-x[1])*gmpy2.invert(x[1]-x[0],p)%p b = (x[1]-a*x[0])%p x = (x[0] - b) * gmpy2.invert(a, p) % p print(long_to_bytes(x))