2024四川省大學生網路安全技能大賽--crypto

qu1st發表於2024-11-15

1、easyrsa

題目
n= 23792583705374189545679156857755903878016250540127710246753745617274304389583344704113138589733408235780341088002610330172981310203101669419279485446903080470828101625401545395900167347886555843342450664942132024224786444135999300216368287067436332890329928437776400029327020705156029375574238475409752116495659018828493129602139588255157554535792454629304247981890180438731436743344841904897508802965065383721491984069867621001306958752387847700301964322000654513387170462564473333941972711152461405584672868313885993694985416498415236157186126868604410600250560806379149260093657763416193133892961340859501330212033
c1= 20344482624179256370686036034206908708335381239531009417311905765071300397395468691718790817100348515269383943649528765236951440907405197496317105096237682190221606905246946829491291624032090863992510241400499875833691618170298297747646000456790043899019441679614851630475378841533993727192042586547188012107230634176122252171485690627296622655975180422130130632386602512782202758409592494990624125296923202676271896180832187882752197279562495019041334318634399696241290423202637102319133014482875076686593996198417877270664088030146942630363075240777951239522578956341759217032833210558253469265617179208914697280264
c2= 14118150871058024400170073309352676674682694541939726874137585759501702103582881187048175033906328270645064754968042751778417450337335905517984685743917274797686821480267730116797657484594914060040840140068273430303726187874829383856918607537695283300898644995015864999016702761214033131949180432877142514076950007840181407049808048749222868732429804915587957635776177834289840628668976974267563687489817479976345457790088257816143924522593975500375007194237366313464630503093922080094547616136038831482968635954162583086125906956633581553024524746154328102746319509490067813335864118384295932089481518760770879501482
e1= 2333
e2= 23333

就是簡單的共模攻擊

exp:
import gmpy2
from Crypto.Util.number import*
n = 23792583705374189545679156857755903878016250540127710246753745617274304389583344704113138589733408235780341088002610330172981310203101669419279485446903080470828101625401545395900167347886555843342450664942132024224786444135999300216368287067436332890329928437776400029327020705156029375574238475409752116495659018828493129602139588255157554535792454629304247981890180438731436743344841904897508802965065383721491984069867621001306958752387847700301964322000654513387170462564473333941972711152461405584672868313885993694985416498415236157186126868604410600250560806379149260093657763416193133892961340859501330212033
e1 = 2333
e2 = 23333
c1 =20344482624179256370686036034206908708335381239531009417311905765071300397395468691718790817100348515269383943649528765236951440907405197496317105096237682190221606905246946829491291624032090863992510241400499875833691618170298297747646000456790043899019441679614851630475378841533993727192042586547188012107230634176122252171485690627296622655975180422130130632386602512782202758409592494990624125296923202676271896180832187882752197279562495019041334318634399696241290423202637102319133014482875076686593996198417877270664088030146942630363075240777951239522578956341759217032833210558253469265617179208914697280264
c2 =14118150871058024400170073309352676674682694541939726874137585759501702103582881187048175033906328270645064754968042751778417450337335905517984685743917274797686821480267730116797657484594914060040840140068273430303726187874829383856918607537695283300898644995015864999016702761214033131949180432877142514076950007840181407049808048749222868732429804915587957635776177834289840628668976974267563687489817479976345457790088257816143924522593975500375007194237366313464630503093922080094547616136038831482968635954162583086125906956633581553024524746154328102746319509490067813335864118384295932089481518760770879501482
s,s1,s2=gmpy2.gcdext(e1,e2)
m=(pow(c1,s1,n)*pow(c2,s2,n))%n
print(long_to_bytes(m))
#flag{L3tt3r5_70_7h3_future}

2、easyRSARSA

題目:
from Crypto.Util.number import *
from secret import flag

p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
n = p * q * r
e = 2 * 65537
m = bytes_to_long(flag)
hint1 = (p ** e - q ** e) % n
hint2 = ((2022 * p - q) ** e) % n
c = pow(m, e, n)

print('hint1=', hint1)
print('hint2=', hint2)
print('n=', n)
print('c=', c)

'''
hint1= 52281369398119567600662410538274474517133545222909276138391564372588246951556629434770221234458474257377439969412704841500791846456027747748203669565548168914696425764936947122334706087984219346335163813276457066769423286733899273378368331536658499951445074723593154096302551355270335147373146189656941967028635503538514210591235797153127984090571130062808740480476891179648059623308845204047386245441238990490866887541280568559745952068080120249721728494529636
hint2= 812269801039413894591278079358829428758036232534135221906772873437636744333426585293727772709659955393324539345478442177306013153481675848440757037566170549490328554607077425823712672804058633402840402515101422958294631642070495372150426904944019441161167313930360440965481038384894804006149168592608984721191275623676598184353692459825319078000352713036259410561499975902803368237100174518148748647427461636349234848907856305248267315083901505095210729966773183
n= 882982249031535548330341246528720199440543946466957383057449513412150447193779757566762076728954117460898887428970617025549995668574636502129794163201567120705719942956794531213763808011596771145684829464604133585457655671694348466503187597400178190815156787162601224605024975743048127298195836665757113897601684518911541677609207386837648455363901768673522248501745633727556776748089329944749837984699389705838494543515399498025589804347229817239564237664909983
c= 175198543718411501549855635400850806059246384562505102614089769131268222450487690256679800266279485952557651309227097624656742869561093126023345189879810915190851567171378500242734898632986941052386989869840615936880252213276789842406696336114243246106091230988556639836826748025596025629542690565576037754055447000774583245251787101189971189153349018453500714541907146003648880552573318011434078436075687038897589887765173313894962578176499867707815372313130165

分析:就是對於二項式定理+模運算的運用
我們的hint2是\((2022p-q)^e\)這個除了第一項為\(2022^e*p^e\),最後一項是\(q^e\),中間的項都會有\(q*p=n\)這個數字,然後我們又模上了n所以我們的除了第一項和第二項其他項都變成0了,所以我們\(hint2=2022^e*p^e+q^emod(n)\)
為什麼呢 我們舉個例子 比如說你\((q+p)^2=q^2+2pq+p^2\)是不是除了第一項和第二項只有p和q,然後中間的項或多或少都會有q和p相乘,所以這道題我們就能夠這樣化簡出我們的hint2。
然後\(hint1=p^e-q^emodn\)
\(hint2=2022^e*p^e+q^emodn\)
所以此時我們就可以透過hint1+hint2消去了我們的\(q^e\),也就是得到\(hint1+hint2=p^e*(2022^e+1)modn\)然後此時我們與n求公約數,就可以得到我們的p,在接著我們得到了p那麼同樣消去p即可,那麼我們配一個係數,就是讓我們的\(2022^emodn\)去乘上一個hint1就可以得到\(2022^e*p^e-2022^e*q^emodn\)然後讓這個式子去減去我們的hint2就可以得到\(-(2022^e+1)*q^emodn\)那麼此時就可以再次與n求公約數就可以得到q,然後我們p和q都能夠得到,r也能夠得到,就是基本的rsa解密即可。

exp:
from Crypto.Util.number import *
from gmpy2 import iroot

e = 2 * 65537
n= 882982249031535548330341246528720199440543946466957383057449513412150447193779757566762076728954117460898887428970617025549995668574636502129794163201567120705719942956794531213763808011596771145684829464604133585457655671694348466503187597400178190815156787162601224605024975743048127298195836665757113897601684518911541677609207386837648455363901768673522248501745633727556776748089329944749837984699389705838494543515399498025589804347229817239564237664909983
c= 175198543718411501549855635400850806059246384562505102614089769131268222450487690256679800266279485952557651309227097624656742869561093126023345189879810915190851567171378500242734898632986941052386989869840615936880252213276789842406696336114243246106091230988556639836826748025596025629542690565576037754055447000774583245251787101189971189153349018453500714541907146003648880552573318011434078436075687038897589887765173313894962578176499867707815372313130165
hint1= 52281369398119567600662410538274474517133545222909276138391564372588246951556629434770221234458474257377439969412704841500791846456027747748203669565548168914696425764936947122334706087984219346335163813276457066769423286733899273378368331536658499951445074723593154096302551355270335147373146189656941967028635503538514210591235797153127984090571130062808740480476891179648059623308845204047386245441238990490866887541280568559745952068080120249721728494529636
hint2= 812269801039413894591278079358829428758036232534135221906772873437636744333426585293727772709659955393324539345478442177306013153481675848440757037566170549490328554607077425823712672804058633402840402515101422958294631642070495372150426904944019441161167313930360440965481038384894804006149168592608984721191275623676598184353692459825319078000352713036259410561499975902803368237100174518148748647427461636349234848907856305248267315083901505095210729966773183
p = GCD(hint2 + hint1, n)
q = GCD(pow(2022,e,n)*hint1 - hint2, n)
r = n//p//q
print(p)
print(q)
print(r)
d = inverse(e//2, (p-1)*(q-1)*(r-1))
m = pow(c,d,n)
m = iroot(m, 2)
print(m)
print(long_to_bytes(m[0]))

3、random

題目:
import random
from Crypto.Util.number import *

with open('flag') as (f):
    flag = list(f.read())
p=getPrime(23)
g=2
a=random.randint(g,p-1)
b=random.randint(g,p-1)
k=pow(g,a*b,p)
print(p)

random.seed(k)
for i in range(0,len(flag),2):
    flag[i],flag[i+1]=flag[i+1],flag[i]
else:
    random.shuffle(flag)
print(flag)


# 5037523
# ['1', '0', 'a', '}', 'b', '0', '9', 'c', 'b', '9', 'a', 'g', '-', '-', 'c', '0', '1', 'c', '9', '4', 'e', '3', '{', 'f', 'f', '7', '1', 'c', 'l', '0', '7', 'e', '6', '9', '8', 'b', '7', '-', 'a', '-', 'f', '3']

這裡的加密關鍵步驟就是在最後的倆步,將相鄰字元的順序交換(flag[i] 和 flag[i+1] 互換)。對字元列表進行隨機打亂(random.shuffle(flag)),隨機種子取自 k=pow(g, a*b, p),這裡使用。
所以我們這裡暴力破解出我們的k,然後再次透過flag的頭的格式來爆破出我們的flag。

exp:
import random
from Crypto.Util.number import getPrime

p = 5037523
mixed_flag = ['1', '0', 'a', '}', 'b', '0', '9', 'c', 'b', '9', 'a', 'g', '-', '-', 'c', '0', '1', 'c', '9', '4', 'e', '3', '{', 'f', 'f', '7', '1', 'c', 'l', '0', '7', 'e', '6', '9', '8', 'b', '7', '-', 'a', '-', 'f', '3']  # 示例加密 flag,請替換為實際的加密結果

g = 2
found = False
for a in range(g, p):
    for b in range(g, p):
        k = pow(g, a * b, p)
        random.seed(k)

        indices = list(range(len(mixed_flag)))
        random.shuffle(indices)

        original_flag = [''] * len(mixed_flag)
        for original_index, shuffled_index in enumerate(indices):
            original_flag[shuffled_index] = mixed_flag[original_index]

        for i in range(0, len(original_flag), 2):
            if i + 1 < len(original_flag):  # 確保沒有越界
                original_flag[i], original_flag[i + 1] = original_flag[i + 1], original_flag[i]

        # 輸出恢復後的 flag
        recovered_flag = ''.join(original_flag)

        # 檢查恢復的 flag 是否符合格式
        if recovered_flag.startswith('flag{') and recovered_flag.endswith('}'):
            print(f"Recovered flag: {recovered_flag}")
            found = True
            break
    if found:
        break

if not found:
    print("No valid flag found.")

今年的四川省省賽的crypto很簡單,真的只需要好好想一下就出來了。

相關文章