2025-强网拟态-crypto

写了两道题,还有一道区块链的题,队友写的

Unsafe Parameters

题目:

from Crypto.Util.number import *
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
from hashlib import sha3_512
from secret import *

def genParams():
    ns = []
    es = []
    ps = []
    d = getPrime(425)
    for _ in 'flag{':
        p, q, r = [getPrime(512) for _ in range(3)]
        ps.append((p, q, r))
        n = p * q * r
        totient = (p - 1) * (q - 1) * (r - 1)
        es.append(inverse(d, totient))
        ns.append(n)

    return (ns, es), (d, ps)

pub, priv = genParams()

key = sha3_512(str(sum(sum(psum) for psum in priv[1])).encode()).digest()[:16]
ct = AES.new(key, AES.MODE_ECB).encrypt(pad(flag, 16))

print(f'ns = {pub[0]}')
print(f'es = {pub[1]}')
print(f'ct = {ct}')

"""
ns = [729626364576206469704240917876675932841677846807662743683194531189219993605123671836962855605283722577718230552963049472251011326675202612492908848548419883361685662678347011887752523869081347313358470192291106167923273619672010347904232948623232956703976722596246251219832472749781700661621717970912452690860710243752051416797956410009096107757901714990018414837758557784033898837218196380413347278999394220278929595840196278059116531409774355756772349502091527, 1905432596115201099512716986634374621489368222604315919606798930577721863294916275385323430940054377575273762764157350871093106918016952598143825002497857813393515175754983371150373414986745909170502391681896252141058196242286758315439213464335711981585004206505072743627148478873299089587473670712150938286701206231734068594554186483978059254161949801153805752489828395472590106405761648181381945795038085612905557546907903561767813822101495476457137965288880829, 1364349980724204783960363890369037262456777329397270902364257972605993939460160766530889520645888701966401869980072151818996346007664249855901114579605632358191242379651843548926065735575249122023543206153088606751338328933651430885645444839242513718915066302971957689904414300766000572990594260836480347717506097403302570129593533017205416936506156113683938133811098995666977893386015199252455279325252257306124895958614122639652100229863446635612470942945471629, 801368910415539931617837996119032301790585643652894417707002521182569449104238101253556548156062846942011258499343192564944616333555000780965111384091131074358231330717413121484815002612991437436336271715078003900216545055505405363415778086330672269759661284535787363323398929120499505051378299467980018690275341014026390376705451595348674549031968858607633947674244014656615045639930798213161815130251215148286379903187335369475976106390101774566278602818405563, 966507016385573035667733231340091844033410158675175976938028218854439065352997895173668326599042719776214706325758565722305289931861889759808022284179479582700755314576250841330755684569639628012527976286442288571350327307582007959428925460653350857512795573323486273071975979456828134582982048746188934676698845075430701350305713747666370252912970653968385390246217234899448990236850880873105998296512557366752267827688836849041157572772272378435636367162425013]
es = [271264973728317298627822473902975461834475616151421882685140849409171660245987005602120200976835072966082573357282000859946014645129524701781302678299643424924092704444611429422064341444927220441684375194952864825982915148126084102832224731498348832396834993134927447743362540828447462072582023959357845229307404791804881057335208287771899121154533179273274029972648764343120454360366227609296867085751393693129946684282269737380796082741762647814800935844443493, 1003585299728442138241618739786172474341836074346983356412903232651178484164007865852681323340512406956827176253325249434459143223478630158795320316445722303141000749369087588146876087005139101967705654538148200848735795226715484701026716263131990473014248826031226350016169675911701420383849573743077161936130739955632072650333006768068396767746102320645544271946493533626477749495460960365939362830334782483616521427745117179433129272929291131199903349977861093, 528794486797786998573050589647661205854628331390578568482905276781799068613879068393786314280307765489986817827366340249545226369795434498075653554440390174127680889163962386407937584138342055553885382937486807537913781141805602397908008361192107987266566035872632130183102501118938531330140154852996630732644530954025739132771439783366022539476194754352734861357158197716623228211860189868592877935421689151152269864018399507621324672725433395533000425391708101, 63082374875671578481986217433413118060930080658278695174993640397998104913203950822096713822227514918774669078130439943184022889683633824002111416144422250644695809731240622289790840695469043596475009958463780096705571401137513331089894183226911665633164170027318352120002851940432163291498705806239158684141492080194438572549164494596965748695244152843943149994989589419519395650481254722496058552304954140980743159877918387972030837603120258130045817858729621, 120373323462979513980656435521004077312964483601298713849302793507801996545855844801219890178210569842943901523332883574699699439655256681068585396438543716728771762620808023696864023456625376138578749985774885652016790204471223404504866831356254849552890279653807176865165230965065842479979722094076544915080001416276324550993965426099480075249719779502220020343237480355441663501565965298776708377675024327374331823503627493136287447543537154779812201209689733]
ct = b'J\x08\x0c\xfe\x0eC\n\x96!\xb3\x05\xa9\x9b\xf9\n\xe3-\xf2m\xdb&.\xb5h\xe1\x0e\xd6\x89\x14\x87Z\x0b0p\xbb\xd9\x93\xd7\x1cT\xa2\xf36\x02\x8e:\\\x92'
"""

根据论文造格

配平一下,将M=2^1024,再通过验证是不是素数来找到d

from Crypto.Util.number import isPrime
import hashlib
from gmpy2 import *
from sage.all import *
ns = [729626364576206469704240917876675932841677846807662743683194531189219993605123671836962855605283722577718230552963049472251011326675202612492908848548419883361685662678347011887752523869081347313358470192291106167923273619672010347904232948623232956703976722596246251219832472749781700661621717970912452690860710243752051416797956410009096107757901714990018414837758557784033898837218196380413347278999394220278929595840196278059116531409774355756772349502091527, 1905432596115201099512716986634374621489368222604315919606798930577721863294916275385323430940054377575273762764157350871093106918016952598143825002497857813393515175754983371150373414986745909170502391681896252141058196242286758315439213464335711981585004206505072743627148478873299089587473670712150938286701206231734068594554186483978059254161949801153805752489828395472590106405761648181381945795038085612905557546907903561767813822101495476457137965288880829, 1364349980724204783960363890369037262456777329397270902364257972605993939460160766530889520645888701966401869980072151818996346007664249855901114579605632358191242379651843548926065735575249122023543206153088606751338328933651430885645444839242513718915066302971957689904414300766000572990594260836480347717506097403302570129593533017205416936506156113683938133811098995666977893386015199252455279325252257306124895958614122639652100229863446635612470942945471629, 801368910415539931617837996119032301790585643652894417707002521182569449104238101253556548156062846942011258499343192564944616333555000780965111384091131074358231330717413121484815002612991437436336271715078003900216545055505405363415778086330672269759661284535787363323398929120499505051378299467980018690275341014026390376705451595348674549031968858607633947674244014656615045639930798213161815130251215148286379903187335369475976106390101774566278602818405563, 966507016385573035667733231340091844033410158675175976938028218854439065352997895173668326599042719776214706325758565722305289931861889759808022284179479582700755314576250841330755684569639628012527976286442288571350327307582007959428925460653350857512795573323486273071975979456828134582982048746188934676698845075430701350305713747666370252912970653968385390246217234899448990236850880873105998296512557366752267827688836849041157572772272378435636367162425013]
es = [271264973728317298627822473902975461834475616151421882685140849409171660245987005602120200976835072966082573357282000859946014645129524701781302678299643424924092704444611429422064341444927220441684375194952864825982915148126084102832224731498348832396834993134927447743362540828447462072582023959357845229307404791804881057335208287771899121154533179273274029972648764343120454360366227609296867085751393693129946684282269737380796082741762647814800935844443493, 1003585299728442138241618739786172474341836074346983356412903232651178484164007865852681323340512406956827176253325249434459143223478630158795320316445722303141000749369087588146876087005139101967705654538148200848735795226715484701026716263131990473014248826031226350016169675911701420383849573743077161936130739955632072650333006768068396767746102320645544271946493533626477749495460960365939362830334782483616521427745117179433129272929291131199903349977861093, 528794486797786998573050589647661205854628331390578568482905276781799068613879068393786314280307765489986817827366340249545226369795434498075653554440390174127680889163962386407937584138342055553885382937486807537913781141805602397908008361192107987266566035872632130183102501118938531330140154852996630732644530954025739132771439783366022539476194754352734861357158197716623228211860189868592877935421689151152269864018399507621324672725433395533000425391708101, 63082374875671578481986217433413118060930080658278695174993640397998104913203950822096713822227514918774669078130439943184022889683633824002111416144422250644695809731240622289790840695469043596475009958463780096705571401137513331089894183226911665633164170027318352120002851940432163291498705806239158684141492080194438572549164494596965748695244152843943149994989589419519395650481254722496058552304954140980743159877918387972030837603120258130045817858729621, 120373323462979513980656435521004077312964483601298713849302793507801996545855844801219890178210569842943901523332883574699699439655256681068585396438543716728771762620808023696864023456625376138578749985774885652016790204471223404504866831356254849552890279653807176865165230965065842479979722094076544915080001416276324550993965426099480075249719779502220020343237480355441663501565965298776708377675024327374331823503627493136287447543537154779812201209689733]
ct = b'J\x08\x0c\xfe\x0eC\n\x96!\xb3\x05\xa9\x9b\xf9\n\xe3-\xf2m\xdb&.\xb5h\xe1\x0e\xd6\x89\x14\x87Z\x0b0p\xbb\xd9\x93\xd7\x1cT\xa2\xf36\x02\x8e:\\\x92'
d = 79707249059210800427586261608616662408613108106616463837006013556788454508274558925787023296092333364088239266520329780878389357
# print(len(ns))

M = 2^1024
# M = 2^512
L = Matrix(ZZ, [[M, es[0], es[1], es[2], es[3], es[4]],
                [0,-ns[0],  0,  0,  0, 0],
                [0,  0,-ns[1],  0,  0, 0],
                [0,  0,  0,-ns[2],  0, 0],
                [0,  0,  0,  0,-ns[3], 0],
                [0,  0,  0,  0, 0, -ns[4]]
                ])
k = L.LLL()
for i in k:
    print(i)
    d = int(abs(i[0]) // M)
    if isPrime(d):
        print('dd:',d)
        break
#d = 79707249059210800427586261608616662408613108106616463837006013556788454508274558925787023296092333364088239266520329780878389357

找到d之后就是正常的d泄露攻击,打两次就可以得到三个因子了

from Crypto.Util.number import *
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
from hashlib import sha3_512
import random
from gmpy2 import *
ns = [729626364576206469704240917876675932841677846807662743683194531189219993605123671836962855605283722577718230552963049472251011326675202612492908848548419883361685662678347011887752523869081347313358470192291106167923273619672010347904232948623232956703976722596246251219832472749781700661621717970912452690860710243752051416797956410009096107757901714990018414837758557784033898837218196380413347278999394220278929595840196278059116531409774355756772349502091527, 1905432596115201099512716986634374621489368222604315919606798930577721863294916275385323430940054377575273762764157350871093106918016952598143825002497857813393515175754983371150373414986745909170502391681896252141058196242286758315439213464335711981585004206505072743627148478873299089587473670712150938286701206231734068594554186483978059254161949801153805752489828395472590106405761648181381945795038085612905557546907903561767813822101495476457137965288880829, 1364349980724204783960363890369037262456777329397270902364257972605993939460160766530889520645888701966401869980072151818996346007664249855901114579605632358191242379651843548926065735575249122023543206153088606751338328933651430885645444839242513718915066302971957689904414300766000572990594260836480347717506097403302570129593533017205416936506156113683938133811098995666977893386015199252455279325252257306124895958614122639652100229863446635612470942945471629, 801368910415539931617837996119032301790585643652894417707002521182569449104238101253556548156062846942011258499343192564944616333555000780965111384091131074358231330717413121484815002612991437436336271715078003900216545055505405363415778086330672269759661284535787363323398929120499505051378299467980018690275341014026390376705451595348674549031968858607633947674244014656615045639930798213161815130251215148286379903187335369475976106390101774566278602818405563, 966507016385573035667733231340091844033410158675175976938028218854439065352997895173668326599042719776214706325758565722305289931861889759808022284179479582700755314576250841330755684569639628012527976286442288571350327307582007959428925460653350857512795573323486273071975979456828134582982048746188934676698845075430701350305713747666370252912970653968385390246217234899448990236850880873105998296512557366752267827688836849041157572772272378435636367162425013]
es = [271264973728317298627822473902975461834475616151421882685140849409171660245987005602120200976835072966082573357282000859946014645129524701781302678299643424924092704444611429422064341444927220441684375194952864825982915148126084102832224731498348832396834993134927447743362540828447462072582023959357845229307404791804881057335208287771899121154533179273274029972648764343120454360366227609296867085751393693129946684282269737380796082741762647814800935844443493, 1003585299728442138241618739786172474341836074346983356412903232651178484164007865852681323340512406956827176253325249434459143223478630158795320316445722303141000749369087588146876087005139101967705654538148200848735795226715484701026716263131990473014248826031226350016169675911701420383849573743077161936130739955632072650333006768068396767746102320645544271946493533626477749495460960365939362830334782483616521427745117179433129272929291131199903349977861093, 528794486797786998573050589647661205854628331390578568482905276781799068613879068393786314280307765489986817827366340249545226369795434498075653554440390174127680889163962386407937584138342055553885382937486807537913781141805602397908008361192107987266566035872632130183102501118938531330140154852996630732644530954025739132771439783366022539476194754352734861357158197716623228211860189868592877935421689151152269864018399507621324672725433395533000425391708101, 63082374875671578481986217433413118060930080658278695174993640397998104913203950822096713822227514918774669078130439943184022889683633824002111416144422250644695809731240622289790840695469043596475009958463780096705571401137513331089894183226911665633164170027318352120002851940432163291498705806239158684141492080194438572549164494596965748695244152843943149994989589419519395650481254722496058552304954140980743159877918387972030837603120258130045817858729621, 120373323462979513980656435521004077312964483601298713849302793507801996545855844801219890178210569842943901523332883574699699439655256681068585396438543716728771762620808023696864023456625376138578749985774885652016790204471223404504866831356254849552890279653807176865165230965065842479979722094076544915080001416276324550993965426099480075249719779502220020343237480355441663501565965298776708377675024327374331823503627493136287447543537154779812201209689733]
d = 79707249059210800427586261608616662408613108106616463837006013556788454508274558925787023296092333364088239266520329780878389357


d = 79707249059210800427586261608616662408613108106616463837006013556788454508274558925787023296092333364088239266520329780878389357

def divide_pq(e, d, n):
    k = e*d - 1
    while True:
        g = random.randint(2, n-1)
        t = k
        while True:
            if t % 2 != 0:
                break
            t //= 2
            x = pow(g, t, n)
            if x > 1 and gmpy2.gcd(x-1, n) > 1:
                p = gmpy2.gcd(x-1, n)
                q = n // p
                if p > q:
                    p,q = q,p
                return (p, n//p)

p,q = divide_pq(es[1], d, ns[1])

p = 12774737533519740050102719759259244882067751682224194057168007144155383457541002357787931040518754664092488111854881718888068936571401170770883987367861823
q,r = divide_pq(es[1], d, ns[1]//p)
print(p)
print(q)
print(r)

最后把五个n的所有因子相加得到key

from Crypto.Util.number import *
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
from hashlib import sha3_512
ct = b'J\x08\x0c\xfe\x0eC\n\x96!\xb3\x05\xa9\x9b\xf9\n\xe3-\xf2m\xdb&.\xb5h\xe1\x0e\xd6\x89\x14\x87Z\x0b0p\xbb\xd9\x93\xd7\x1cT\xa2\xf36\x02\x8e:\\\x92'

key = sha3_512(str(156153497594247358765396179613649056293308992681241616288376609821218999176612095856686173629609505210284936141678187878288723742318272771805218987444978987).encode()).digest()[:16]
# ct = AES.new(key, AES.MODE_ECB).decrypt(ct)
cipher = AES.new(key, AES.MODE_ECB)
pt_padded = cipher.decrypt(ct)
print(pt_padded)
# b'flag{9b31dd3e-aa6a-4c4d-b796-bff4e4dfe0cc}\x06\x06\x06\x06\x06\x06'

FMS

题目:

import os
import pty
from Crypto.Util.number import *
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
from hashlib import sha256
from random import randrange
from string import ascii_letters, digits

flag = os.getenv('FLAG')

class PRNG:
    def __init__(self, a=None, b=None, p=None, seed=None):
        self.p = p if p else getPrime(128)
        self.a = a if a else randrange(1, self.p)
        self.b = b if b else randrange(0, self.p)
        self.state = seed if seed else randrange(0, self.p)

    def next(self):
        self.state = (self.a * self.state + self.b) % self.p
        return self.state

    def randbytes(self, n):
        out = b''
        for _ in range(n):
            out += bytes([self.next() % 256])
        return out

    def choices(self, seq, k):
        return [seq[self.next() % len(seq)] for _ in range(k)]

    def getPrime(self, n):
        while True:
            num = self.randbytes(n // 8)
            p = bytes_to_long(num) | (1 << (n - 1)) | 1
            if isPrime(p):
                return p

    def getrandbits(self, n):
        num = self.randbytes((n + 7) // 8)
        return bytes_to_long(num) & ((1 << n) - 1)

    def __repr__(self):
        return f'a = {self.a}\nb = {self.b}\np = {self.p}'

prng = PRNG()

Account = {"admin": sha256(("".join(prng.choices(ascii_letters + digits, 32))).encode()).hexdigest(),
           "guest": "84983c60f7daadc1cb8698621f802c0d9f9a3c3c295c810748fb048115c186ec"}

user = None

menu = """Flag Management System
[L]ogin
[G]et Public Key
[R]ead Flag
[E]xit"""

if __name__ == "__main__":
    while True:
        print(menu)
        op = input(">>> ").strip().upper()

        if op == "L" or op == "LOGIN":
            vcode = prng.randbytes(4).hex().rjust(8, '0')
            print(f"Verification code: {vcode}")
            username = input("Username: ").strip()
            password = input("Password: ").strip()
            verify = input("Verification code: ").strip()

            if verify != vcode:
                print("Verification code error!")
                continue

            if username in Account and Account[username] == sha256(password.encode()).hexdigest():
                print(f"Welcome, {username}!")
                user = username

            else:
                print("Login failed!")

        elif op == "G" or op == "GET PUBLIC KEY":
            print(prng)

        elif op == "R" or op == "READ FLAG":
            if user == "admin":
                key = prng.randbytes(16)
                iv = prng.randbytes(16)
                aes = AES.new(key, AES.MODE_CBC, iv)
                print(aes.encrypt(pad(flag.encode(), 16)).hex())
            else:
                print("Permission denied!")

        elif op == "E" or op == "EXIT":
            print("Goodbye!")
            exit(0)
            
        else:
            print("Invalid option!")

输入L可以得到lcg的低位,通过lcg低位攻击来得到seed1

from Crypto.Util.number import *
a = 13941520907158714473918710887539047357
b = 92853591741814007561734434801610616029
m = 320610939576252324852242294602969765103
c = 'd2b23ac5735e7fe39525ee913fc8e6a2d34d5c43babc87141536400019c2becf58c68daac9e8ddba5b30537cc3a7d074cf6e25187eb16081b90fc8592ac96490'

l = [int(c[i:i+2], 16) for i in range(0, len(c), 2)]
# print(len(l))
L = [0] + l

length = len(L)
A = [1]
B = [0]

for i in range(1,length-1):
    A.append(a*A[i-1] % m)
    B.append((a*B[i-1] + (a*L[i]+b-L[i+1])*inverse(2^8,m))%m)

A = A[1:]
B = B[1:]

Ge = Matrix(ZZ,length,length)

for i in range(len(A)):
    Ge[i,i] = m
    Ge[-2,i] = A[i]
    Ge[-1,i] = B[i]

K = m // 2**8
Ge[-2,-2] = 1
Ge[-1,-1] = K

for line in Ge.LLL():
    if abs(line[-1]) == K:
        H1 = line[-2]
        seed1 = H1 * 2**8 + L[1]
        seed = (seed1 - b) * inverse(a,m) % m
        print(f"seed = {seed}")

再倒推出admin的密码,登录admin用户

seed = 209140930315962367469101203329617119477
def get_roll():
    global seed
    seed = (seed-b)*inverse(a,m)% m
    return seed
from string import ascii_letters, digits
seq = ascii_letters + digits
messsage = ''
for i in range(32):
    messsage += seq[seed % len(seq)]
    get_roll()

print(messsage[::-1])

再使用seed1来推出key和iv,解密

def get_roll():
    global seed
    seed = (seed * a+ b)%m
    return seed
for i in range (4*18 ):
    seed = get_roll()
print(seed)

c = bytes.fromhex('e60d55df60bee9401dce922555320e56178a0a1d6154580c136b9827a89c5cfd6e631ec6a42a2d141a3350d0740b0eee')

class PRNG:
    def __init__(self, a=None, b=None, p=None, seed=None):

        self.p = 280718006317390668718774503076992098681
        self.a = 276689987123371432433371211357624822970
        self.b = 206460973139202549449013782273508368007
        self.state = 77863535934612303523447390248869048121

    def next(self):
        self.state = (self.a * self.state + self.b) % self.p
        return self.state

    def randbytes(self, n):
        out = b''
        for _ in range(n):
            out += bytes([self.next() % 256])
        return out

    def choices(self, seq, k):
        return [seq[self.next() % len(seq)] for _ in range(k)]

    def getPrime(self, n):
        while True:
            num = self.randbytes(n // 8)
            p = bytes_to_long(num) | (1 << (n - 1)) | 1
            if isPrime(p):
                return p

    def getrandbits(self, n):
        num = self.randbytes((n + 7) // 8)
        return bytes_to_long(num) & ((1 << n) - 1)

    def __repr__(self):
        return f'a = {self.a}\nb = {self.b}\np = {self.p}'

from Crypto.Cipher import AES
prng = PRNG()
key = prng.randbytes(16)
iv = prng.randbytes(16)
aes = AES.new(key, AES.MODE_CBC, iv)
print(aes.decrypt(c))