BUUCTF——rsa系列(6)

目录

[INSHack2019]Yet Another RSA Challenge - Part 1

[NPUCTF2020]共 模 攻 击


[INSHack2019]Yet Another RSA Challenge - Part 1

题目:

import subprocess
p = subprocess.check_output('openssl prime -generate -bits 2048 -hex')
q = subprocess.check_output('openssl prime -generate -bits 2048 -hex')
flag = int('INSA{REDACTED}'.encode('hex'), 16)

N = int(p,16) * int(q,16)
print N
print '0x'+p.replace('9F','FC')
print pow(flag,65537,N)

给了n、c、e、以及被替换过的p。

可以看到替换规则是将‘9F’ 换成‘FC’,通过将替换过的p进行按‘FC’分隔,得到:

说明有4个‘FC’,但是我们不能确定这里所有的‘FC’都是被替换而来的,也有可能原本就有,所以这里共有2^{4} == 16种情况,需要进行爆破。在爆破的过程中满足能被n整除的p就可以退出,整体代码如下:

import gmpy2
from Crypto.Util.number import *

e = 65537
p = '0xDCC5A0BD3A1FC0BEB0DA1C2E8CF6B474481B7C12849B76E03C4C946724DB577D2825D6AA193DB559BC9DBABE1DDE8B5E7805E48749EF002F622F7CDBD7853B200E2A027E87E331AFCFD066ED9900F1E5F5E5196A451A6F9E329EB889D773F08E5FBF45AACB818FD186DD74626180294DCC31805A88D1B71DE5BFEF3ED01F12678D906A833A78EDCE9BDAF22BBE45C0BFB7A82AFE42C1C3B8581C83BF43DFE31BFD81527E507686956458905CC9A660604552A060109DC81D01F229A264AB67C6D7168721AB36DE769CEAFB97F238050193EC942078DDF5329A387F46253A4411A9C8BB71F9AEB11AC9623E41C14FCD2739D76E69283E57DDB11FC531B4611EE3'
n = 719579745653303119025873098043848913976880838286635817351790189702008424828505522253331968992725441130409959387942238566082746772468987336980704680915524591881919460709921709513741059003955050088052599067720107149755856317364317707629467090624585752920523062378696431510814381603360130752588995217840721808871896469275562085215852034302374902524921137398710508865248881286824902780186249148613287250056380811479959269915786545911048030947364841177976623684660771594747297272818410589981294227084173316280447729440036251406684111603371364957690353449585185893322538541593242187738587675489180722498945337715511212885934126635221601469699184812336984707723198731876940991485904637481371763302337637617744175461566445514603405016576604569057507997291470369704260553992902776099599438704680775883984720946337235834374667842758010444010254965664863296455406931885650448386682827401907759661117637294838753325610213809162253020362015045242003388829769019579522792182295457962911430276020610658073659629786668639126004851910536565721128484604554703970965744790413684836096724064390486888113608024265771815004188203124405817878645103282802994701531113849607969243815078720289912255827700390198089699808626116357304202660642601149742427766381
c = 596380963583874022971492302071822444225514552231574984926542429117396590795270181084030717066220888052607057994262255729890598322976783889090993129161030148064314476199052180347747135088933481343974996843632511300255010825580875930722684714290535684951679115573751200980708359500292172387447570080875531002842462002727646367063816531958020271149645805755077133231395881833164790825731218786554806777097126212126561056170733032553159740167058242065879953688453169613384659653035659118823444582576657499974059388261153064772228570460351169216103620379299362366574826080703907036316546232196313193923841110510170689800892941998845140534954264505413254429240789223724066502818922164419890197058252325607667959185100118251170368909192832882776642565026481260424714348087206462283972676596101498123547647078981435969530082351104111747783346230914935599764345176602456069568419879060577771404946743580809330315332836749661503035076868102720709045692483171306425207758972682717326821412843569770615848397477633761506670219845039890098105484693890695897858251238713238301401843678654564558196040100908796513657968507381392735855990706254646471937809011610992016368630851454275478216664521360246605400986428230407975530880206404171034278692756


p1 = p.split('FC')
print(p1)

repalce_list = ['9F','FC']
for i in repalce_list:
    for j in repalce_list:
        for k in repalce_list:
            for m in repalce_list:
                p2 = '0xDCC5A0BD3A1' + i + '0BEB0DA1C2E8CF6B474481B7C12849B76E03C4C946724DB577D2825D6AA193DB559BC9DBABE1DDE8B5E7805E48749EF002F622F7CDBD7853B200E2A027E87E331A' + j + 'FD066ED9900F1E5F5E5196A451A6F9E329EB889D773F08E5FBF45AACB818FD186DD74626180294DCC31805A88D1B71DE5BFEF3ED01F12678D906A833A78EDCE9BDAF22BBE45C0BFB7A82AFE42C1C3B8581C83BF43DFE31BFD81527E507686956458905CC9A660604552A060109DC81D01F229A264AB67C6D7168721AB36DE769CEAFB97F238050193EC942078DDF5329A387F46253A4411A9C8BB71F9AEB11AC9623E41C14' + k + 'D2739D76E69283E57DDB11' + m + '531B4611EE3'
                p3 = int(p2,16)
                if n % p3 == 0:
                    p = p3
                    break

q = n // p
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
m = gmpy2.powmod(c,d,n)

print(long_to_bytes(m))

[NPUCTF2020]共 模 攻 击

hint.py:

from gmpy2 import *
from Crypto.Util.number import *
from secret import hint

m = bytes_to_long(hint)
p = getPrime(256)
c = pow(m, 256, p)
print(p)

p, q = getPrime(256), getPrime(256)
n = p * q
e1, e2 = getPrime(32), getPrime(32)
c1, c2 = pow(c, e1, n), pow(c, e2, n)
print(n)
print(e1, c1)
print(e2, c2)

'''
107316975771284342108362954945096489708900302633734520943905283655283318535709
6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579
2303413961 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723
2622163991 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249
'''

task.py:

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

flag = flag.strip(b"npuctf{").strip(b"}")
m = bytes_to_long(flag)

p, q = getPrime(512), getPrime(512)
n = p * q
e1, e2 = p, q
c1, c2 = pow(m, e1, n), pow(m, e2, n)

print(n)
print(c1)
print(c2)

'''
128205304743751985889679351195836799434324346996129753896234917982647254577214018524580290192396070591032007818847697193260130051396080104704981594190602854241936777324431673564677900773992273463534717009587530152480725448774018550562603894883079711995434332008363470321069097619786793617099517770260029108149
96860654235275202217368130195089839608037558388884522737500611121271571335123981588807994043800468529002147570655597610639680977780779494880330669466389788497046710319213376228391138021976388925171307760030058456934898771589435836261317283743951614505136840364638706914424433566782044926111639955612412134198
9566853166416448316408476072940703716510748416699965603380497338943730666656667456274146023583837768495637484138572090891246105018219222267465595710692705776272469703739932909158740030049375350999465338363044226512016686534246611049299981674236577960786526527933966681954486377462298197949323271904405241585
'''

首先解hint:

看到有两部分,第一部分是以e = 256的rsa解密,但因为e与phi_n不互质的原因,用一般的方法解不出来,看了大佬们的wp后,知道了用sympy.nthroots_mod(c,e,n)来解,可以用于e不是很大且一般的rsa解法行不通的时候。

from Crypto.Util.number import *
import sympy

n = 6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579
p = 107316975771284342108362954945096489708900302633734520943905283655283318535709

m = sympy.nthroot_mod(c,256,p)
print(long_to_bytes(m))

得到hint,最终的flag长度小于400。感觉没什么用:

b'm.bit_length() < 400'

第二部分则是共模攻击了,利用脚本可以解出c来:

from gmpy2 import *

e1 = 2303413961
c1 = 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723
e2 = 2622163991
c2 = 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249

s = gcdext(e1, e2)  #扩展欧几里得算法,得到x,y,即ax+by=gcd(a,b)
m1 = pow(c1, s[1], n)
m2 = pow(c2, s[2], n)

c = (m1 * m2) % n
print(c)
#c = 19384002358725759679198917686763310349050988223627625096050800369760484237557

再来看task:

由给出的程序可以知道:

c1 = m^e1 mod n        c2 = m^e2 mod n,且e1 = p,e2 = q,故:

c1 = m^p mod n

c2 = m^q mod n

 接下来就是利用定理来得到一个方程了,参考了大佬的步骤,尝试着推一推吧(嫌敲起来麻烦,在纸上推算了!)

 

 系数都是已知的,利用sage运算:

# sage
# R.<m> = Zmod(n)[]
# f = m^2 - (c1 + c2)*m + c1*c2
# flag = f.smallroots(2^400)[0] #括号内的是根的边界,我们所求的根也就是m,这里hint已经给出了m.bit_length()<400

整体代码如下:

from gmpy2 import *
from Crypto.Util.number import *
import sympy

n = 6807492006219935335233722232024809784434293293172317282814978688931711423939629682224374870233587969960713638310068784415474535033780772766171320461281579
p = 107316975771284342108362954945096489708900302633734520943905283655283318535709
c = 19384002358725759679198917686763310349050988223627625096050800369760484237557
q = n // p
m = sympy.nthroot_mod(c,256,p)
print(long_to_bytes(m))

e1 = 2303413961
c1 = 1754421169036191391717309256938035960912941109206872374826444526733030696056821731708193270151759843780894750696642659795452787547355043345348714129217723
e2 = 2622163991
c2 = 1613454015951555289711148366977297613624544025937559371784736059448454437652633847111272619248126613500028992813732842041018588707201458398726700828844249

s = gcdext(e1, e2)  #扩展欧几里得算法,得到x,y,即ax+by=gcd(a,b)
m1 = pow(c1, s[1], n)
m2 = pow(c2, s[2], n)

c = (m1 * m2) % n
print(c)
#c = 19384002358725759679198917686763310349050988223627625096050800369760484237557

flag = 4242839043019782000788118887372132807371568279472499477998758466224002905442227156537788110520335652385855
print(long_to_bytes(flag))

思路代码参考:http://t.csdn.cn/M2Hi1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值