DASCTF 2024暑期挑战赛------1z_RSA

题目:

from Crypto.Util.number import *
from sympy import *
import os
from secrets import flag

nbit =130
e = 3
l = getPrime(505)
m = bytes_to_long(flag + os.urandom(64))

assert len(flag) == 29

while True:
    p, q = getPrime(nbit), getPrime(nbit)
    PQ = int(str(p<<120)+str(q))
    QP = int(str(q<<120)+str(p))
    if isPrime(PQ) and isPrime(QP):
        break

n = PQ * QP
PP = nextprime((PQ >> 190) * (QP & (2 ** 190 - 1)))
QQ = nextprime((QP >> 190) * (PQ & (2 ** 190 - 1)))
N = PP * QQ
M = pow(m,1,l)
c = pow(m,e,N)

print('n =', n)
print('M =', M)
print('l =', l)
print('c =', c)

'''
n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322
l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189
c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923
'''

分析代码,需要求出m要得到N的值,那么就得求出PQQP。看一下PQQP的取值方式,知道\(PQ=p*2^{120}*10^{40}+q\)\(QP=q*2^{120}*10^{39}+p\),所以\(n=PQ*QP=p * q * (2 ^{240} * 10^{79} + 1) + (p^2 + 10 * q^2) * 2^{120} * 10^{39}\),分析一下知道\(2 ^{240} * 10^{79} + 1\)的比特位数大概是503左右,\((p^2 + 10 * q^2) * 2^{120} * 10^{39}\)的比特位数大概是510左右,两者相差不大,那么两边同时除以\(2 ^{240} * 10^{79} + 1\),得\(p*q=n//(2 ^{240} * 10^{79} + 1) \pm x\),这里x的值并不大,可以自行设置个区间进行爆破,那么p*q的值我们是可以知道的,要想求出两个未知数p q还需要知道一个方程才能解出来,我们回到最开始的\(n=PQ*QP=p * q * (2 ^{240} * 10^{79} + 1) + (p^2 + 10 * q^2) * 2^{120} * 10^{39}\),既然我们知道p*q的值我们可以转化一下等式为\(n-p * q * (2 ^{240} * 10^{79} + 1)=(p^2 + 10 * q^2) * 2^{120} * 10^{39}\),化简一下\(p^2 + 10 * q^2=\frac{n-p * q * (2 ^{240} * 10^{79} + 1)}{2^{120}*10^{39}}\),这就是我们第二个方程式了,最后写脚本求出p q注:n - p * q * (2 ^{240} * 10^{79} + 1)必须能被2^{120} * 10^{39}整除

exp:

from sympy import *

n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691

for x in range(1500):
    pq=n//(2**240*10**79+1)-x
    if (n-pq*(2**240*10**79+1))%(2**120*10**39)==0:
        p2_q2=(n-pq*(2**240*10**79+1))//(2**120*10**39)
        p=Symbol('p')
        q=Symbol('q')
        pq1=pq-p*q
        pq2=p**2+10*q**2-p2_q2
        s=solve((pq1,pq2))
        print(s)
#p: 1213149261930568621267125437333569321667, q: 855604426214387476576649090490109822073

最后求出N,接下来求解m

\[M=m \pm k*l \rightarrow c=(M \pm k*l)^3\mod N \]

那么我们可以用coppersmith求出k

exp:

from sympy import *

p = 1213149261930568621267125437333569321667
q = 855604426214387476576649090490109822073
PQ = int(str(p<<120)+str(q))
QP = int(str(q<<120)+str(p))
PP = nextprime((PQ >> 190) * (QP & (2 ** 190 - 1)))
QQ = nextprime((QP >> 190) * (PQ & (2 ** 190 - 1)))
N = PP * QQ
#N = 763933528218428362740063144747893290714655295576768532896029874141179804730143020017430379534079773751531037961074867132893544981605022026151484151321515584652838724809597675412676810669583078026377048734720511960708515190930979
#sage
from Crypto.Util.number import *

n = 18339446336492672809908730785358232636383625709800392830207979464962269419140428722248172110017576390002616004691759163126532392634394976712779777822451878822759056304050545622761060245812934467784888422790178920804822224673755691
M = 36208281423355218604990190624029584747447986456188203264389519699277658026754156377638444926063784368328407938562964768329134840563331354924365667733322
l = 56911058350450672322326236658556745353275014753768458552003425206272938093282425278193278997347671093622024933189270932102361261551908054703317369295189
c = 720286366572443009268610917990845759123049408295363966717060100862857351750759651979922104897091176824666482923148635058966589592286465060161271579501861264957611980854954664798904862706450723639237791023808177615189976108231923
N = 763933528218428362740063144747893290714655295576768532896029874141179804730143020017430379534079773751531037961074867132893544981605022026151484151321515584652838724809597675412676810669583078026377048734720511960708515190930979

PR.<x> = PolynomialRing(Zmod(N))
f = c - (M+x*l)^3
f = f.monic()
roots = f.small_roots(X=2^239,epsilon = 0.02)
k = roots[0]
m = M+k*l
print(long_to_bytes(m))
#DASCTF{Ar3_Y0u_Su93_Abt139??}
posted @ 2024-07-20 21:06  L00kback  阅读(180)  评论(0编辑  收藏  举报
Title