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…...
OpenClaw 2026年阿里云8分钟本地云端集成零基础部署及使用教程
OpenClaw 2026年阿里云8分钟本地云端集成零基础部署及使用教程。本文面向零基础用户,完整说明在轻量服务器与本地Windows11、macOS、Linux系统中部署OpenClaw(Clawdbot)的流程,包含环境配置、服务启动、Skills集成、阿里云百炼API…...
AI智能证件照制作工坊高可用部署:生产环境配置建议
AI智能证件照制作工坊高可用部署:生产环境配置建议 1. 项目概述与核心价值 AI智能证件照制作工坊是一个商业级证件照生产工具,基于Rembg高精度抠图引擎构建。这个工具能够将普通的生活照或自拍照,通过全自动流程转换为符合标准的证件照&…...
RViz实战:如何用C++在ROS中动态切换不同形状的物体(含避坑指南)
RViz实战:如何用C在ROS中动态切换不同形状的物体(含避坑指南) 在机器人开发过程中,RViz作为ROS生态中的三维可视化利器,其核心价值在于让抽象的数据变得直观可见。而Marker消息系统则是实现这种可视化的关键桥梁——它…...
YOLO12在工业质检场景:PCB缺陷识别与小目标检测实战案例
YOLO12在工业质检场景:PCB缺陷识别与小目标检测实战案例 1. 引言:当AI质检员遇上电路板 想象一下,你是一家电子厂的质检主管。每天,成千上万块印刷电路板(PCB)从生产线上下来,每一块都需要经过…...
编译原理实战:5分钟搞定词法分析器的选择题(含答案解析)
编译原理实战:词法分析器选择题高效解题指南 在编译原理的学习和考试中,词法分析器相关选择题往往是考察重点,也是许多同学容易失分的部分。面对复杂的正规式、有限自动机等概念,如何快速准确地做出判断?本文将带你深入…...
Datawhale AI冬令营-学习笔记-task1
很多企业训练出来的通用模型,我们在使用时并不能很好得解答我们生活中的疑惑,故我们需要一些定制专属大模型来解答在特殊情境下的特定问题,通过投喂一些特定的数据,使得让专属模型在特定领域有着更出色的表现。本次学习将 基于《甄…...
3个步骤掌握阿里云盘命令行客户端的快传链接:大文件分享的终极解决方案
3个步骤掌握阿里云盘命令行客户端的快传链接:大文件分享的终极解决方案 【免费下载链接】aliyunpan 阿里云盘命令行客户端,支持JavaScript插件,支持同步备份功能。 项目地址: https://gitcode.com/GitHub_Trending/ali/aliyunpan 在当…...
AI Agent 的动态知识更新:保持 LLM 知识的实时性
AI Agent 的动态知识更新:保持 LLM 知识的实时性 关键词:AI Agent、动态知识更新、大语言模型(LLM)、实时性、知识图谱 摘要:本文聚焦于 AI Agent 的动态知识更新,旨在探讨如何保持大语言模型(LLM)知识的实时性。首先介绍了相关背景,包括目的、预期读者等。接着阐述了…...
电子元器件检测数据集VOC+YOLO格式1032张5类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):1032标注数量(xml文件个数):1032标注数量(txt文件个数):1032标注类别…...
为什么很多人学 Django 会懵?因为没搞懂 MVC 和 MTV 的真正区别
很多刚接触 Django 的开发者,甚至包括不少测试工程师,在学习 Django 时都会遇到一个困惑:为什么 Django 不叫 MVC,而是 MTV?更奇怪的是:很多教程还会说:“Django 的 MTV 其实就是 MVC。”这句话…...
