buuctf_Dest0g3_crypto
阅读原文时间:2023年07月08日阅读:1

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)

这里要先转换成字节,然后把内容拿出来写成字符串才能计算。这里我卡了很久。后面几题因为考试复习,所以没时间去看,要不要复盘看之后有没有时间再去解了。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章