2024 网鼎杯 CTF --- Crypto wp
文章目录
- 青龙组
- Crypto1
- Crypto2
- 白虎组
- Crypto1
- Crypto2
- 朱雀组
- Crypto2
- Crypto3
- part1
- part2
- part3
- part4
青龙组
Crypto1
题目:
from Crypto.Util.number import *
from secret import flagp = getPrime(512)
q = getPrime(512)
n = p * q
d = getPrime(299)
e = inverse(d,(p-1)*(q-1))
m = bytes_to_long(flag)
c = pow(m,e,n)
hint1 = p >> (512-70)
hint2 = q >> (512-70)print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
print(f"hint1 = {hint1}")
print(f"hint2 = {hint2}")n = 123789043095302886784777548580725867919630872720308267296330863659260260632444171595208750648710642616709290340791408935502415290984231140635423328808872594955139658822363033096014857287439409252367248420356169878044065798634016290690979979625051287064109800759113475629317869327100941592970373827299442569489
e = 112070481298571389221611833986644006256566240788306316765530852688390558290807060037831460397016038678699757261874520899143918664293504728402666398893964929840011110057060969775245481057773655679041350091817099143204028098431544760662690479779286160425059494739419234859710815966582837874194763305328789592245
c = 63662561509209168743977531923281040338804656992093161358503738280395090747786427812762995865224617853709000826994250614233562094619845247321880231488631212423212167167713869682181551433686816142488666533035193128298379649809096863305651271646535125466745409868274019550361728139482502448613835444108383177119hint1 = 897446442156802074692
hint2 = 1069442646630079275131
论文:367.pdf
高位boneh_durfee攻击
exp:
import time
time.clock = time.timedebug = Truestrict = Falsehelpful_only = True
dimension_min = 7 # 如果晶格达到该尺寸,则停止移除
# 显示有用矢量的统计数据
def helpful_vectors(BB, modulus):nothelpful = 0for ii in range(BB.dimensions()[0]):if BB[ii,ii] >= modulus:nothelpful += 1# 显示带有 0 和 X 的矩阵
def matrix_overview(BB, bound):for ii in range(BB.dimensions()[0]):a = ('%02d ' % ii)for jj in range(BB.dimensions()[1]):a += '0' if BB[ii,jj] == 0 else 'X'if BB.dimensions()[0] < 60: a += ' 'if BB[ii, ii] >= bound:a += '~'#print (a)# 尝试删除无用的向量
# 从当前 = n-1(最后一个向量)开始
def remove_unhelpful(BB, monomials, bound, current):# 我们从当前 = n-1(最后一个向量)开始if current == -1 or BB.dimensions()[0] <= dimension_min:return BB# 开始从后面检查for ii in range(current, -1, -1):# 如果它没有用if BB[ii, ii] >= bound:affected_vectors = 0affected_vector_index = 0# 让我们检查它是否影响其他向量for jj in range(ii + 1, BB.dimensions()[0]):# 如果另一个向量受到影响:# 我们增加计数if BB[jj, ii] != 0:affected_vectors += 1affected_vector_index = jj# 等级:0# 如果没有其他载体最终受到影响# 我们删除它if affected_vectors == 0:#print ("* removing unhelpful vector", ii)BB = BB.delete_columns([ii])BB = BB.delete_rows([ii])monomials.pop(ii)BB = remove_unhelpful(BB, monomials, bound, ii-1)return BB# 等级:1#如果只有一个受到影响,我们会检查# 如果它正在影响别的向量elif affected_vectors == 1:affected_deeper = Truefor kk in range(affected_vector_index + 1, BB.dimensions()[0]):# 如果它影响哪怕一个向量# 我们放弃这个if BB[kk, affected_vector_index] != 0:affected_deeper = False# 如果没有其他向量受到影响,则将其删除,并且# 这个有用的向量不够有用#与我们无用的相比if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]):#print ("* removing unhelpful vectors", ii, "and", affected_vector_index)BB = BB.delete_columns([affected_vector_index, ii])BB = BB.delete_rows([affected_vector_index, ii])monomials.pop(affected_vector_index)monomials.pop(ii)BB = remove_unhelpful(BB, monomials, bound, ii-1)return BB# nothing happenedreturn BB"""
Returns:
* 0,0 if it fails
* -1,-1 如果 "strict=true",并且行列式不受约束
* x0,y0 the solutions of `pol`
"""
def boneh_durfee(pol, modulus, mm, tt, XX, YY):"""Boneh and Durfee revisited by Herrmann and May在以下情况下找到解决方案:
* d < N^delta
* |x|< e^delta
* |y|< e^0.5
每当 delta < 1 - sqrt(2)/2 ~ 0.292"""# substitution (Herrman and May)PR.<u, x, y> = PolynomialRing(ZZ) #多项式环Q = PR.quotient(x*y + 1 - u) # u = xy + 1polZ = Q(pol).lift()UU = XX*YY + 1# x-移位gg = []for kk in range(mm + 1):for ii in range(mm - kk + 1):xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kkgg.append(xshift)gg.sort()# 单项式 x 移位列表monomials = []for polynomial in gg:for monomial in polynomial.monomials(): #对于多项式中的单项式。单项式():if monomial not in monomials: # 如果单项不在单项中monomials.append(monomial)monomials.sort()# y-移位for jj in range(1, tt + 1):for kk in range(floor(mm/tt) * jj, mm + 1):yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk)yshift = Q(yshift).lift()gg.append(yshift) # substitution# 单项式 y 移位列表for jj in range(1, tt + 1):for kk in range(floor(mm/tt) * jj, mm + 1):monomials.append(u^kk * y^jj)# 构造格 Bnn = len(monomials)BB = Matrix(ZZ, nn)for ii in range(nn):BB[ii, 0] = gg[ii](0, 0, 0)for jj in range(1, ii + 1):if monomials[jj] in gg[ii].monomials():BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)#约化格的原型if helpful_only:# #自动删除BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1)# 重置维度nn = BB.dimensions()[0]if nn == 0:print ("failure")return 0,0# 检查向量是否有帮助if debug:helpful_vectors(BB, modulus^mm)# 检查行列式是否正确界定det = BB.det()bound = modulus^(mm*nn)if det >= bound:print ("We do not have det < bound. Solutions might not be found.")print ("Try with highers m and t.")if debug:diff = (log(det) - log(bound)) / log(2)print ("size det(L) - size e^(m*n) = ", floor(diff))if strict:return -1, -1else:print ("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")# display the lattice basisif debug:matrix_overview(BB, modulus^mm)# LLLif debug:print ("optimizing basis of the lattice via LLL, this can take a long time")#BB = BB.BKZ(block_size=25)BB = BB.LLL()if debug:print ("LLL is done!")# 替换向量 i 和 j ->多项式 1 和 2if debug:print ("在格中寻找线性无关向量")found_polynomials = Falsefor pol1_idx in range(nn - 1):for pol2_idx in range(pol1_idx + 1, nn):# 对于i and j, 构造两个多项式PR.<w,z> = PolynomialRing(ZZ)pol1 = pol2 = 0for jj in range(nn):pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY)pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)# 结果PR.<q> = PolynomialRing(ZZ)rr = pol1.resultant(pol2)if rr.is_zero() or rr.monomials() == [1]:continueelse:print ("found them, using vectors", pol1_idx, "and", pol2_idx)found_polynomials = Truebreakif found_polynomials:breakif not found_polynomials:print ("no independant vectors could be found. This should very rarely happen...")return 0, 0rr = rr(q, q)# solutionssoly = rr.roots()if len(soly) == 0:print ("Your prediction (delta) is too small")return 0, 0soly = soly[0][0]ss = pol1(q, soly)solx = ss.roots()[0][0]return solx, solydef example():############################################# 随机生成数据###########################################start_time =time.perf_counterstart =time.clock()size=512length_N = 2*size;ss=0s=70;M=1 # the number of experimentsdelta = 299/1024# p = random_prime(2^512,2^511)for i in range(M):
# p = random_prime(2^size,None,2^(size-1))
# q = random_prime(2^size,None,2^(size-1))
# if(p<q):
# temp=p
# p=q
# q=tempN = 123789043095302886784777548580725867919630872720308267296330863659260260632444171595208750648710642616709290340791408935502415290984231140635423328808872594955139658822363033096014857287439409252367248420356169878044065798634016290690979979625051287064109800759113475629317869327100941592970373827299442569489e = 112070481298571389221611833986644006256566240788306316765530852688390558290807060037831460397016038678699757261874520899143918664293504728402666398893964929840011110057060969775245481057773655679041350091817099143204028098431544760662690479779286160425059494739419234859710815966582837874194763305328789592245c = 63662561509209168743977531923281040338804656992093161358503738280395090747786427812762995865224617853709000826994250614233562094619845247321880231488631212423212167167713869682181551433686816142488666533035193128298379649809096863305651271646535125466745409868274019550361728139482502448613835444108383177119hint1 = 897446442156802074692 # p高位hint2 = 1069442646630079275131 # q高位
# print ("p真实高",s,"比特:", int(p/2^(512-s)))
# print ("q真实高",s,"比特:", int(q/2^(512-s)))# N = p*q;# 解密指数d的指数( 最大0.292)m = 7 # 格大小(越大越好/越慢)t = round(((1-2*delta) * m)) # 来自 Herrmann 和 May 的优化X = floor(N^delta) # Y = floor(N^(1/2)/2^s) # 如果 p、 q 大小相同,则正确for l in range(int(hint1),int(hint1)+1):print('\n\n\n l=',l)pM=l;p0=pM*2^(size-s)+2^(size-s)-1;q0=N/p0;qM=int(q0/2^(size-s))A = N + 1-pM*2^(size-s)-qM*2^(size-s);#A = N+1P.<x,y> = PolynomialRing(ZZ)pol = 1 + x * (A + y) #构建的方程# Checking bounds#if debug:#print ("=== 核对数据 ===")#print ("* delta:", delta)#print ("* delta < 0.292", delta < 0.292)#print ("* size of e:", ceil(log(e)/log(2))) # e的bit数# print ("* size of N:", len(bin(N))) # N的bit数#print ("* size of N:", ceil(log(N)/log(2))) # N的bit数#print ("* m:", m, ", t:", t)# boneh_durfeeif debug:##print ("=== running algorithm ===")start_time = time.time()solx, soly = boneh_durfee(pol, e, m, t, X, Y)if solx > 0:#print ("=== solution found ===")if False:print ("x:", solx)print ("y:", soly)d_sol = int(pol(solx, soly) / e)ss=ss+1print ("=== solution found ===")print ("p的高比特为:",l)print ("q的高比特为:",qM)print ("d=",d_sol) if debug:print("=== %s seconds ===" % (time.time() - start_time))#breakprint("ss=",ss)#end=time.process_timeend=time.clock()print('Running time: %s Seconds'%(end-start))
if __name__ == "__main__":example()
解出d
d = 815288165251971990144240125719456676622201418787728487985993940108011619486967079496288981
接着RSA解密
n = 123789043095302886784777548580725867919630872720308267296330863659260260632444171595208750648710642616709290340791408935502415290984231140635423328808872594955139658822363033096014857287439409252367248420356169878044065798634016290690979979625051287064109800759113475629317869327100941592970373827299442569489
e = 112070481298571389221611833986644006256566240788306316765530852688390558290807060037831460397016038678699757261874520899143918664293504728402666398893964929840011110057060969775245481057773655679041350091817099143204028098431544760662690479779286160425059494739419234859710815966582837874194763305328789592245
c = 63662561509209168743977531923281040338804656992093161358503738280395090747786427812762995865224617853709000826994250614233562094619845247321880231488631212423212167167713869682181551433686816142488666533035193128298379649809096863305651271646535125466745409868274019550361728139482502448613835444108383177119
d = 815288165251971990144240125719456676622201418787728487985993940108011619486967079496288981
m = pow(c,d,n)
flag = bytes.fromhex(hex(m)[2:])
print(flag)
Crypto2
题目:
# coding: utf-8
#!/usr/bin/env python2import gmpy2
import random
import binascii
from hashlib import sha256
from sympy import nextprime
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.number import long_to_bytes
from FLAG import flag
#flag = 'wdflag{123}'def victory_encrypt(plaintext, key):key = key.upper()key_length = len(key)plaintext = plaintext.upper()ciphertext = ''for i, char in enumerate(plaintext):if char.isalpha():shift = ord(key[i % key_length]) - ord('A')encrypted_char = chr((ord(char) - ord('A') + shift) % 26 + ord('A'))ciphertext += encrypted_charelse:ciphertext += charreturn ciphertextvictory_key = "WANGDINGCUP"
victory_encrypted_flag = victory_encrypt(flag, victory_key)p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
a = 0
b = 7
xG = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
yG = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
G = (xG, yG)
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
h = 1
zero = (0,0)dA = nextprime(random.randint(0, n))if dA > n:print("warning!!")def addition(t1, t2):if t1 == zero:return t2if t2 == zero:return t2(m1, n1) = t1(m2, n2) = t2if m1 == m2:if n1 == 0 or n1 != n2:return zeroelse:k = (3 * m1 * m1 + a) % p * gmpy2.invert(2 * n1 , p) % pelse:k = (n2 - n1 + p) % p * gmpy2.invert((m2 - m1 + p) % p, p) % pm3 = (k * k % p - m1 - m2 + p * 2) % pn3 = (k * (m1 - m3) % p - n1 + p) % preturn (int(m3),int(n3))def multiplication(x, k):ans = zerot = 1while(t <= k):if (k &t )>0:ans = addition(ans, x)x = addition(x, x)t <<= 1return ansdef getrs(z, k):(xp, yp) = Pr = xps = (z + r * dA % n) % n * gmpy2.invert(k, n) % nreturn r,sz1 = random.randint(0, p)
z2 = random.randint(0, p)
k = random.randint(0, n)
P = multiplication(G, k)
hA = multiplication(G, dA)
r1, s1 = getrs(z1, k)
r2, s2 = getrs(z2, k)print("r1 = {}".format(r1))
print("r2 = {}".format(r2))
print("s1 = {}".format(s1))
print("s2 = {}".format(s2))
print("z1 = {}".format(z1))
print("z2 = {}".format(z2))key = sha256(long_to_bytes(dA)).digest()
cipher = AES.new(key, AES.MODE_CBC)
iv = cipher.iv
encrypted_flag = cipher.encrypt(pad(victory_encrypted_flag.encode(), AES.block_size))
encrypted_flag_hex = binascii.hexlify(iv + encrypted_flag).decode('utf-8')print("Encrypted flag (AES in CBC mode, hex):", encrypted_flag_hex)# output
# r1 = 66378485426889535028763915423685212583706810153195012097516816885575964878246
# r2 = 66378485426889535028763915423685212583706810153195012097516816885575964878246
# s1 = 73636354334739290806716081380360143742414582638332132893041295586890856253300
# s2 = 64320109990895398581134015047131652648423777800538748939578192006599226954034
# z1 = 35311306706233977395060423051262119784421232920823462737043282589337379493964
# z2 = 101807556569342254666094290602497540565936025601030395061064067677254735341454
# ('Encrypted flag (AES in CBC mode, hex):', u'3cdbe372c9bc279e816336ad69b8247f4ec05647a7e97285dd64136875004b638b77191fe9bef702cb873ee93dbe376c050d0c721b69f17f539cff83372cc37b')
ECDSA 共k攻击求dA
已知
s 1 = ( z 1 + r ∗ d A ) m o d n ∗ k − 1 m o d n s_1 = (z_1+r*dA) \space mod \space n *k^{-1} \space mod \space n s1=(z1+r∗dA) mod n∗k−1 mod n
s 2 = ( z 2 + r ∗ d A ) m o d n ∗ k − 1 m o d n s_2 = (z_2+r*dA) \space mod \space n *k^{-1} \space mod \space n s2=(z2+r∗dA) mod n∗k−1 mod n
两边同时乘上k
s 1 k = ( z 1 + r ∗ d A ) m o d n s_1k = (z_1+r*dA) \space mod \space n s1k=(z1+r∗dA) mod n
s 2 k = ( z 2 + r ∗ d A ) m o d n s_2k = (z_2+r*dA) \space mod \space n s2k=(z2+r∗dA) mod n
两式相减,得到k
k = ( s 2 − s 1 ) − 1 ( z 2 − z 1 ) m o d n k = (s_2-s_1)^{-1}(z_2-z_1) \space mod \space n k=(s2−s1)−1(z2−z1) mod n
带入式子1,即可计算出dA
d A = ( s 1 k − z 1 ) × k − 1 m o d n dA = (s_1k-z_1)\times k^{-1} \space mod \space n dA=(s1k−z1)×k−1 mod n
之后直接计算出key和iv解AES密文即可
然后根据加密代码逻辑还原明文
import gmpy2
from hashlib import sha256
from Crypto.Util.number import *
from Crypto.Cipher import AES
import binasciidef victory_decrypt(ciphertext, key):key = key.upper()key_length = len(key)plaintext = ''for i, char in enumerate(ciphertext):if char.isalpha():shift = ord(key[i % key_length]) - ord('A')decrypted_char = chr((ord(char) - ord('A') - shift + 26) % 26 + ord('A'))plaintext += decrypted_charelse:plaintext += charreturn plaintextr1 = 66378485426889535028763915423685212583706810153195012097516816885575964878246
r2 = 66378485426889535028763915423685212583706810153195012097516816885575964878246
s1 = 73636354334739290806716081380360143742414582638332132893041295586890856253300
s2 = 64320109990895398581134015047131652648423777800538748939578192006599226954034
z1 = 35311306706233977395060423051262119784421232920823462737043282589337379493964
z2 = 101807556569342254666094290602497540565936025601030395061064067677254735341454
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
c = '3cdbe372c9bc279e816336ad69b8247f4ec05647a7e97285dd64136875004b638b77191fe9bef702cb873ee93dbe376c050d0c721b69f17f539cff83372cc37b'
k = (z2-z1)*gmpy2.invert(s2-s1,n) %n
dA = (s1*k-z1)*gmpy2.invert(r1,n)%n
key = sha256(long_to_bytes(dA)).digest()
iv = binascii.unhexlify(c[:32])
enc = binascii.unhexlify(c[32:])
cipher = AES.new(key, AES.MODE_CBC,iv)
flag = cipher.decrypt(enc)
print(flag)
#SDSRDO{34697E430N6H6URW68849Q8HWT81039J}
ciphertext = "SDSRDO{34697E430N6H6URW68849Q8HWT81039J}"
victory_key = "WANGDINGCUP"
decrypted_flag = victory_decrypt(ciphertext, victory_key)print("Decrypted flag:", decrypted_flag)
#WDFLAG{34697E430F6B6ACA68849D8FCE81039B}
白虎组
Crypto1
先ddl了,有时间再补上
Crypto2
题目:
from Crypto.Util.number import getPrime, isPrime, GCD, inversenbits = 2048
gbits = 1000
g = getPrime(int(gbits))
while True:a = getPrime(int(nbits*0.5)-gbits)p = 2*g*a + 1if isPrime(p):breakwhile True:b = getPrime(int(nbits*0.5)-gbits)q = 2*g*b + 1if p!=q and isPrime(q):break
N = p*q
e = 65537def str2int(s):return int(s.encode('latin-1').hex(),16)def int2str(i):tmp=hex(i)[2:]if len(tmp)%2==1:tmp='0'+tmpreturn bytes.fromhex(tmp).decode('latin-1')with open('pubkey.txt','w') as f:f.write(str(e)+'\n')f.write(str(N)+'\n')with open('flag.txt') as f:plain = str2int(f.read())c = pow(plain,e,N)
with open('cipher.txt','wb') as f:f.write(int2str(c).encode('latin-1'))
分析代码,我们可以发现p和q的生成都存在一个共同的因子g,约为1000bit
又 ∵ p = 2 g a + 1 , q = 2 g b + 1 \because p = 2ga+1,q = 2gb+1 ∵p=2ga+1,q=2gb+1
⇒ g = g c d ( p − 1 , q − 1 ) \Rightarrow g = gcd(p-1,q-1) ⇒g=gcd(p−1,q−1)
所以我们可以使用Pollard’s rho来分解n,从而求得p和q
最后再把密文处理成整数型,然后计算出phi,d解密即可获得flag
exp:
import gmpy2
from Crypto.Util.number import *def f(x, n):return (pow(x, n - 1, n) + 3) % ndef rho(n):i = 1while True:a = getRandomRange(2, n)b = f(a, n)j = 1while True:p = GCD(abs(a - b), n)print('{} in {} circle'.format(j, i))if p == n:breakelif p > 1:return (p, n // p)else:a = f(a, n)b = f(f(b, n), n)j += 1i += 1#将密文转换整型
with open('cipher.txt', 'rb') as f:c_bytes = f.read() # 读取字节内容c_hex = c_bytes.hex() # 将字节转换为十六进制字符串c = int(c_hex, 16) # 将十六进制字符串转换为整数e = 65537
n = 49025724928152491719950645039355675823887062840095001672970308684156817293484070166684235178364916522473822184239221170514602692903302575847326054102901449806271709230774063675539139201327878971370342483682454617270705142999317092151456200639975738970405158598235961567646064089356496022247689989925574384915789399433283855087561428970245448888799812611301566886173165074558800757040196846800189738355799057422298556992606146766063202605288257843684190291545600282197788724944382475099313284546776350595539129553760118549158103804149179701853798084612143809757187033897573787135477889183344944579834942896249251191453
#Pollard’s rho分解n,
#p,q = rho(n)
p = 181081097501198023069853833182353184261284123229534078254107942099502325869566163846505417960576038861954213847321685798395883194037860319430010178354074600519049325312842897561278830450748961589667396822373094094674865532726953310816962745801088563041800719074771895743022649725941252134035150899684475275107
q = 270739053411293468044358005572326880715866131246316305975150551797771999927260913691624449594733673350641598358977228099278925982221096409496197961213452575581038864123668037331549492912118266914139408344450017736857756347795681452284667629499583154669046006953194443040693208729068117415444168170452989294079phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)
朱雀组
Crypto2
题目给了密文c,n以及p,其中p的高256bit已知
显然这是一个p高位泄露的题型,但是卡界了。
这一类题,我在2023 LitCTF 的baby_xor一题中出过一样的考点,详情移步下方链接,这里就不细讲了。
2023 LitCTF — Crypto wp
from tqdm import *
n = 0x00b8cb1cca99b6ac41876c18845732a5cbfc875df346ee9002ce608508b5fcf6b60a5ac7722a2d64ef74e1443a338e70a73e63a303f3ac9adf198595699f6e9f30c009d219c7d98c4ec84203610834029c79567efc08f66b4bc3f564bfb571546a06b7e48fb35bb9ccea9a2cd44349f829242078dfa64d525927bfd55d099c024fph = 0xe700568ff506bd5892af92592125e06cbe9bd45dfeafe931a333c13463023d4f0000000000000000000000000000000000000000000000000000000000000000
pbits = 512
p_high = ph>>256
for i in trange(2**8):p4 = p_high<<8p4 = p4 + ikbits = pbits - p4.nbits()p4 = p4 << kbitsPR.<x> = PolynomialRing(Zmod(n))f = x + p4roots = f.small_roots(X=2^kbits, beta=0.4, epsilon=0.01)if roots: p = p4+int(roots[0]) if n%p==0:print(i,p)break
爆破得到
i = 194
p = 12098520864598198757294135341465388062087431109285224283440314414683283061468500249596026217234382854875647811812632201834942205849073893715844547051090363
from Crypto.Util.number import *
import gmpy2
import libnumf = open("flag.enc","rb").read()
c = bytes_to_long(f)
p = 12098520864598198757294135341465388062087431109285224283440314414683283061468500249596026217234382854875647811812632201834942205849073893715844547051090363
n = 0x00b8cb1cca99b6ac41876c18845732a5cbfc875df346ee9002ce608508b5fcf6b60a5ac7722a2d64ef74e1443a338e70a73e63a303f3ac9adf198595699f6e9f30c009d219c7d98c4ec84203610834029c79567efc08f66b4bc3f564bfb571546a06b7e48fb35bb9ccea9a2cd44349f829242078dfa64d525927bfd55d099c024f
e = 65537
q = n//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)
之后计算出q = n//p,把密文变成数字型,再RSA解密即可得到flag
Crypto3
part1
n 1 ≈ p 1 × 2024 p 1 ≈ 2024 p 1 2 n_1 \approx p_1 \times 2024p_1 \approx 2024p_1^{2} n1≈p1×2024p1≈2024p12
整除2024,然后对n1开方即可得到p1,进而得到q1
n1 =
p1 = gmpy2.iroot(n1//2024,2)[0]
q1 = n1//p1
得到p1和q1
p1 = 146187607535300384587509957494226602879910697731111793338231366571998962914635615996598727004205169961576448628561413122161261394771744901435074146079222198287010135623393031759366562782057113205707175142954551779767710913840908209285742147746099427389400973759220801645310208401376788865791190217328962123279
q1 = 295883717651447978405120153968314644228939252207770269716580285941725900939222486777115823456511264002230732024208300159254393063018011680504590071664345729332908514501747496280957923070883597128351322489340012802249846889613998215594342107038105241036147570888662902530107861804386620664361368999873819337516721
part2
已知
n 2 = p 2 ∗ q 2 , n 22 = p 2 2 + q 2 2 n_2 = p_2*q_2,n_{22} = p_2^{2}+q_2^{2} n2=p2∗q2,n22=p22+q22
那么我们直接构建方程组解方程即可
n2 =
n22 =
p2,q2 = Ints('p2 q2')
s = Solver()
s.add(p2*q2==n2)
s.add(p2**2+q2**2==n22)
if s.check()==sat:print(s.model())
得到p2和q2
p2 = 133064204383114442564887327191574256650055020929830824588577417753167292659660059589564610129957808064002805580421156153609277092389753135192904997169182787255213644860856072991606212800442053226675120936710208060680648681274616282517421189570805017586256581334157425386374483509501090965717646720700424863423
q2 = 161350628589676557525881716966340935717969334783533837289612088856244362686139907887162014592790132128414148723412888028361068777482425667132948875411222080236173967775667519908708279765880512473014384298105752518090429868307024159426520644435015258039304108930727310884096853455754839248318020906028016894579
part3
根据p3和q3得生成代码,可知
p 3 + q 3 = 2 ( n 3 + 1 ) p_3+q_3 = 2(\sqrt{n_3}+1) p3+q3=2(n3+1)
再联合
n 3 = p 3 q 3 n_3 = p_3q_3 n3=p3q3
可以构造方程组计算出p3和q3
n3 =
tmp = gmpy2.iroot(n3,2)[0]
p3,q3 = Ints('p3 q3')
s = Solver()
s.add(p3*q3==n3)
s.add(p3+q3==2*tmp+2)
if s.check()==sat:print(s.model())
得到p3和q3
p3 = 122919460677181447255662000442101333281019894158297462412806821518657755917099521145678690717375396316626833583612356812214587401412448220563982839146665862717678495178437386577882720343715419646347453965273307650714361987001939787363067549306301977112348400269518912107383153989960205330328806948574142432881
q3 = 122919460677181447255662000442101333281019894158297462412806821518657755917099521145678690717375396316626833583612356812214587401412448220563982839146665862719627439871738815429215471546402837328038925028763750154507765739783853121032116043651820874648359779165148305098515735172075366847764584719616506196289
part4
已知
m 1 = p 1 m 2 + p 2 m + p 3 m_1 = p_1m^2+p_2m+p_3 m1=p1m2+p2m+p3
m 2 = q 1 m 2 + q 2 m + q 3 m_2 = q_1m^2+q_2m+q_3 m2=q1m2+q2m+q3
c 1 = m 1 e m o d n c_1 = m_1^e \space mod \space n c1=m1e mod n
c 2 = m 2 e m o d n c_2 = m_2^e \space mod \space n c2=m2e mod n
一眼顶针 Franklin-Reiter攻击,但是e = 2999,有点大,不太好多项式GCD,所以我们使用half gcd来加速多项式得gcd
#sage
from Crypto.Util.number import *
import sysdef HGCD(a, b):if 2 * b.degree() <= a.degree() or a.degree() == 1:return 1, 0, 0, 1m = a.degree() // 2a_top, a_bot = a.quo_rem(x^m)b_top, b_bot = b.quo_rem(x^m)R00, R01, R10, R11 = HGCD(a_top, b_top)c = R00 * a + R01 * bd = R10 * a + R11 * bq, e = c.quo_rem(d)d_top, d_bot = d.quo_rem(x^(m // 2))e_top, e_bot = e.quo_rem(x^(m // 2))S00, S01, S10, S11 = HGCD(d_top, e_top)RET00 = S01 * R00 + (S00 - q * S01) * R10RET01 = S01 * R01 + (S00 - q * S01) * R11RET10 = S11 * R00 + (S10 - q * S11) * R10RET11 = S11 * R01 + (S10 - q * S11) * R11return RET00, RET01, RET10, RET11def GCD(a, b):q, r = a.quo_rem(b)if r == 0:return bR00, R01, R10, R11 = HGCD(a, b)c = R00 * a + R01 * bd = R10 * a + R11 * bif d == 0:return c.monic()q, r = c.quo_rem(d)if r == 0:return dreturn GCD(d, r)sys.setrecursionlimit(500000)p1 = 146187607535300384587509957494226602879910697731111793338231366571998962914635615996598727004205169961576448628561413122161261394771744901435074146079222198287010135623393031759366562782057113205707175142954551779767710913840908209285742147746099427389400973759220801645310208401376788865791190217328962123279
q1 = 295883717651447978405120153968314644228939252207770269716580285941725900939222486777115823456511264002230732024208300159254393063018011680504590071664345729332908514501747496280957923070883597128351322489340012802249846889613998215594342107038105241036147570888662902530107861804386620664361368999873819337516721p2 = 133064204383114442564887327191574256650055020929830824588577417753167292659660059589564610129957808064002805580421156153609277092389753135192904997169182787255213644860856072991606212800442053226675120936710208060680648681274616282517421189570805017586256581334157425386374483509501090965717646720700424863423
q2 = 161350628589676557525881716966340935717969334783533837289612088856244362686139907887162014592790132128414148723412888028361068777482425667132948875411222080236173967775667519908708279765880512473014384298105752518090429868307024159426520644435015258039304108930727310884096853455754839248318020906028016894579p3 = 122919460677181447255662000442101333281019894158297462412806821518657755917099521145678690717375396316626833583612356812214587401412448220563982839146665862717678495178437386577882720343715419646347453965273307650714361987001939787363067549306301977112348400269518912107383153989960205330328806948574142432881
q3 = 122919460677181447255662000442101333281019894158297462412806821518657755917099521145678690717375396316626833583612356812214587401412448220563982839146665862719627439871738815429215471546402837328038925028763750154507765739783853121032116043651820874648359779165148305098515735172075366847764584719616506196289
e = 2999
n = 16384707752002961811357426356040804358820450429112719059482965460688633224199445850016434753713403979835193345762008018698844949530549502743281731789334994428312464772130516824285978243651287411553116255652677650004040824347186268439788928865418368468897627214552572846541839629323949068937120798767586917684764944219031287061253819651989184659516095370231858355076296906499453937821927440892978892852470311395853382511321806654834173438462402181182706548632711364029421502619027705821496435350762046222825598323497861393301677598992958820184003364763320507041485736186970914568690758845870075203051617037883827279119
c1 = 11382473352009511791762101735529507838446758824791351775250810654314066423650685628073502579664186057184344713574429940611514864513995383801386486394825452589218688059897458368223518637647179221771655104137667329953446341815527699304599435283634443556038985090968474934734321344125280569467142049038929368549733232047316780077686016318662303350081357699377969335914292631398295061602601940464649624118295616080162917211435856653333110858004250959483891522407923876955812205685375843940874486371994485161526059198019014530740524036481557433830304867422828002361446861419824025752025995296741718962141953713234949894732
c2 = 13291355062242181017235433629558689027068114611650872691659197232933062720760260933280099178334615566562244698391494264051061145257215694115131167336658805533954362024110598093368016089512260336234014588390607552801658614571912470713860293915607463462319165043506295500174873235810829299741016973929360670488678562024980338443636210602228872744449850339238513161642644630785241443001404597604581629303749287855365022218361488602768556292856610619067231689100946362621816109192111615866980116556776737918323907474176583284350758109722993772794866722135312051956704194889790127430725508449097365193657563726357277350509R.<x> = PolynomialRing(Zmod(n))
f = (p1 * x * x + p2 * x + p3)^e - c1
g = (q1 * x * x + q2 * x + q3)^e - c2
res = GCD(f,g)
m = -res.monic().coefficients()[0]
flag = long_to_bytes(int(m))
print(flag)
【许多的故事,大大小小的,末尾就两个字,“还好”。而”还好“的注解,大概就是”希望“。】
相关文章:

2024 网鼎杯 CTF --- Crypto wp
文章目录 青龙组Crypto1Crypto2 白虎组Crypto1Crypto2 朱雀组Crypto2Crypto3part1part2part3part4 青龙组 Crypto1 题目: from Crypto.Util.number import * from secret import flagp getPrime(512) q getPrime(512) n p * q d getPrime(299) e inverse(d,…...

深度学习基础知识-损失函数
目录 1. 均方误差(Mean Squared Error, MSE) 2. 平均绝对误差(Mean Absolute Error, MAE) 3. Huber 损失 4. 交叉熵损失(Cross-Entropy Loss) 5. KL 散度(Kullback-Leibler Divergence&…...
《逆向记录》
这里写自定义目录标题 1.什么是vmp加密VMP加密的工作原理VMP加密的应用场景和优缺点实际应用案例 2.什么是ast混淆3.魔改算法总结 1.什么是vmp加密 VMP加密(Virtual Machine Protection)是一种软件保护技术,旨在通过虚拟化和加密技术来保…...
chatgpt3.5权重参数有多少MB;llama7B权重参数有多少MB
目录 chatgpt3.5权重参数有多少MB llama7B权重参数有多少MB chatgpt3.5权重参数有多少MB 关于ChatGPT 3.5的权重参数占用的存储空间大小,虽然直接给出具体的MB数值可能较为困难(因为这取决于多种因素,如参数表示的精度、是否进行了压缩等),但可以根据其参数量来估算一个…...

ST IoT Wireless 物联网与无线技术 研讨会
一、研讨会背景与目的 ◆ 意法半导体致力于提供可靠且经济实惠的无线连接解决方案,包含Wireless NFC Security & Esim等产品。 ◆ 将智能物体连接到互联网和云,或者从更广泛的意义上说,连接到物联网(IoT)。 ◆ 远程监控、配…...
PHP实现雪花算法生成唯一ID
引言 雪花算法是Twitter开源的分布式ID生成算法,可以产生64位的ID。其中第一位是固定的正数标识,41位用于存储时间戳,剩下的为机器ID和序列号。通过时间戳、机器ID和序列号的组合,确保每个ID都是唯一的。 PHP代码 1、定义雪花算…...

APP的设置页面,应该怎样尽可能减少用户的输入操作呢
一、引言 在当今数字化时代,移动应用程序(APP)已经成为人们生活中不可或缺的一部分。无论是社交娱乐、工作学习还是日常生活,我们都离不开各种 APP 的帮助。而 APP 的设置页面作为用户调整应用参数、个性化定制功能的重要入口&am…...

Node.js:内置模块
Node.js:内置模块 Node.jsfs模块读取文件写入文件__dirname path模块路径拼接文件名解析 http模块创建服务 Node.js 传统的JavaScript是运行在浏览器的,浏览器就是其运行环境。 浏览器提供了JavaScript的API,以及解析JavaScript的解析引擎&a…...

3. keil + vscode 进行stm32协同开发
1. 为什么使用vscode 主要还是界面友好,使用习惯问题,vscode 从前端,js, c/c, qt, 仓颉,rust都有很好插件的支持,并且有romote, wsl 等很多插件可以提高效率, 唯一的问题就是要使用插件进行环境…...

React 组件生命周期与 Hooks 简明指南
文章目录 一、类组件的生命周期方法1. 挂载阶段2. 更新阶段3. 卸载阶段 二、函数组件中的 Hooks1. useState2. useEffect3. useContext4. useReducer 结论 好的,我们来详细讲解一下 React 类组件的生命周期方法和函数组件中的钩子(hooks)。 …...
【springcloud】gateway网关的作用
目录 1. 说明2. 路由转发3. 负载均衡4. 安全认证与授权5. 熔断与降级6. 请求限流7. 监控与日志8. 过滤器功能 1. 说明 1.在Spring Cloud中,Gateway网关扮演着至关重要的角色。2.基于Spring Framework 5、Spring Boot和Project Reactor构建的API网关,专为…...

「C/C++」C++11 之<thread>多线程编程
✨博客主页何曾参静谧的博客📌文章专栏「C/C++」C/C++程序设计📚全部专栏「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明目…...

HTML前端页面设计静态网站-仿百度
浅浅分享一下前端作业,大佬轻喷~ <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>百度(伪)</title><style>body {margin: 0;padding: 0;}.top-bar {dis…...

百度SEO是否还有用?福州百度SEO专家林汉文为你深度解析
大家好,我是林汉文,一名专注于百度SEO优化的专家,最近有很多人问我:百度SEO还有用吗?在如今快速变化的数字营销环境中,这确实是一个值得探讨的问题。今天,我就来为大家详细分析百度SEO的现状&am…...
数学建模学习(134):使用Python基于WISP的多准则决策分析
WISP算法技术性文章 1. 算法介绍 WISP(Weighted Independent Set Problem)是一种优化算法,主要用于解决图论中的加权独立集问题。加权独立集问题是一个经典的组合优化问题,涉及从一个图中选择一个独立的顶点集,使得所选顶点的总权重最大。这个问题在计算机科学、运筹学、…...
.net core NPOI以及NOPI mapper
我们在日常开发中对Excel的操作可能会比较频繁,好多功能都会涉及到Excel的操作。在.Net Core中大家可能使用Npoi比较多,这款软件功能也十分强大,而且接近原始编程。但是直接使用Npoi大部分时候我们可能都会自己封装一下,毕竟根据二…...

分布式锁(redisson,看门狗,主从一致性)
目录 分布式锁一:基本原理和实现方式二:分布式锁的实现1:分布式锁的误删问题2:解决误删问题 三:lua脚本解决多条命令原子性问题调用lua脚本 四:Redisson1:redisson入门2:redisson可重…...

openEuler 服务器Python自动化安装WEB服务器和文件上传服务(1)
一、系统准备 我们的服务器采用了 openEuler 22.03 (LTS-SP4) 的初始化服务器模式安装 二、安装步骤 (一)安装依赖库 在终端中运行以下命令确保系统安装了必要的依赖: sudo dnf install -y python3上述 Python 脚本中的依赖库会在运行 Py…...

【Python游戏开发】石头剪刀布游戏(附完整Python完整代码)
石头剪刀布游戏:Pygame实现 结果图前言核心函数思考步骤实现原理和公式代码实现结论结果图 前言 石头剪刀布是一种经典的猜拳游戏,简单易玩但却蕴含着一定的策略性。本文将介绍如何使用Python和Pygame库开发一个简单的石头剪刀布游戏,并探讨其中的核心功能实现和思考过程。 …...
ctfshow(94,95)--PHP特性--strpos函数
建议先学习intval函数相关内容 Web94 源代码: include("flag.php"); highlight_file(__FILE__); if(isset($_GET[num])){$num $_GET[num];if($num"4476"){die("no no no!");}if(preg_match("/[a-z]/i", $num)){die(&qu…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...