635 words
3 minutes
御网杯 2026 复现
因为没打御网杯,所以问 Lamb 学妹要了题复现一下看看。
Crypto
BabyRSA
题目:
from Crypto.Util.number import bytes_to_long, getPrimefrom secret import flag
m = bytes_to_long(flag)e = 3
p = getPrime(512)q = getPrime(512)n = p * q
c = pow(m, e, n)
print(f"n = {n}")print(f"e = {e}")print(f"c = {c}")签到题,对c + k * n开三次根找flag就行(本题中直接对c开即可)。
exp.py:
from gmpy2 import irootfrom Crypto.Util.number import long_to_bytes
n = 106376708471638081356023241888652175743260071488862952322696441188500330953258762786909460198563614242640037648446773201494442383628725589189230563631047713207930813772004230385987574126969015874307576382328088151347177772790519879585263208787209747491607370703131250822062490952064568038598955428368247262989e = 3c = 2217344750798176987884922681016983401499645893525707818415742269785793369334864878621546637030713277893458149668533117349008039140359740471790484492703060384410958650758080292114663603623769028805539666282734724093278095429393220973912927452539157520935554837926799000926309for k in range(10000): res = iroot(c + k * n, e) if res[1]: m = int(res[0]) print(long_to_bytes(m).decode()) break# flag{01412463306735a1bcace3b5d20293f1}ScatterRSA
题目:
from secret import flagfrom Crypto.Util.number import *import random
m = bytes_to_long(flag)e = 3
print(f"e = {e}")
for i in range(3): p = getPrime(512) q = getPrime(512) n = p * q a = random.getrandbits(128) | (1 << 127) b = random.getrandbits(256) | (1 << 255) c = pow(a * m + b, e, n)
print(f"n{i+1} = {n}") print(f"a{i+1} = {a}") print(f"b{i+1} = {b}") print(f"c{i+1} = {c}")题目给出三组数据:
其中,a为 128-bit,b为 256-bit,e = 3。
也就是说我们可以得到三个如下形式且都有一个小根x = m的多项式:
将其通过CRT合并后得到一个模N = n1 * n2 * n3域下的多项式,此时N很大而x很小,直接 CopperSmith 打出x即可。
exp.py:
# SageMath 10.7from Crypto.Util.number import long_to_bytes
e = 3n1 = 78406644063412330827144269082165693855524775872040115517201173073443410480229769568274148648378599447340559212013136304104371398343431564153428535062874800376311265127625727766687101716232202416348874941159422385827020377234200304383339914279306109539295055950771168695795983450922479086642719974951568001123a1 = 179069785188197128063735833062298282088b1 = 108602310920516135899953625199026479831613528130098983765509775304380481049236c1 = 63252812179719365415824095661395699873619221281620649284116525456495492657969128347395906262694181920298642514886137258913612425874543244412361141570055505065364160387485022351593955914517007934817693712484398995438325025790526298775819525749798156105149707900940592786793945170245658868658074048714286848360n2 = 95020468976740939492744504421572718358377589957590862534596426944713745697519407316474954374220717547414847190383624684829981365714162496004205923099654648343561409997185055826399789260059018296236445634896974399171937408534594770556492595577486034736886981715897932731287622893964944487359432563222589773169a2 = 256937765435419090013996554824329198102b2 = 106194089384191278641160829411989148866555891040956845008761670010296097473891c2 = 69189455762124018990354259751049315347885716276141026926254387098606184767677119541615753786850384135301904271598568283598341309350338300849980006939154544582117288358462253645929195237077943587484536869068620740282202954818087710662521305731662434404639604765467522290344380872734642898064819919222866525595n3 = 76327387850259066558503241279944367595819739218711435387090070188701489593268018671200393965036334822971788731105131043689617213814536539958962946216274727013886635077932479201396877992034094563923228010894175882636493331356330645383301647712606020240651124738679361743860337944932489521911308225518554189671a3 = 230197610510629587425547735570441529186b3 = 102036531983721422375656270902750955826372568198958868967463605609586959104862c3 = 70530911982806921131468678265423284512112079960880985596519011279227498232312624801272691438407551711362218333097001183623780244884146290664329110735889965737872515329899563749587762154521351009913925896897262019326623455825827780598885978929696497223116909384396989202217844912113182815342075250443286215518N = n1 * n2 * n3params = [(n1, a1, b1, c1), (n2, a2, b2, c2), (n3, a3, b3, c3)]R = Zmod(N)['x']x = R.gen()coeffs = []for deg in range(4): coeffs_mod = [] for n, a, b, c in params: poly = (a * x + b) ** e - c coeffs_mod.append(ZZ(poly[deg]) % n) coeffs.append(crt(coeffs_mod, [n for n, _, _, _ in params]))f = sum(coeffs[deg] * x ** deg for deg in range(4)).monic()roots = f.small_roots(X=2**512, beta=0.34, epsilon=0.05)print(long_to_bytes(ZZ(roots[0])).decode())# flag{82a05145b36137b03a83e7f0ff974472}ECDSA
题目:
{ "public_key_x": 32278952872456905780547099814767063939618086688091564927040207716943270835518, "public_key_y": 93846569305589930548786857142802880745325076740913072568852571412159575637982, "message1": "57656c636f6d6520746f2074686520435446206368616c6c656e676521", "message2": "506c65617365207265636f766572207468652073656372657420666c61672e", "signature1_r": 42578704313794367821723835270379231244352828328579180961262224566499528870073, "signature1_s": 61517967644966080965941217493019375085650749498249064881177432677183620596205, "signature2_r": 42578704313794367821723835270379231244352828328579180961262224566499528870073, "signature2_s": 20743684232977419667933391628349856033378723646037279217784454422133981848103, "curve": "SECP256k1"}题目名似乎直接说了nonce重用,仔细看看题目数据会发现r也是一样的。从签名公式开始浅推一下:
当k重用时:
两式相减:
再代回任一签名等式即可恢复私钥:
exp.py:
from hashlib import sha256from Crypto.Util.number import inverse
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141public_key_x = 32278952872456905780547099814767063939618086688091564927040207716943270835518public_key_y = 93846569305589930548786857142802880745325076740913072568852571412159575637982message1 = "57656c636f6d6520746f2074686520435446206368616c6c656e676521"message2 = "506c65617365207265636f766572207468652073656372657420666c61672e"signature1_r = 42578704313794367821723835270379231244352828328579180961262224566499528870073signature1_s = 61517967644966080965941217493019375085650749498249064881177432677183620596205signature2_r = 42578704313794367821723835270379231244352828328579180961262224566499528870073signature2_s = 20743684232977419667933391628349856033378723646037279217784454422133981848103z1 = int(sha256(bytes.fromhex(message1)).hexdigest(), 16)z2 = int(sha256(bytes.fromhex(message2)).hexdigest(), 16)k = (z1 - z2) * inverse(signature1_s - signature2_s, n) % nd = (signature1_s * k - z1) * inverse(signature1_r, n) % nflag = f"flag{{ecdsa_nonce_reuse_{hex(d)[2:][:32]}}}"print(flag)# flag{ecdsa_nonce_reuse_d35fe9a03a2162fd5441bb19346d95fd}ECB
网上找到的wp传送门,神题我只能说。
exp.py:
from Crypto.Cipher import AESfrom Crypto.Util.Padding import unpad
c = open("ciphertext.bin", "rb").read()key = b'VERY_SECRET_KEY!'cipher = AES.new(key, AES.MODE_ECB)m = unpad(cipher.decrypt(c), 16).decode()print(m)# CTF{SECRET_FLAG:flag{c2jqvo7s6dfnkjuobt1x7hfksa9cp7pu}}END_OF_FLAG 御网杯 2026 复现
https://q1uju.cc/posts/御网杯2026复现/ Some information may be outdated









