buuctf_Dest0g3_crypto
babyAES:
题目如下:
from Crypto.Cipher import AES import os iv = os.urandom(16) key = os.urandom(16) my_aes = AES.new(key, AES.MODE_CBC, iv) flag = open('flag.txt', 'rb').read() flag += (16 - len(flag) % 16) * b'\x00' c = my_aes.encrypt(flag) print(c) print(iv) print(key) ''' b'C4:\x86Q$\xb0\xd1\x1b\xa9L\x00\xad\xa3\xff\x96 hJ\x1b~\x1c\xd1y\x87A\xfe0\xe2\xfb\xc7\xb7\x7f^\xc8\x9aP\xdaX\xc6\xdf\x17l=K\x95\xd07' b'\xd1\xdf\x8f)\x08w\xde\xf9yX%\xca[\xcb\x18\x80' b'\xa4\xa6M\xab{\xf6\x97\x94>hK\x9bBe]F' '''
百度简单理解一下AES加密算法,分析题目发生是CBC模式,知道了偏移量iv,密钥key,可以进行解密,脚本如下:
from Crypto.Cipher import AES c = b'C4:\x86Q$\xb0\xd1\x1b\xa9L\x00\xad\xa3\xff\x96 hJ\x1b~\x1c\xd1y\x87A\xfe0\xe2\xfb\xc7\xb7\x7f^\xc8\x9aP\xdaX\xc6\xdf\x17l=K\x95\xd07' iv = b'\xd1\xdf\x8f)\x08w\xde\xf9yX%\xca[\xcb\x18\x80' key = b'\xa4\xa6M\xab{\xf6\x97\x94>hK\x9bBe]F' cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = cipher.decrypt(c) print(decrypted.rstrip(b'\0')) # 解密完成后将加密时添加的多余字符'\0'删除
得到flag:Dest0g3{d0e5fa76-e50f-76f6-9cf1-b6c2d576b6f4}
ezDLP:
题目如下:
from Crypto.Util.number import * flag = open('flag.txt', 'rb').read() x = bytes_to_long(flag) g = 19 p = 335215034881592512312398694238485179340610060759881511231472142277527176340784432381542726029524727833039074808456839870641607412102746854257629226877248337002993023452385472058106944014653401647033456174126976474875859099023703472904735779212010820524934972736276889281087909166017427905825553503050645575935980580803899122224368875197728677516907272452047278523846912786938173456942568602502013001099009776563388736434564541041529106817380347284002060811645842312648498340150736573246893588079033524476111268686138924892091575797329915240849862827621736832883215569687974368499436632617425922744658912248644475097139485785819369867604176912652851123185884810544172785948158330991257118563772736929105360124222843930130347670027236797458715653361366862282591170630650344062377644570729478796795124594909835004189813214758026703689710017334501371279295621820181402191463184275851324378938021156631501330660825566054528793444353 h = pow(g, x, p) print(h) ''' 199533304296625406955683944856330940256037859126142372412254741689676902594083385071807594584589647225039650850524873289407540031812171301348304158895770989218721006018956756841251888659321582420167478909768740235321161096806581684857660007735707550914742749524818990843357217489433410647994417860374972468061110200554531819987204852047401539211300639165417994955609002932104372266583569468915607415521035920169948704261625320990186754910551780290421057403512785617970138903967874651050299914974180360347163879160470918945383706463326470519550909277678697788304151342226439850677611170439191913555562326538607106089620201074331099713506536192957054173076913374098400489398228161089007898192779738439912595619813699711049380213926849110877231503068464392648816891183318112570732792516076618174144968844351282497993164926346337121313644001762196098432060141494704659769545012678386821212213326455045335220435963683095439867976162 '''
dlp即离散对数问题,参考下图讲解,简单来讲就是给了g和h,h和g有关系:h=ga然后求出a。因为h和g给的数值很大,所以我们使用特殊工具sage
直接使用sage求出x,然后使用long_to_bytes()函数得到flag:
#sage g = 19 p = 335215034881592512312398694238485179340610060759881511231472142277527176340784432381542726029524727833039074808456839870641607412102746854257629226877248337002993023452385472058106944014653401647033456174126976474875859099023703472904735779212010820524934972736276889281087909166017427905825553503050645575935980580803899122224368875197728677516907272452047278523846912786938173456942568602502013001099009776563388736434564541041529106817380347284002060811645842312648498340150736573246893588079033524476111268686138924892091575797329915240849862827621736832883215569687974368499436632617425922744658912248644475097139485785819369867604176912652851123185884810544172785948158330991257118563772736929105360124222843930130347670027236797458715653361366862282591170630650344062377644570729478796795124594909835004189813214758026703689710017334501371279295621820181402191463184275851324378938021156631501330660825566054528793444353 h = 199533304296625406955683944856330940256037859126142372412254741689676902594083385071807594584589647225039650850524873289407540031812171301348304158895770989218721006018956756841251888659321582420167478909768740235321161096806581684857660007735707550914742749524818990843357217489433410647994417860374972468061110200554531819987204852047401539211300639165417994955609002932104372266583569468915607415521035920169948704261625320990186754910551780290421057403512785617970138903967874651050299914974180360347163879160470918945383706463326470519550909277678697788304151342226439850677611170439191913555562326538607106089620201074331099713506536192957054173076913374098400489398228161089007898192779738439912595619813699711049380213926849110877231503068464392648816891183318112570732792516076618174144968844351282497993164926346337121313644001762196098432060141494704659769545012678386821212213326455045335220435963683095439867976162 x = discrete_log(mod(h,p),mod(g,p)) print(x)
得到flag:Dest0g3{07ed2a6f-182f-a05d-c81e-1318af820a78}
ezStream:
题目如下:
from Crypto.Util.number import * f = open('flag.txt', 'r') flag = f.read() f.close() assert flag[:8] == "Dest0g3{" 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())) lcg = LCG() lcg.output() c = b''.join([long_to_bytes(ord(flag[i]) ^ (lcg.next() % 10)) for i in range(len(flag))]) print(bytes_to_long(c)) ''' a = 3939333498 b = 3662432446 m = 2271373817 state1 = 17362 state2 = 20624 600017039001091357643174067454938198067935635401496485588306838343558125283178792619821966678282131419050878 '''
根据题目,可以知道是流密码中LCG线性同余问题,只要得到随机数种子,就能找到lcg.next的值,继而得到flag明文。
爆破随机数种子脚本:
a = 3939333498 b = 3662432446 m = 2271373817 seed = 1 #爆破LCG的随机数种子 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 == 17362: #state1 seed2 = next1(a, b, m, seed) if seed2 == 20624: #state2 print(seed) break seed += 1 #104984523
得到随机数种子为:104984523。
所以解flag脚本如下:
from Crypto.Util.number import * a = 3939333498 b = 3662432446 m = 2271373817 #求解流密码中LCG问题 class LCG: def __init__(self): self.a = a self.b = b self.m = m self.seed = 104984523 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())) lcg = LCG() lcg.output() c = 600017039001091357643174067454938198067935635401496485588306838343558125283178792619821966678282131419050878 c_byte = long_to_bytes(c) c_str = 'Agtp6b3zd15d3017-d71f-e<83$a6kj/b`f03325>b23~' flag = b''.join([long_to_bytes(ord(c_str[i]) ^ (lcg.next() % 10)) for i in range(len(c_str))]) print(flag)
这里要先转换成字节,然后把内容拿出来写成字符串才能计算。这里我卡了很久。后面几题因为考试复习,所以没时间去看,要不要复盘看之后有没有时间再去解了。