2023 LitCTF — Crypto wp

  • Post author:
  • Post category:其他




前言

由于探姬小姐姐(bushi)跟我讲LitCTF是一个新生赛捏,所以我出的几个题题目都是比较简单,偏向于新手向。这里面可能有一点难度的题目就是baby_xor了,简单考一下copper定理,但是最终有45解挺出乎我的意料的。



easy_math

题目:

from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
e = 65537
p = getPrime(512)
q = getPrime(128)
n = p*q
hint = p**3-q**5
c = pow(m,e,n)
print(f'n = {n}')
print(f'c = {c}')
print(f'hint = {hint}')
'''
n = 2230791374046346835775433548641067593691369485828070649075162141394476183565187654365131822111419512477883295758461313983481545182887415447403634720326639070667688614534290859200753589300443797
c = 2168563038335029902089976057856861885635845445863841607485310134441400500612435296818745930370268060353437465666224400129105788787423156958336380480503762222278722770240792709450637433509537280
hint = 392490868359411675557103683163021977774935163924606169241731307258226973701652855448542714274348304997416149742779376023311152228735117186027560227613656229190807480010615064372521942836446425717660375242197759811804760170129768647414717571386950790115746414735411766002368288743086845078803312201707960465419405926186622999423245762570917629351110970429987377475979058821154568001902541710817731089463915930932142007312230897818177067675996751110894377356758932
''' 


思路1:

已知



n

=

p

q

n=p*q






n




=








p













q





,以及



h

i

n

t

=

p

3

q

5

hint = p^3-q^5






hin


t




=









p










3





















q










5












,可直接构成方程组,然后直接解方程得到p q。

import gmpy2
from Crypto.Util.number import *
from sympy import *
n = 2230791374046346835775433548641067593691369485828070649075162141394476183565187654365131822111419512477883295758461313983481545182887415447403634720326639070667688614534290859200753589300443797
c = 2168563038335029902089976057856861885635845445863841607485310134441400500612435296818745930370268060353437465666224400129105788787423156958336380480503762222278722770240792709450637433509537280
hint = 392490868359411675557103683163021977774935163924606169241731307258226973701652855448542714274348304997416149742779376023311152228735117186027560227613656229190807480010615064372521942836446425717660375242197759811804760170129768647414717571386950790115746414735411766002368288743086845078803312201707960465419405926186622999423245762570917629351110970429987377475979058821154568001902541710817731089463915930932142007312230897818177067675996751110894377356758932
e = 65537
p, q = symbols("p q")
eq = [p * q - n, p**3-q**5 - hint]
result = list(nonlinsolve(eq, [p, q]))
p, q = int(result[0][0]), int(result[0][1])
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)


思路2:

由于



p

3

p^3







p










3












远大于



q

5

q^5







q










5












,所以我们直接对hint开三次方,可到一个近似p的数,之后往后循环取下一个素数直至被n整除即可,此时该素数为p。

import gmpy2
from Crypto.Util.number import *
from sympy import *
n = 2230791374046346835775433548641067593691369485828070649075162141394476183565187654365131822111419512477883295758461313983481545182887415447403634720326639070667688614534290859200753589300443797
c = 2168563038335029902089976057856861885635845445863841607485310134441400500612435296818745930370268060353437465666224400129105788787423156958336380480503762222278722770240792709450637433509537280
hint = 392490868359411675557103683163021977774935163924606169241731307258226973701652855448542714274348304997416149742779376023311152228735117186027560227613656229190807480010615064372521942836446425717660375242197759811804760170129768647414717571386950790115746414735411766002368288743086845078803312201707960465419405926186622999423245762570917629351110970429987377475979058821154568001902541710817731089463915930932142007312230897818177067675996751110894377356758932
e = 65537
p_near = gmpy2.iroot(hint,3)[0]
while n%p_near !=0:
    p_near = gmpy2.next_prime(p_near)
p = p_near
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)



Euler

题目:

from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p*q
c = pow(m,n-p-q+3,n)
print(f'n = {n}')
print(f'c = {c}')
"""
n = 115140122725890943990475192890188343698762004010330526468754961357872096040956340092062274481843042907652320664917728267982409212988849109825729150839069369465433531269728824368749655421846730162477193420534803525810831025762500375845466064264837531992986534097821734242082950392892529951104643690838773406549
c = 406480424882876909664869928877322864482740577681292497936198951316587691545267772748204383995815523935005725558478033908575228532559165174398668885819826720515607326399097899572022020453298441
"""

这题的考点是对

欧拉定理

的运用。

欧拉定理:对于任意两个正整数a,n,若gcd(a,n)=1,则:





a

φ

(

n

)

1

 

m

o

d

 

n

a^{\varphi(n)} \equiv 1 \space mod \space n







a











φ


(


n


)





















1




m


o


d




n







已知





c

m

n

p

q

+

3

 

m

o

d

 

n

c \equiv m^{n-p-q+3} \space mod \space n






c














m











n





p





q


+


3












m


o


d




n







根据欧拉定理,化简,得到





c

m

φ

(

n

)

+

2

m

o

d

n

m

2

 

m

o

d

 

n

c \equiv m^{\varphi(n)+2} mod n \equiv m^2 \space mod \space n






c














m











φ


(


n


)


+


2










m


o


d


n














m










2











m


o


d




n







因此直接将c开平方即可到flag

import gmpy2
from Crypto.Util.number import *

n = 115140122725890943990475192890188343698762004010330526468754961357872096040956340092062274481843042907652320664917728267982409212988849109825729150839069369465433531269728824368749655421846730162477193420534803525810831025762500375845466064264837531992986534097821734242082950392892529951104643690838773406549
c = 406480424882876909664869928877322864482740577681292497936198951316587691545267772748204383995815523935005725558478033908575228532559165174398668885819826720515607326399097899572022020453298441
m = gmpy2.iroot(c,2)[0]
flag = long_to_bytes(m)
print(flag)



babyLCG

题目:

from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
bit_len = m.bit_length()
a = getPrime(bit_len)
b = getPrime(bit_len)
p = getPrime(bit_len+1)

seed = m
result = []
for i in range(10):
    seed = (a*seed+b)%p
    result.append(seed)
print(result)
"""
result = [699175025435513913222265085178805479192132631113784770123757454808149151697608216361550466652878, 193316257467202036043918706856603526262215679149886976392930192639917920593706895122296071643390, 1624937780477561769577140419364339298985292198464188802403816662221142156714021229977403603922943, 659236391930254891621938248429619132720452597526316230221895367798170380093631947248925278766506, 111407194162820942281872438978366964960570302720229611594374532025973998885554449685055172110829, 1415787594624585063605356859393351333923892058922987749824214311091742328340293435914830175796909, 655057648553921580727111809001898496375489870757705297406250204329094679858718932270475755075698, 1683427135823894785654993254138434580152093609545092045940376086714124324274044014654085676620851, 492953986125248558013838257810313149490245209968714980288031443714890115686764222999717055064509, 70048773361068060773257074705619791938224397526269544533030294499007242937089146507674570192265]
"""  

本题主要是对4个LCG公式的综合利用,属于一道非常经典的LCG基础题目

1.已知



X

n

+

1

反推

X

n

X_{n+1}反推X_n







X











n


+


1



















反推



X










n


























X

n

=

a

1

(

X

n

+

1

b

)

 

m

o

d

 

m

X_n = a^{-1}(X_{n+1}-b)\space mod \space m







X










n




















=









a














1










(



X











n


+


1






























b


)




m


o


d




m







证明:




X

n

+

1

=

a

X

n

+

b

 

m

o

d

 

m

X_{n+1} = aX_n +b \space mod \space m







X











n


+


1





















=








a



X










n




















+








b




m


o


d




m









a

X

n

=

X

n

+

1

b

 

m

o

d

 

m

\Rightarrow aX_n = X_{n+1}-b \space mod \space m















a



X










n




















=









X











n


+


1






























b




m


o


d




m









X

n

=

a

1

(

X

n

+

1

b

)

 

m

o

d

 

m

\Rightarrow X_n = a^{-1}(X_{n+1}-b) \space mod \space m
















X










n




















=









a














1










(



X











n


+


1






























b


)




m


o


d




m




2.求a





a

=

(

X

n

+

2

X

n

+

1

)

(

X

n

+

1

X

n

)

1

 

m

o

d

 

m

a = (X_{n+2}-X_{n+1})(X_{n+1}-X_{n})^{-1} \space mod \space m






a




=








(



X











n


+


2































X











n


+


1



















)


(



X











n


+


1































X











n




















)














1












m


o


d




m







证明:




{

X

n

+

2

=

a

X

n

+

1

+

b

 

m

o

d

 

m

 

X

n

+

1

=

a

X

n

1

+

b

 

m

o

d

 

m

\left\{\begin{matrix} X_{n+2} = aX_{n+1}+b \space mod \space m \space \\ X_{n+1} = aX_{n1}+b \space mod \space m \end{matrix}\right.








{















X











n


+


2





















=




a



X











n


+


1





















+




b




m


o


d




m











X











n


+


1





















=




a



X











n


1





















+




b




m


o


d




m


























两式相减




X

n

+

2

X

n

+

1

=

a

(

X

n

+

1

X

n

)

 

m

o

d

 

m

X_{n+2}-X_{n+1} = a(X_{n+1}-X_n) \space mod \space m







X











n


+


2































X











n


+


1





















=








a


(



X











n


+


1































X










n


















)




m


o


d




m









a

=

(

X

n

+

2

X

n

+

1

)

(

X

n

+

1

X

n

)

1

 

m

o

d

 

m

\Rightarrow a = (X_{n+2}-X_{n+1})(X_{n+1}-X_n)^{-1} \space mod \space m















a




=








(



X











n


+


2































X











n


+


1



















)


(



X











n


+


1































X










n



















)














1












m


o


d




m






3.求b





b

=

(

X

n

+

1

a

X

n

)

 

m

o

d

 

m

b = (X_{n+1}-aX_{n}) \space mod \space m






b




=








(



X











n


+


1






























a



X











n



















)




m


o


d




m







证明:




X

n

+

1

=

a

X

n

+

b

 

m

o

d

 

m

X_{n+1} = aX_n +b \space mod \space m







X











n


+


1





















=








a



X










n




















+








b




m


o


d




m









b

=

X

n

+

1

a

X

n

 

m

o

d

 

m

\Rightarrow b = X_{n+1}-aX_n \space mod \space m















b




=









X











n


+


1






























a



X










n




















m


o


d




m






4.求m





t

n

=

X

n

+

1

X

n

,

m

=

g

c

d

(

t

n

+

1

t

n

1

t

n

t

n

,

t

n

t

n

2

t

n

1

t

n

1

)

t_n = X_{n+1}-X_{n},m = gcd(t_{n+1}t_{n-1}-t_{n}t_{n},t_{n}t_{n-2}-t_{n-1}t_{n-1})







t










n




















=









X











n


+


1































X











n



















,




m




=








g


c


d


(



t











n


+


1




















t











n





1































t











n




















t











n



















,





t











n




















t











n





2































t











n





1




















t











n





1



















)







证明:





t

n

=

X

n

+

1

X

n

t_n= X_{n+1}-X_n







t










n




















=









X











n


+


1































X










n

























t

n

=

(

a

X

n

+

b

)

(

a

X

n

1

+

b

)

=

a

t

n

1

 

m

o

d

 

m

\Rightarrow t_n = (aX_n+b)-(aX_{n-1}+b)=at_{n-1} \space mod \space m
















t










n




















=








(


a



X










n




















+








b


)













(


a



X











n





1





















+








b


)




=








a



t











n





1





















m


o


d




m









t

n

+

1

t

n

1

t

n

t

n

=

a

t

n

t

n

1

a

t

n

1

a

t

n

1

 

m

o

d

 

m

\Rightarrow t_{n+1}t_{n-1}-t_{n}t_{n} = at_{n}t_{n-1}-at_{n-1}at_{n-1} \space mod \space m
















t











n


+


1




















t











n





1































t











n




















t











n





















=








a



t











n




















t











n





1






























a



t











n





1



















a



t











n





1





















m


o


d




m









t

n

+

1

t

n

1

t

n

t

n

=

a

a

t

n

1

t

n

1

a

t

n

1

a

t

n

1

 

m

o

d

 

m

\Rightarrow t_{n+1}t_{n-1}-t_{n}t_{n} = aat_{n-1}t_{n-1}-at_{n-1}at_{n-1} \space mod \space m
















t











n


+


1




















t











n





1































t











n




















t











n





















=








aa



t











n





1




















t











n





1






























a



t











n





1



















a



t











n





1





















m


o


d




m









t

n

+

1

t

n

1

t

n

t

n

=

0

 

m

o

d

 

m

\Rightarrow t_{n+1}t_{n-1}-t_{n}t_{n} = 0 \space mod \space m
















t











n


+


1




















t











n





1































t











n




















t











n





















=








0




m


o


d




m






可证,



T

n

=

t

n

+

1

t

n

1

t

n

t

n

T_n = t_{n+1}t_{n-1}-t_{n}t_{n}







T










n




















=









t











n


+


1




















t











n





1































t











n




















t











n


























m

m






m





的倍数

那么,



T

n

T

n

1

之间的最大公约数数大概率

m

T_n和T_{n-1}之间的最大公约数数大概率m







T










n






















T











n





1



















之间的最大公约数数大概率


m









m

=

g

c

d

(

T

n

,

T

n

1

)

\Rightarrow m = gcd(T_n,T_{n-1})















m




=








g


c


d


(



T










n


















,





T











n





1



















)









m

=

g

c

d

(

(

t

n

+

1

t

n

1

t

n

t

n

)

,

(

t

n

t

n

2

t

n

1

t

n

1

)

)

\Rightarrow m = gcd((t_{n+1}t_{n-1}-t_{n}t_{n}),(t_{n}t_{n-2}-t_{n-1}t_{n-1}))















m




=








g


c


d


((



t











n


+


1




















t











n





1































t











n




















t











n



















)


,




(



t











n




















t











n





2































t











n





1




















t











n





1



















))




由于在求m的时候不知道gcd出来的是m还是m的倍数,所以我们把每组



g

c

d

(

T

n

,

T

n

1

)

gcd(T_n,T_{n-1})






g


c


d


(



T










n


















,





T











n





1



















)





都算出来,然后再计算出a和b,最后看一下哪一个是flag就ok了


解题脚本:

import gmpy2
from Crypto.Util.number import *
result = [699175025435513913222265085178805479192132631113784770123757454808149151697608216361550466652878, 193316257467202036043918706856603526262215679149886976392930192639917920593706895122296071643390, 1624937780477561769577140419364339298985292198464188802403816662221142156714021229977403603922943, 659236391930254891621938248429619132720452597526316230221895367798170380093631947248925278766506, 111407194162820942281872438978366964960570302720229611594374532025973998885554449685055172110829, 1415787594624585063605356859393351333923892058922987749824214311091742328340293435914830175796909, 655057648553921580727111809001898496375489870757705297406250204329094679858718932270475755075698, 1683427135823894785654993254138434580152093609545092045940376086714124324274044014654085676620851, 492953986125248558013838257810313149490245209968714980288031443714890115686764222999717055064509, 70048773361068060773257074705619791938224397526269544533030294499007242937089146507674570192265]
t = []
for i in range(len(result)-1):
    t.append(result[i]-result[i-1])
for i in range(len(result)-3):
    p = gmpy2.gcd((t[i + 1] * t[i - 1] - t[i] * t[i]), (t[i + 2] * t[i] - t[i + 1] * t[i + 1]))
    try:
        a = (gmpy2.invert(result[8] - result[7], p) * (result[9] - result[8])) % p
        b = (result[9] - a * result[8]) % p
        seed = (result[0] - b) * gmpy2.invert(a, p) % p
        print(long_to_bytes(seed))
    except:
        continue



baby_xor

题目:

from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
assert len(flag)==32
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 65537
c1 = p^m
c2 = pow(m,e,n)
print(f'n = {n}')
print(f'c1 = {c1}')
print(f'c2 = {c2}')
"""
n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
c2 = 112016152270171196606652761990170033221036025260883289104273504703557624964071464062375228351458191745141525003775876044271210498526920529385038130932141551598616579917681815276713386113932345056134302042399379895915706991873687943357627747262597883603999621939794450743982662393955266685255577026078256473601
"""

这题主要考点是

coppersmith

,但是卡了上届。需要去调

epsilon

增大格子,从而增大根的上限。当epsilon调至最小,即

0.01

时;

p



512bit



p

的高位至少泄露

264bit

时候,环多项式方程在模n情况下有解,但是现在

p = p>>256

,也就是说只泄露了高

256

位,我们还需要爆破

8bit

才能copper出来,大概爆破时间5~6分钟左右。

from tqdm import *
from Crypto.Util.number import *

n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
pbits = 512
p_high = c1>>256
for i in trange(2**8):
        p4 = p_high<<8
        p4 = p4 + i
        kbits = pbits - p4.nbits()
        p4 = p4 << kbits
        PR.<x> = PolynomialRing(Zmod(n))
        f = x + p4
        roots = 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
            
m = c1.__xor__(int(p))
flag = long_to_bytes(int(m))
print(flag)

【善,论心不论迹,论迹贫家无孝子;恶,论迹不论心,论心世上无完人。】



版权声明:本文为luochen2436原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。