[GWCTF 2019]babyRSA | NSSCTF
观察主函数
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 
 | import hashlibimport sympy
 from Crypto.Util.number import *
 
 flag = 'GWHT{******}'
 secret = '******'
 
 assert(len(flag) == 38)
 
 half = len(flag) / 2
 
 flag1 = flag[:half]
 flag2 = flag[half:]
 
 secret_num = getPrime(1024) * bytes_to_long(secret)
 
 p = sympy.nextprime(secret_num)
 q = sympy.nextprime(p)
 
 N = p * q
 
 e = 0x10001
 
 F1 = bytes_to_long(flag1)
 F2 = bytes_to_long(flag2)
 
 c1 = F1 + F2
 c2 = pow(F1, 3) + pow(F2, 3)
 assert(c2 < N)
 
 m1 = pow(c1, e, N)
 m2 = pow(c2, e, N)
 
 output = open('secret', 'w')
 output.write('N=' + str(N) + '\n')
 output.write('m1=' + str(m1) + '\n')
 output.write('m2=' + str(m2) + '\n')
 output.close()
 
 
 | 
给了N,m1,m2
| 12
 3
 4
 
 | N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
 m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
 
 
 | 
此处p和q是两个相邻的素数
| 12
 
 | p = sympy.nextprime(secret_num)q = sympy.nextprime(p)
 
 | 
可以通过对N开根号求出后面的q(注意此处需要用sympy的sqrt,math库的sqrt无法求解这么大的数)
exp:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | import hashlibimport sympy
 from Crypto.Util.number import *
 e = 0x10001
 N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
 m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
 m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
 q=sympy.nextprime(sympy.sqrt(N))
 p=sympy.prevprime(q)
 print(p*q==N)
 phi=(p-1)*(q-1)
 d=int(sympy.invert(e,phi))
 c1=pow(m1,d,N)
 c2=pow(m2,d,N)
 from z3 import*
 f=Solver()
 F1,F2=Int('F1'),Int('F2')
 f.add(F1+F2==c1,pow(F1,3)+pow(F2,3)==c2)
 while f.check()==sat:
 m=f.model()
 nF1,nF2=m[F1],m[F2]
 f.add(Or(F1!=nF1,F2!=nF2))
 flag1,flag2=long_to_bytes(int(str(nF1))),long_to_bytes(int(str(nF2)))
 flag=flag1+flag2
 print(flag)
 
 | 
最终通过求解phi(N)((p-1)*(q-1))和e关于模phi(N)的逆元
通过公式 c=pow(m,d,N)就可以求解出对应的明文了
结果(因为F1和F2等价所以有两个值)
