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…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
