2024SHCTF

注:针对2024SHCTF赛事,写下自己的解题思路以及个别赛题赛后复现对于题目而产生的理解。

Week1

d_known

task:

from Crypto.Util.number import *
from gmpy2 import*
from flag import flag m = bytes_to_long(flag)
p = getPrime(1024)
q = next_prime(p)
n = p * q
e = 0x10001
d = inverse(e, (p-1) * (q-1))
c = pow(m, e, n)
print(c)
print(d) '''
c = 2023280206852799756188533543726445899210461674882103741449846207085209158128274530066961712554168490693338804965645257201915901430270289914927031884869765066207700835767543832965446328994297771171239554854439801951855734405930228978819264617926307331498279823792404896708489491845814993901912406921233209174052585982422702902921150509799525025006961668679058706680338445147732742087594370544143929344692878849762859325278353499113047627166145064375388330723568647380571912097704007649949039872655521965438358883046062395057460962164069910080794938688401346483471199715397419486956888803799635787660289917216321436075
d = 5325557477974651131933634251521791991925782269036709550928544143247135213750451805876289560548176503358408907072006083232605644148148348426759760165848721826856045819883560475601424759644170039021289236399016340754732526066778542800516887549418899285710399950124543460448926261999153088331976259647327700619342183115011084680629309966651674276478502656272680143227400879298842573111724783827297704483713490258469730037991356794901334012297158591206594636469676973210545148034611453362521846968132369356368152162040634155912080095620977164991291750678677808423018575966921693161165571968455135962605729487885568490033
'''

analysis:

已知d,

\[ed≡1(mod\ \ phi)=>ed-1≡0(mod\ \ phi)=>ed-1 = k*phi
\]

e.bit_length = 17;d.bit_length = 2046;phi.bit_length≈2048,所以可以大致推出k的位数,爆破求出phi

然后求出p,q,q = next_prime(p),p,q接近,直接对phi开方然后用next_prime,prevprime即可求解p,q

tqdm: tqdm是一个快速、扩展性很强的Python库,用于在长循环中添加一个进度提示信息,能够给用户一个直接的反馈。range-->trange

exp:

from Crypto.Util.number import *
from sympy import *
from gmpy2 import *
from tqdm import *
c = 2023280206852799756188533543726445899210461674882103741449846207085209158128274530066961712554168490693338804965645257201915901430270289914927031884869765066207700835767543832965446328994297771171239554854439801951855734405930228978819264617926307331498279823792404896708489491845814993901912406921233209174052585982422702902921150509799525025006961668679058706680338445147732742087594370544143929344692878849762859325278353499113047627166145064375388330723568647380571912097704007649949039872655521965438358883046062395057460962164069910080794938688401346483471199715397419486956888803799635787660289917216321436075
d = 5325557477974651131933634251521791991925782269036709550928544143247135213750451805876289560548176503358408907072006083232605644148148348426759760165848721826856045819883560475601424759644170039021289236399016340754732526066778542800516887549418899285710399950124543460448926261999153088331976259647327700619342183115011084680629309966651674276478502656272680143227400879298842573111724783827297704483713490258469730037991356794901334012297158591206594636469676973210545148034611453362521846968132369356368152162040634155912080095620977164991291750678677808423018575966921693161165571968455135962605729487885568490033
e = 65537
kphi = e*d - 1
for k in trange(2**13,2**17):
if kphi % k == 0:
phi = kphi // k
p = next_prime(iroot(phi,2)[0])
q = prevprime(iroot(phi,2)[0])
if d == inverse(e,(p-1)*(q-1)):
m = pow(c,d,p*q)
print(long_to_bytes(m))
# SHCTF{53398660-8e40-460d-9f28-2b25b687fbe9}

baby_mod

task:

from Crypto.Util.number import *
from enc import flag m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
r = getPrime(777)
t = getPrime(777)
tmp = getPrime(15)
e = 65537
n = p*q
print(f"c = {pow(m,e,n)}")
print(f"leak = {p*r-q*t-tmp}")
print(f"r = {r}")
print(f"t = {t}")
'''
c = 17937472553998606504669747140789726307439582196963451030969242254157949062129324494114590658920012871180079814675678946453897865233224992985089451278231663618857965418389487647355253063941790618808955858162224234190981820557457655720791346278352310012094147015720264246236621546172323951815149898363856098823
leak = -1587213174398707503036319512989790705844433773053364648490744871188009448006267321887626866013134130998268382756317172409049882250682995546076129821312371197174231288418315516151931068209717088211878340641266286735555866264605212381502721300165430517113230358235888004114974340620550567298211707561178407907225299235498063377164047589836058708230195966901891786125922264824283899806368097
r = 466415729162296733529092458774194130369566652709805609481844599849536821250812719015532685709318199315612306114406654748660375049578603355246845205423401652241172615507957208288364106021726317326899229799053280291178121413651628535023
t = 635316670184189895492730019113841833333699743242997516619486647136468690062607793643684031305893867906907074562340028701514502349937069085426784869269608878466785830130266100418807129895963018317044053909910919832387196116916663544813
'''

analysis:

\[leak = pr-qt-tmp\\
leak+tmp=pr-qt\\
leak+tmp≡pr(mod\ \ t)
\]

此时有r,t,leak也就是说tmp确定时我们即可利用(leak+tmp)*inverse(r,t)%t求解p。

exp:

from Crypto.Util.number import *

# Given values
e = 65537
c = 17937472553998606504669747140789726307439582196963451030969242254157949062129324494114590658920012871180079814675678946453897865233224992985089451278231663618857965418389487647355253063941790618808955858162224234190981820557457655720791346278352310012094147015720264246236621546172323951815149898363856098823
leak = -1587213174398707503036319512989790705844433773053364648490744871188009448006267321887626866013134130998268382756317172409049882250682995546076129821312371197174231288418315516151931068209717088211878340641266286735555866264605212381502721300165430517113230358235888004114974340620550567298211707561178407907225299235498063377164047589836058708230195966901891786125922264824283899806368097
r = 466415729162296733529092458774194130369566652709805609481844599849536821250812719015532685709318199315612306114406654748660375049578603355246845205423401652241172615507957208288364106021726317326899229799053280291178121413651628535023
t = 635316670184189895492730019113841833333699743242997516619486647136468690062607793643684031305893867906907074562340028701514502349937069085426784869269608878466785830130266100418807129895963018317044053909910919832387196116916663544813
for temp in range(2**14,2**15):
if isPrime(temp):
p = (leak + temp) * inverse(r, t) % t
if isPrime(p):
q = (p * r - leak - temp) // t
if isPrime(q):
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, p * q)
flag = long_to_bytes(m)
print(flag)
break
# SHCTF{0055b9ad-d96a-4d43-a9a9-28ecb08d557e}

Week2

worde很大

task:

import gmpy2
from Crypto.Util.number import *
from enc import flag m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p*q
e = getPrime(200)
d = gmpy2.invert(e,(p-1)*(q-1))
dp = d % (p-1)
c = pow(m,e,n) print(f"n = {n}")
print(f"c = {c}")
print(f"e = {e}")
print(f"dp = {dp}")
'''
n = 107032957087630288996268413289950221007178661091952415803799204807322719946773789072727097283876411371451855146945178785099365053975022744275499071412639566826876925607457076160736517239727314406122177641305989161650710675377046111659861132320470194374212535258339049977749925125713806268856103059658246838823
c = 13426059268971299890058502967962382039319233826881681062400371816555313938352978412770129453032021159626652883952418968332266876616888219630681123569091893928354304104629165208088101777538952907693381585125393549212184411084081938892612243511190758716729464349148805390375073663394447190303250531328411306179
e = 940179304603814149880259136688231799983345424885109815443153
dp = 1389519949170420652498985591042020010547189625918115450421402099250611740108790835840554944891132491698692658805867305372374541674726218271082297905819817
'''

analysis:

dp泄露,但是e很大,利用费马小定理可以求出p

\[d_p≡d(mod\quad(p-1))\\
ed≡1(mod(\ \ (p-1)(q-1)))\\
由性质戊:\\
若a_1≡b_1(mod\ \ m),a_2≡b_2(mod\ \ m),则\\
a_1a_2≡b_1b_2(mod \ \ m)\\
特别地,若a≡b(mod\ \ m),则ak≡bk(mod\ \ m)\\
ed_p≡ed(mod\ \ (p-1))\\
\forall m:(m,p) = 1;m^{ed_p}(mod\ \ n)≡m^{ed(mod\ \ (p-1))}(mod\ \ p)\\
m^{ed_p}(mod\ \ n)≡m^{1+k(p-1)}(mod\ \ p)\\
由费马小定理:a^{p-1}≡1(mod\ \ p)=>a^p≡a(mod\ \ p)\\
m^{1+k(p-1)}≡m(mod\ \ p)\\
m^{ed_p}(mod\ \ n)≡m(mod\ \ p)=>m^{ed_p}(mod\ \ n)-m≡0(mod\ \ p)\\
又∵n = p*q.则m^{ed_p}(mod \ \ n) - m与n存在最大公因数p.\\
\forall m:(m,p)=1,满足p=gcd(m^{ed_p}(mod\ \ n)-m,n),m∈(1,p)
\]

exp:

from Crypto.Util.number import *
n = 107032957087630288996268413289950221007178661091952415803799204807322719946773789072727097283876411371451855146945178785099365053975022744275499071412639566826876925607457076160736517239727314406122177641305989161650710675377046111659861132320470194374212535258339049977749925125713806268856103059658246838823
c = 13426059268971299890058502967962382039319233826881681062400371816555313938352978412770129453032021159626652883952418968332266876616888219630681123569091893928354304104629165208088101777538952907693381585125393549212184411084081938892612243511190758716729464349148805390375073663394447190303250531328411306179
e = 940179304603814149880259136688231799983345424885109815443153
dp = 1389519949170420652498985591042020010547189625918115450421402099250611740108790835840554944891132491698692658805867305372374541674726218271082297905819817
p = GCD(pow(5,e*dp,n)-5,n)
q = n // p
phi_n = (p-1) * (q-1)
d = inverse(e,phi_n)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)
#SHCTF{worD_E_YOU_d1aN_DA_EA7zaA}

pading

task:

from Crypto.Util.number import *
import gmpy2
flag = b'SHCTF{********}'
assert len(flag) == 39
p = getPrime(512)
q = getPrime(512)
n = p * q
e = 0x3
pad = b'a_easy_problem'
c = pow(bytes_to_long(flag + pad),e,n)
print(f'n = {n}')
print(f'c = {c}')
'''
n = 75098630616111482769180659620329958045667354926061075208260621193990567410087157843957397740063249813712091785246064471170031967563730722416238514564741845799209165882736179507743810974327683565208643579519017836211681069084365442156637269419638211790587926949896791807497864162801395061736248644788921667789
c = 3638646373008661843144668651345881752890064263891078270562520797735374345440840522319031089914051142881157757879267055752918804376422359639737717683576378097238618841707519724197204326012840131370755503486240820145945437287578597232976614322766435861623599998349726858207129492804638826767780589762299083258
'''

analysis:

此题对于flag+pad进行加密,小e,并且已知pad,隶属于高位攻击,使用coppersmith算法求解。

flag的二进制位时39*8=312,e次方之后是312*3=936而n的位数是1024,312的flag相对于1024的n来说是小值,可用coppersmith的方法求解。

beta的值依据912/1024=0.89取整0.8,epslilon慢慢放小。对于多项式的方程而言

现有一个e阶的多项式f,那么可以:f =

\[b≥n^β,(0≤β≤)
\]

2.在模n意义下,快速求出

\[n^{β^2 \over e}
\]

coppersmith: 在RSA中,高位攻击,已知部分二进制位,通过coppersmith定理(里面应用了LLL算法)求剩余二进制位。p,q位数一致时,unkown_bits/p_bits≤0.44.sagemath中的small_roots(X= ,beta= ),beta选在0.4.

small_roots: 使用small_roots时,多设一个参数epsilon,让里面构造的格大一点,就可以不用爆破直接出结果了,epsilon越小,造出来的格越大。在不设置的情况下默认为beta/8,这里就是0.4*8=0.05,这样跑不出来结果,就可以尝试缩小epsilon的值,可以通过逐步减小的值来求解答案epsilon=0.026就可以出结果。当epslion过小时,格过大,LLL算法会非常耗时,这里测试epsilon=0.01就需要一点时间了。所以一般取0.01左右出不来,就得考虑方法问题了。

exp:

from Crypto.Util.number import *

n = 75098630616111482769180659620329958045667354926061075208260621193990567410087157843957397740063249813712091785246064471170031967563730722416238514564741845799209165882736179507743810974327683565208643579519017836211681069084365442156637269419638211790587926949896791807497864162801395061736248644788921667789
c = 3638646373008661843144668651345881752890064263891078270562520797735374345440840522319031089914051142881157757879267055752918804376422359639737717683576378097238618841707519724197204326012840131370755503486240820145945437287578597232976614322766435861623599998349726858207129492804638826767780589762299083258
e=3 pre=b'SHCTF{'
suf=b'}a_easy_problem' flag_length=39
# 去除高位,即SHCTF{
pre_bits=(flag_length+len(suf)-1-len(pre))*8
# 计算后面已知明文的bits
suf_bits=len(suf)*8
# 计算未知的bits
unknown_bits=(flag_length-len(pre)-1)*8 PR.<x> = PolynomialRing(Zmod(n))
# f = m^e-c
# x即unknown的部分
# bytes_to_long(a+b)≠bytes_to_long(a)+bytes_to_long(b);bytes_to_long(a+b)=bytes_to_long(a)*2^(len(a)*8)
f=(bytes_to_long(pre)*2^pre_bits+x*2^suf_bits+bytes_to_long(suf))^e-c
f=f.monic()
m=f.small_roots(X=2^unknown_bits,beta=0.4,epsilon=0.026)
if m:
x=m[0]
flag=pre+long_to_bytes(int(x))+suf
print(flag)
#b'SHCTF{4RE_yOu_PaDddln9_mE_8oY_EIz66G45}a_easy_problem'

ezECC

from Crypto.Util.number import *
from flag import flag assert flag.startswith(b'SHCTF{') m = next_prime(bytes_to_long(flag))
p = getPrime(512)
a,b = getPrime(128),getPrime(128)
E = EllipticCurve(Zmod(p),[a,b])
k = getPrime(256)
A1 = E.random_point()
A2 = A1*k
M = E.lift_x(m)
C = M+A2 print('p = ',p)
print('k = ',k)
print('A1 = ',A1)
print('C = ',C)

data:

p =  9799485259524549113003780400336995829253375211044694607315372450399356814285244762186468904824132005209991983177601498069896166228214442123763065076327679
k = 73771953838487511457389800773038323262861649769228176071578897500004883270121
A1 = (5945412329827707694132352090606154232045921322662767755331097180167148601629747751274580872108985870208681845078153424348847330421799769770041805208089791 : 4113102573821904570542216004200810877456931033522276527318388416329888348077285857968081007666714313806776668203284797556825595791189566621228705928598709 : 1)
C = (2336301464307188733995312208152021176388718095735565422234047912672553316288080052957448196669174030921526180747767251838308335308474037066343018337141276 : 6868888273736103386336636953449998615833854869329393895956720058438723636197866928342387693671211918574357564701700555086194574821628053750572619551290025 : 1)

analysis:

已知A1和C两个在曲线上地点和曲线地p值,根据曲线

\[y^2=x^3+ax+b(mod\ \ p)
\]

两个式子相减求得a和b.构造曲线,由于C=M+A2,且A2=kA1,A1和k的值都已知。M=C-kA1求得M的值,由于M的x坐标是明文m的下一个素数,爆破即可。

点的处理: 对于题目给出数据的点,我们要进行修改,因为sagemath中的点要求(x,y)而非(x:y:1)

遗留问题: sympy中的prevprime函数的使用方法。

exp:

from Crypto.Util.number import *

p =  9799485259524549113003780400336995829253375211044694607315372450399356814285244762186468904824132005209991983177601498069896166228214442123763065076327679
k = 73771953838487511457389800773038323262861649769228176071578897500004883270121
A1 = (5945412329827707694132352090606154232045921322662767755331097180167148601629747751274580872108985870208681845078153424348847330421799769770041805208089791 , 4113102573821904570542216004200810877456931033522276527318388416329888348077285857968081007666714313806776668203284797556825595791189566621228705928598709 )
C = (2336301464307188733995312208152021176388718095735565422234047912672553316288080052957448196669174030921526180747767251838308335308474037066343018337141276 , 6868888273736103386336636953449998615833854869329393895956720058438723636197866928342387693671211918574357564701700555086194574821628053750572619551290025 ) a = inverse(A1[0]-C[0],p)*((A1[1]**2-A1[0]**3)-(C[1]**2-C[0]**3))% p
b = (C[1]**2-C[0]**3-a*C[0])%p E = EllipticCurve(Zmod(p),[a,b])
A1 = E(A1)
C = E(C)
M = C-k*A1 mm = (M.xy())[0]
for i in range(292):
m = long_to_bytes(int(mm-i))
if m.endswith(b'}'):
print(m)

魔鬼的步伐

task:


from Crypto.Util.number import *
from random import choice
from enc import flag m = bytes_to_long(flag)
def get_primes(limit):
primes = []
is_prime = [True] * (limit + 1)
for num in range(2, limit + 1):
if is_prime[num]:
primes.append(num)
for multiple in range(num * num, limit + 1, num):
is_prime[multiple] = False
return primes def get_Prime(bits):
while True:
n = 2
while n.bit_length() < bits:
n *= choice(primes)
if isPrime(n + 1):
return n + 1 e = 65537
primes = get_primes(e)
p = get_Prime(512)
q = get_Prime(512)
n = p*q
c = pow(m,e,n)
print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
'''
n = 779579301738188606639541475585479048662338414978423162511086618350581959037809676355175033940672838358216296034989613684765924879020007985463372880378958453235938149726732804842653385407460552866449233717559756619739481517089434393605029261842182116054349584175198599481092380973944251651872382058614325364639417
e = 65537
c = 547032040563518540116157223879027303340872416038133089003193905244978422560735616179910978730578423924420033057963791332760379132346877909806353927165538096867865399527460216074519919572776729647581400118345644864260152466704275743378828075020134070702051989890847762735538767329450466068109132805742740564390842
'''

analysis:

欧拉函数φ(n): 给定一个正整数 n,欧拉函数就是求在 [1,n) 区间上,与 n互质的整数的个数。举例来说,设m = 8,则与8互质的正整数集合A={1, 3, 5, 7},此集合共有4个元素,所以 φ ( 8 ) = 4。

\[\forall n\in \mathbb{N^+},φ(n)=∣A∣,whereA=\{m|1≤m≤n,(m,n)=1\}\\
|S|表示集合S中的元素个数
\]

欧拉定理: 对任意两个正整数 a , n ,若两者互素,则:对比费马小定理,实际上就是欧拉定理的特殊情况。

\[a^{φ(n)}≡1(mod\ \ n)=>a^{kφ(n)}=(a^{φ(n)})^k≡1^k≡1(mod\ \ n)
\]

所以只要指数是模数n的欧拉函数的倍数,在模n下就等于1.

对于本题中的情况:

\[p = p_1p_2\cdots p_s+1;q=q_1q_2\cdots q_t+1\\
φ(p)=p_1p_2\cdots p_s;φ(q)=q_1q_2\cdots q_t\\
n = pq;φ(n)=p_1p_2\cdots p_sq_1q_2\cdots q_t\\
所以只需要遍历get\_primes()得到的素数表就可以得到数a的计算指数.\\
得,a^{k*φ(n)}≡1(mod\ \ n)\\
a^{k*φ(n)}-1≡0(mod\ \ p)=>gcd(a^{k*φ(n)}-1,n)=p
\]

求解φ(n)即可。

exp:

from Crypto.Util.number import *
# Given values
n = 779579301738188606639541475585479048662338414978423162511086618350581959037809676355175033940672838358216296034989613684765924879020007985463372880378958453235938149726732804842653385407460552866449233717559756619739481517089434393605029261842182116054349584175198599481092380973944251651872382058614325364639417
e = 65537
c = 547032040563518540116157223879027303340872416038133089003193905244978422560735616179910978730578423924420033057963791332760379132346877909806353927165538096867865399527460216074519919572776729647581400118345644864260152466704275743378828075020134070702051989890847762735538767329450466068109132805742740564390842 # 初始化生成光滑数的列表get_primes(e)
def get_primes(limit):
primes = []
is_prime = [True] * (limit + 1)
for num in range(2, limit + 1):
if is_prime[num]:
primes.append(num)
for multiple in range(num * num, limit + 1, num):
is_prime[multiple] = False
return primes
# 由于n = p * q ,而p,q分别由一个get_primes生成,所以最终n的列表应该是2*get_primes(e)
primes_value = get_primes(e) + get_primes(e) # 求解φ(n)
def Solve(n):
counter = 0
for p in primes_value:
if n % p == 0:
counter += 1
return n - counter - 2 # 减去1和n的两种情况
# 取素数2当作最初的a,在φ(n)的范围内不断增大指数寻找GCD(a^{k*φ(n)}-1,n) != 0和 != n
a = 2
for _ in range(2,Solve(n)):
a = pow(a,_,n)
p = GCD(a-1,n)
if p !=1 and p != n:
q = n // p
break
phi_n = (p-1)*(q-1)
d = inverse(e,phi_n)
flag = long_to_bytes(pow(c,d,n))
print(flag)
#SHCTF{1rlCTioN_is_ThE_d3vils_st3P_4s}

E&R

task:

#sage
from Crypto.Util.number import *
from secret import flag flag = flag[6:-1]
l = len(flag)
m1 = bytes_to_long(flag[:l//2])
m2 = bytes_to_long(flag[l//2:])
#RSA
p = getPrime(256)
q = getPrime(256)
n = p * q
e = 65537
r_q = int(bin(q)[2:][::-1] , 2)
leak = p ^ r_q
c = pow(m2,e,n) #ECC
E = EllipticCurve(Zmod(n),[114514,1919810])
G = E.lift_x(Integer(m1))
P = G * e
print(f'leak = {leak}')
print(f'n = {n}')
print(f'c = {c}')
print(f'P = {P}')
# leak = 5599968251197363876087002284371721787318931284225671549507477934076746561842
# n = 7120275986401660066259983193598830554385933355254283093021239164350142898387660104515624591378875067038235085428170557400012848874756868985306042421950909
# c = 6803450117490196163076010186755045681029929816618361161925865477601994608941714788803007124967390157378525581080320415602012078322064392991884070073083436
# P = (4143131125485719352848137000299706175276016714942734255688381872061184989156686585992844083387698688432978380177564346382756951426943827434190895490233627 : 3879946878859691332371384275396678851932267609535096278038417524609690721322205780110680003522999409696718745532857001461869452116434787256032366267905519 : 1)

analysis:

Crypto趣题-剪枝

剪枝: 剪枝是对于树算法类的题目而言的,通过减去已经计算后的树的枝点来缩短算法的时间复杂度。而在这里则是同时找到p和q高位或低位,要是只找p高位和q低位,爆破条件无法判断,这就是为什么这题需要同时用到pxorq的两端.

剪枝已知条件: p 与 q 的反方向二进制的异或值,共256bit,记为p_xor_q

剪枝搜索方式: 1.从两端向中间搜索 2. 每一次搜索,需利用当前 pxorq 两端的bit位。这是因为,pxorq 的当前最高位对应p的最高位及q的最低位,pxorq 的当前最低位对应p的最低位及q的最高位 (其中最高、最低均是对于当前搜索而言) 3.如果当前需搜索的最高位为”1”,则对应两种可能:p该位为1,q对应低位为0;p该位为0,q对应低位为1。剩下依此类推

剪枝条件: 将p、q未搜索到的位全填0,乘积应小于n 将p、q未搜索到的位全填1,乘积应大于n p、q 低 k 位乘积再取低 k 位,应与 n 的低 k 位相同

exp:

第一部分参考鸡块大神的文章。

from Crypto.Util.number import *
import sys
e = 65537
leak = 5599968251197363876087002284371721787318931284225671549507477934076746561842
n = 7120275986401660066259983193598830554385933355254283093021239164350142898387660104515624591378875067038235085428170557400012848874756868985306042421950909
c = 6803450117490196163076010186755045681029929816618361161925865477601994608941714788803007124967390157378525581080320415602012078322064392991884070073083436
P = (4143131125485719352848137000299706175276016714942734255688381872061184989156686585992844083387698688432978380177564346382756951426943827434190895490233627 , 3879946878859691332371384275396678851932267609535096278038417524609690721322205780110680003522999409696718745532857001461869452116434787256032366267905519) p_xor_q = str(bin(leak)[2:]).zfill(256) def find(ph, qh, pl, ql):
l = len(ph)
tmp0 = ph + (256 - 2 * l) * "0" + pl
tmp1 = ph + (256 - 2 * l) * "1" + pl
tmq0 = qh + (256 - 2 * l) * "0" + ql
tmq1 = qh + (256 - 2 * l) * "1" + ql
if (int(tmp0, 2) * int(tmq0, 2) > n):
return
if (int(tmp1, 2) * int(tmq1, 2) < n):
return
if (int(pl, 2) * int(ql, 2) % (2 ** (l - 1)) != n % (2 ** (l - 1))):
return if (l == 128):
pp0 = int(tmp0, 2)
if (n % pp0 == 0):
pf = pp0
qf = n // pp0
print(pf)
print(qf)
phi = (pf - 1) * (qf - 1)
d = inverse(e, phi)
m1 = pow(c, d, n)
print(long_to_bytes(m1))
exit() else:
if (p_xor_q[l] == "1" and p_xor_q[255 - l] == "1"):
find(ph + "1", qh + "0", "1" + pl, "0" + ql)
find(ph + "0", qh + "0", "1" + pl, "1" + ql)
find(ph + "1", qh + "1", "0" + pl, "0" + ql)
find(ph + "0", qh + "1", "0" + pl, "1" + ql)
elif (p_xor_q[l] == "1" and p_xor_q[255 - l] == "0"):
find(ph + "1", qh + "0", "0" + pl, "0" + ql)
find(ph + "0", qh + "0", "0" + pl, "1" + ql)
find(ph + "1", qh + "1", "1" + pl, "0" + ql)
find(ph + "0", qh + "1", "1" + pl, "1" + ql)
elif (p_xor_q[l] == "0" and p_xor_q[255 - l] == "1"):
find(ph + "0", qh + "0", "1" + pl, "0" + ql)
find(ph + "0", qh + "1", "0" + pl, "0" + ql)
find(ph + "1", qh + "0", "1" + pl, "1" + ql)
find(ph + "1", qh + "1", "0" + pl, "1" + ql)
elif (p_xor_q[l] == "0" and p_xor_q[255 - l] == "0"):
find(ph + "0", qh + "0", "0" + pl, "0" + ql)
find(ph + "1", qh + "0", "0" + pl, "1" + ql)
find(ph + "0", qh + "1", "1" + pl, "0" + ql)
find(ph + "1", qh + "1", "1" + pl, "1" + ql) find("1", "1", "1", "1")
# p = 64760524083545528318139240449356269097871629401328435356643510319660757701117
# q = 109947782034870726628911928816041880655659770652764045401662566933641952899777
# -908f-7c002c687387

第二部分ECC,在这里已知n,a,b,P,而m2是就是M的x坐标,那么主要任务就是求出e,对于曲线的逆元。而n的位数较大,这里试过,无法直接求取模n的曲线的阶,而n = p * q,所以可以转为求模p,模q的阶,之后求取e对于n的逆元。

# sage
from Crypto.Util.number import *
p = 64760524083545528318139240449356269097871629401328435356643510319660757701117
q = 109947782034870726628911928816041880655659770652764045401662566933641952899777
e = 65537
n = 7120275986401660066259983193598830554385933355254283093021239164350142898387660104515624591378875067038235085428170557400012848874756868985306042421950909
P = E(4143131125485719352848137000299706175276016714942734255688381872061184989156686585992844083387698688432978380177564346382756951426943827434190895490233627 , 3879946878859691332371384275396678851932267609535096278038417524609690721322205780110680003522999409696718745532857001461869452116434787256032366267905519)
E = EllipticCurve(Zmod(n),[114514,1919810])
Ep = EllipticCurve(Zmod(p),[114514,1919810])
Eq = EllipticCurve(Zmod(q),[114514,1919810])
phi_n = Ep.order()*Eq.order()
d = inverse(e,phi_n)
G = P * d
m = G[0]
flag = long_to_bytes(int(m))
print(flag)
# a67b2a9b-0542-4646

2024SHCTF--Crypto--Week1&Week2--WP的更多相关文章

  1. BUUCTF CRYPTO部分题目wp

    对密码学了解不多,做一下熟悉熟悉 1,看我回旋踢 给的密文synt{5pq1004q-86n5-46q8-o720-oro5on0417r1} 简单的凯撒密码,用http://www.zjslove. ...

  2. 【代码笔记】iOS-和当前时间比较

    代码: #import "RootViewController.h" @interface RootViewController () @end @implementation R ...

  3. Js计算-当月每周有多少天

    查看Demo: 源代码如下: <script> //计算当月总天数 function getCountDays() { var curDate = new Date(); /* 获取当前月 ...

  4. pat_1014

    1014. 福尔摩斯的约会 (20) 时间限制 50 ms 内存限制 32000 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 大侦探福尔摩斯接到一张奇怪的字 ...

  5. Coursera深度学习(DeepLearning.ai)编程题&笔记

    因为是Jupyter Notebook的形式,所以不方便在博客中展示,具体可在我的github上查看. 第一章 Neural Network & DeepLearning week2 Logi ...

  6. 日期求星期(java)-蓝桥杯

    日期求星期问题(java)-蓝桥杯 1:基姆拉尔森计算公式(计算星期) 公式: int week = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; 此处y,m,d指代年 ...

  7. sql pivot(行转列) 和unpivot(列转行)的用法

    1.PIVOT用法(行转列) select * from Table_Score as a pivot (sum(score) for a.name in ([语文],[数学],[外语],[文综],[ ...

  8. [2017BUAA软工助教]学期总结

    一.表 学号 第0次 week1 week2 week3 个人项目 附加1 结对项目 附加2 a团队得分 a贡献分 b团队得分 b贡献分 阅读作业 提问回顾 总分1 总分2 14011100 8 8 ...

  9. [2017BUAA软工助教]个人得分总表(至alpha结束)

    一.表 学号 第0次 week1 week2 week3 个人项目 附加1 结对项目 附加2 a团队 a团队得分 a贡献分 总分(不计) 总分(记) 15061119 7 9.5 12 9 45.75 ...

  10. 20172324《Java程序设计》第3周学习总结

    20172324<Java程序设计>第3周学习总结 教材学习内容总结 随机数,记住要返回的是指定的字符前一个. String类型的一些用法,例如concat(连接),toUpperCase ...

随机推荐

  1. 【牛客刷题】HJ15 求int型正整数在内存中存储时1的个数

    题目链接 题倒是很简单,最开始用了这么一种解法: package main import "fmt" func main() { a := 0 fmt.Scan(&a) s ...

  2. Python向IP地址发送字符串

    在Python中,向IP地址发送字符串通常意味着你需要通过某种协议来实现通信.最常见的协议包括TCP和UDP.这里,我将分别给出使用TCP和UDP协议向指定IP地址发送字符串的示例代码. 1.TCP. ...

  3. GC终结标记 SuspendEE 是怎么回事

    一:背景 1. 讲故事 写这篇是起源于训练营里有位朋友提到了一个问题,在 !t -special 输出中有一个 SuspendEE 字样,这个字样在 coreclr 中怎么弄的?输出如下: 0:000 ...

  4. SSH 登陆 Windows 时踩过的坑

    有一次处于某些原因我在 Mac 上使用 SSH 远程登陆了 Windows,然后在 Windows 上使用 SSH 登陆 localhost,惊讶地发现登不进去!SSH 提示公钥验证失败.可是我的 W ...

  5. 【Burp Suite】Mac之破解明文密码

    一.安装CA证书 安装证书是为了代理的时候可以继续访问地址,否则的话会提示网络异常 参考文章:<Mac系统Burp Suite的安装>,文章中是火狐浏览器的操作 1.谷歌浏览器 选择导出的 ...

  6. IDEA - ruoyi - srpingboot - 离线运行

    前提:有项目对应的repository文件,RY的DB配置正常(mysql新增schema ry, 执行 /sql下的sql文件,同步调整ruoyi-admin下的application-druid. ...

  7. manim边学边做--带箭头直线

    带箭头的直线就是有方向的直线,既可以用来表示矢量,也可以用来标记某个关键位置.manim中提供了4种常用的带箭头的直线模块: Arrow:单箭头的直线 DoubleArrow:双箭头的直线 Label ...

  8. 游戏AI行为决策——MLP(多层感知机/人工神经网络)

    游戏AI行为决策(特别篇)--MLP(附代码与项目) 你一定听说过神经网络的大名,你有想过将它用于游戏AI的行为决策上吗?其实在(2010年发布的)<最高指挥官2>中就有应用了,今天请允许 ...

  9. Angular 18+ 高级教程 – 目录

    请按顺序阅读 关于本教程 初识 Angular Get Started Angular Compiler (AKA ngc) Quick View Dependency Injection 依赖注入  ...

  10. SQL Server 冗余维护

    介绍 冗余是维护的魔鬼, 是性能优化的天使 常见的冗余有 1. computed column 2. principal 的识别字段 3. cross computed 4. cascade soft ...