Before_Sunset
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from Crypto.Util.number import *from hashlib import sha256from Crypto.Cipher import AESfrom random import *from Crypto.Util.Padding import *flag = b'flag{XXXXXXXXX}' note = b'Before_Sunset*xt' keys = [] for i in range (4 ): key = bytes (choices(note,k=3 )) keys.append(sha256(key).digest()) cipher = b'happy_newyear!!!' for i in range (4 ): cipher = AES.new(keys[i], AES.MODE_ECB).encrypt(cipher) enkey = sha256(b"" .join(keys)).digest() enflag = AES.new(enkey,AES.MODE_ECB).encrypt(pad(flag,AES.block_size)) print (f'cipher = {cipher} ' )print (f'enflag = {enflag} ' )""" cipher = b'4\xf6\x89\x81:\xd7\xf4\xc4\xad\xb1)\x99\xb1l\xe2\x7f' enflag = b'\x964\xdcq\xcc\xe9\xde\xfe=\xfb\x08\\\x9e\xe3\xf5\xef^\x9c\x11\xaa\xb8\x97\xe61\x1ee\xe4dV\x0c\x1c\xf7 \xabX]\x92\xd6\xa3\xdegD\xbb\xbd\x98\x90\xeb~' """ aaaaa
用 note
生成了 4 个密钥(每个是从 note
中随机选 3 字节,再 SHA256 得到 32 字节 AES 密钥)
用这些密钥对一个固定明文 P = b"happy_newyear!!!"
连续加密 4 次,得到 cipher = C4
;
把这 4 个密钥拼起来 SHA256 出 enkey
,用它对 flag 做
AES-ECB 加密(带 PKCS#7 padding),得到 enflag
。
采用的是相遇攻击的思想
所有 (K0, K1)
组合下的结果 c2
存进字典
map_fw
,键是加密结果,值是 K0 和 K1 的索引。
构建完后,map_fw
是一个【中间密文 →
密钥对】的快速查找表。
对每个 (K3, K2)
组合,从最终密文 C4
开始反向解密:
判断 c2
是否在前向字典里 ——
如果找到了,说明这两个密钥和前面对应的 (K0,K1)
正好组成了一组正确密钥
简单来说就是一边通过前半段的寻找建字典然后一边查
EXP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 from itertools import productfrom hashlib import sha256from Crypto.Cipher import AESfrom Crypto.Util.Padding import unpadP = b"happy_newyear!!!" C4 = b"4\xf6\x89\x81:\xd7\xf4\xc4\xad\xb1)\x99\xb1l\xe2\x7f" enflag = b'\x964\xdcq\xcc\xe9\xde\xfe=\xfb\x08\\\x9e\xe3\xf5\xef^\x9c\x11\xaa\xb8\x97\xe61\x1ee\xe4dV\x0c\x1c\xf7 \xabX]\x92\xd6\xa3\xdegD\xbb\xbd\x98\x90\xeb~' note = b"Before_Sunset*xt" key3_list = [bytes (k) for k in product(note, repeat=3 )] aes_keys = [sha256(k3).digest() for k3 in key3_list] map_fw = {} for i, K0 in enumerate (aes_keys): c1 = AES.new(K0, AES.MODE_ECB).encrypt(P) for j, K1 in enumerate (aes_keys): c2 = AES.new(K1, AES.MODE_ECB).encrypt(c1) map_fw[c2] = (i, j) found = None for l, K3 in enumerate (aes_keys): c3 = AES.new(K3, AES.MODE_ECB).decrypt(C4) for k, K2 in enumerate (aes_keys): c2_prime = AES.new(K2, AES.MODE_ECB).decrypt(c3) if c2_prime in map_fw: i, j = map_fw[c2_prime] K0, K1 = aes_keys[i], aes_keys[j] found = (K0, K1, K2, K3) break if found: break if not found: raise ValueError("没找到密钥组合!" ) K0, K1, K2, K3 = found print ("找到四个 AES 密钥!" )enkey = sha256(K0 + K1 + K2 + K3).digest() plain = unpad(AES.new(enkey, AES.MODE_ECB).decrypt(enflag), AES.block_size) print ("Flag =" , plain)
See you again
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 from random import *import stringfrom Crypto.Util.number import *from sage.all import *flag = b'flag{XXXXXXXXXXXXX}' ext_len = 4 *23 - len (flag) flag += '' .join(choice(string.printable) for _ in range (ext_len)) def my_rsa_encrypt (): p = getPrime(512 ) q = getPrime(512 ) n = p * q data = [] for i in range (4 ): data.append(bytes_to_long(flag[23 *i:23 *(i+1 )].encode())) M = Matrix(Zmod(n), [data[i:i+2 ] for i in range (0 , len (data), 2 )]) e = 65537 C = M**e x1=randint(0 ,2 **11 ) y1=randint(0 ,2 **114 ) x2=randint(0 ,2 **11 ) y2=randint(0 ,2 **514 ) hint1=x1*p+y1*q hint2=x2*p+y2*q print ("hint1 =" , hint1) print ("hint2 =" , hint2) print ("n =" , n) return C C = my_rsa_encrypt() print ("C =" , C)''' hint1 = 168265279404811256277233395102642358475458409482403711393035752197600859883963939768385846094966123277287664746626323932557461116229847433749541823928128333856483359321776317487696165625065 hint2 = 388525731960756845976560311958832822501361876609762739131361346349184345486942393347353228412856257245501810230005909157804781984160852691049705221909148849268628655156230494562410040271685185427100514456092002902461455124227295965928975113228265630904429459035860216889967825964526267040037892094324439719411 n = 73072541902206871020737492238712393160727227031674788366854370087046494314953414149210811810993251599137993812618059430654795580640655927531189983107761278404614174799313759634478308102715209502959314132742690028687179640727016334879648957747421327650216141691465903844138851357328611067635106605344718049129 C = [ 6310748775703051581154234569431184868982413857734351142080359008436987630184616677942361392389551047027017330071293367514311142151815936199483256586417636348041649876709276752266778499479183523443148337562720814581572407854278542331966812940447535783779656684256297221348716866635101085755860498353339242115 5144330870923367619389647825281339367482009106753859407075628907488466365472218688907933875894666639770145465222088465870419295906638236631404037390832689261596431619354248820909813429665843949224111735121883894006720533494334946354541598413794931072951879543749090953489715640123785787585906571296066228337] [33291873086307192132352453738238356328226272776193653137970607851693478963529798496768193693023879049338380362901921264407689229849253505523956752578525472920304538365514116510285387059498125392190213470841105539220357787132908727038425638513550855537375794144340611979256932750425138088529265202217417349326 8710391985351492354130113806218295166875250333985231739921757023007679201614662002300751925094702862907693146762459566351810351082709246293390023137646644466382528873636039529534916744087376534336847024714465012051303713158199842172134865427319373041223732135032837752292040371239661190751800891412327395907] '''
审计代码,该题中将flag分成了四给块,以此构成了一个2*2类型的密文矩阵,其他采取的是常规RSA加密的形式,
并且泄露了hint1和hint2 h i n t 1 = x 1 * p + y 1 * q
h i n t 2 = x 2 * p + y 2 * q
其中的x1和x2为(0-2048)随机数
y1和y2为2^114位数
我们需要利用数学关系约分得到p和q
为了约分hin1和hin2
我们需要建立式子 x 1 * h i n t 2 − x 2 * h i n t 1
= x 1 * (x 2 * p + y 2 * q ) − x 2 * (x 1 * p + y 1 * q )
= x 1 * x 2 * p + x 1 * y 2 * q − x 2 * x 1 * p − x 2 * y 1 * q
= x 1 * y 2 * q − x 2 * y 1 * q
= q * (x 1 * y 2 − x 2 * y 1)
然后将这个式子与n求最大公约数即可分解n
1 gcd(x1 * hint2 - x2 * hint1, n) = gcd(q * something, p * q) = q
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 import mathhint1 = 168265279404811256277233395102642358475458409482403711393035752197600859883963939768385846094966123277287664746626323932557461116229847433749541823928128333856483359321776317487696165625065 hint2 = 388525731960756845976560311958832822501361876609762739131361346349184345486942393347353228412856257245501810230005909157804781984160852691049705221909148849268628655156230494562410040271685185427100514456092002902461455124227295965928975113228265630904429459035860216889967825964526267040037892094324439719411 n = 73072541902206871020737492238712393160727227031674788366854370087046494314953414149210811810993251599137993812618059430654795580640655927531189983107761278404614174799313759634478308102715209502959314132742690028687179640727016334879648957747421327650216141691465903844138851357328611067635106605344718049129 hint1_mod_n = hint1 % n hint2_mod_n = hint2 % n for x1 in range (0 , 2049 ): for x2 in range (0 , 2049 ): if x1 == 0 and x2 == 0 : continue term1 = (x1 * hint2_mod_n) % n term2 = (x2 * hint1_mod_n) % n candidate_mod_n = (term1 - term2) % n current_gcd = math.gcd(candidate_mod_n, n) if current_gcd > 1 : print (f"Found factors with x1={x1} , x2={x2} " ) p = current_gcd q = n // current_gcd print ("p =" , p) print ("q =" , q) exit() p = 9840199651059680279315545552078195603933414815185149988850805053207130958990873093781755127037056517374437691746406285746154497813695817556539648065445111 q = 7425920661511961227328493926307082700428726975369330043535693658853751767178547931292974567810134212365247300045094600690928968177216378782623096259591839 n = p * q phi = (p - 1 ) * (q - 1 ) e = 65537 d = inverse_mod(e, phi) c11 = 6310748775703051581154234569431184868982413857734351142080359008436987630184616677942361392389551047027017330071293367514311142151815936199483256586417636348041649876709276752266778499479183523443148337562720814581572407854278542331966812940447535783779656684256297221348716866635101085755860498353339242115 c12 = 5144330870923367619389647825281339367482009106753859407075628907488466365472218688907933875894666639770145465222088465870419295906638236631404037390832689261596431619354248820909813429665843949224111735121883894006720533494334946354541598413794931072951879543749090953489715640123785787585906571296066228337 c21 = 33291873086307192132352453738238356328226272776193653137970607851693478963529798496768193693023879049338380362901921264407689229849253505523956752578525472920304538365514116510285387059498125392190213470841105539220357787132908727038425638513550855537375794144340611979256932750425138088529265202217417349326 c22 = 8710391985351492354130113806218295166875250333985231739921757023007679201614662002300751925094702862907693146762459566351810351082709246293390023137646644466382528873636039529534916744087376534336847024714465012051303713158199842172134865427319373041223732135032837752292040371239661190751800891412327395907 R = Zmod(n) C = Matrix(R, [[c11, c12], [c21, c22]]) M = C ** d from Crypto.Util.number import long_to_bytesdata = [] for row in M: for element in row: data.append(long_to_bytes(int (element))) flag = b'' .join(data) print (flag.decode())