DASCTF2022九月赛-Crypto-easySignin

题目py文件:

from Crypto.Util.number import *
import libnum
from random import randint
from secret import flag

p = getPrime(512)
d = getPrime(40)
m = libnum.s2n(flag)
a = randint(2,p)
b = randint(2,p)
c = randint(2,p)
g = d

for i in range(10):
    g = (c*d^2 + b*g + a)%p
    a = (a*b - c) % p
    b = (b*c - a) % p 
    c = (c*a - b) % p 

t = (m+d)^2 %p

print('p=',p)
print('a=',a)
print('b=',b)
print('c=',c)
print('g=',g)
print('t=',t)

'''
p= 7591656713055743077369340861541583433090841738590989539280316533530045331013958613146671718809022799047779468311222607020894006899032327866283558110087799
a= 4392865163304254999527172406061971162689920565151840813033448791785156740502864894051809689255751412382468345217962713758808061870635744521996229554057672
b= 2119856022628544669301306700581535843188073099896481101405665476192582614655960576092254118367775147735092457551317887281026710342124525625026559538165667
c= 3370586754351688470908526079815435343732016329743637661764947106415792049906966624513736208696137655804912688128186282852926377345819134856707156640355705
g= 2221154642536617375933147254663757148609834736621720750750043572054496685087600339999953459509198087870095805651320901316659013390557077204194753685935362
t= 6426975621182152052236088849377616252912408340750729257254509090637526282051064469268808395760737262115678691330037039061905028548054911000486882481093832
'''

反正拿过来是不会,一看好家伙这循环,后来仔细观察了一下a、b、c是可以逆着循环求出来初值的,但之后还是不会,一看同事也一直没交,寻思害他也不会,无所谓咯~后来才知道人家周末根本没看这个题,然后吃完午饭回来那会儿工夫人家就做完了……(可恶
啊至于我,我到现在也不太懂(笑死
所以说努力有啥意义啊,再努力也比不上别人本来有天赋(哭死

碎碎念结束,看题。

首先还是逆着循环去求解abc,这里把每一次循环的a、b、c的值都缓存下来方便后续使用
知识点:线性同余式求解未知因数。(好像是叫这个吧?
就是说:

对于式子a*b mod p = c,b、p、c均已知时,可以求出a,a=c*invert(b,p) mod p

本题中 c = (c*a - b) % p ,等式左侧的c已知,a、b、p已知,想要求等式右侧和a相乘的那个c的值,原式可以转化为:

c+b mod p = c*a mod p

也就有c=(c+b)*invert(a,p) mod p,
同理有b=(b+a)*invert(c,p) mod p和a=(a+c)*invert(b,p) mod p
写Python脚本求解出从第10轮至第1轮循环的c、b、a的值,并缓存到一个列表abc中,列表的每个元素又是一个列表,存着每一轮循环求得的a、b、c的值。

a= 4392865163304254999527172406061971162689920565151840813033448791785156740502864894051809689255751412382468345217962713758808061870635744521996229554057672
b= 2119856022628544669301306700581535843188073099896481101405665476192582614655960576092254118367775147735092457551317887281026710342124525625026559538165667
c= 3370586754351688470908526079815435343732016329743637661764947106415792049906966624513736208696137655804912688128186282852926377345819134856707156640355705
p= 7591656713055743077369340861541583433090841738590989539280316533530045331013958613146671718809022799047779468311222607020894006899032327866283558110087799
abc=[0]*10
for i in range(9,-1,-1):
    c=(c+b)*gmpy2.invert(a,p)%p
    b=(b+a)*gmpy2.invert(c,p)%p
    a=(a+c)*gmpy2.invert(b,p)%p
    abc[i]=[int(a),int(b),int(c)]

然后进入新的世界:
借助SageMath求解题目文件中t = (m+d)^2 % p这个式子中(m+d)的值,这里t和p都是已知的。
关于SageMath怎么用(在macOS下:
先下载下来,我是从这里下的:http://mirrors.ustc.edu.cn/sagemath/osx/intel/index.html
然后在终端进入SageMath目录下,输入./sage,回车
在sage下输入:(要注意语法格式

p= 7591656713055743077369340861541583433090841738590989539280316533530045331013958613146671718809022799047779468311222607020894006899032327866283558110087799
t= 6426975621182152052236088849377616252912408340750729257254509090637526282051064469268808395760737262115678691330037039061905028548054911000486882481093832
R.=Zmod(p)[]
f=x^2-t
f.roots()

这里p和t都是题目中已知的。
DASCTF2022九月赛-Crypto-easySignin_第1张图片
得到两组解,不知道为什么要取下面那个,题目看上去并没有交代m+d的取值范围,所以这里暂且认为最后将两个值都代入计算试一试,确定需要的值是130661655927230795642760431379039778633673372572819159728043876332994399613135476225358。
所以到这里知道了m+d的值。

m+d=130661655927230795642760431379039778633673372572819159728043876332994399613135476225358

接下来就是借助for循环中对g值更新的运算来求d
观察表达式g = (c*d^2 + b*g + a)%p,之前我们已经计算出并缓存了每一次循环的a、b、c的值,最后一次循环结束后的g值已知,又知道循环开始前的g=d,可以设未知数d为xg的“临时值”(就是指循环结束得到最后的g之前的那些g的值,即从循环开始前的g=d到倒数第二次循环得到的g的值)为tg,且循环开始前tg=x,列出循环中的计算式,每轮循环参与计算g = (c*d^2 + b*g + a)%p的a、b、c直接用之前存在列表abc中的值,把这些已知条件都告诉SageMath,SageMath就可以求解出x即d的值。

没看明白?那直接往下看在SageMath里的代码怎么写吧,没想到还可以这么写,而且这么写还能求解出想要的值(属实不敢想
先在SageMath中给出需要的值,包括通过运行之前的Python脚本得到的列表abc,题目已知的p、g,然后还是按sage中的语法格式去设未知数x,注意在循环前要先写tg=x。个人理解,对于g = (c*d^2 + b*g + a)%p,d是x,有x的式子默认最后要%p,循环结束后得到的g移到另一侧,就有了f=tg-g,最后f.roots()得到方程的两组解。

abc=[[184972745971509494177749002438471045142431744349694071290568699875759696273259964144195521605616391458033949428260257403866133106081122954953351131066266, 5203346575880216155246099170513405396695418799624477309823705848477387257144158566705537881272662895232085767641640102113789121259979434162072009911706202, 5128252735042950570541661862704057778697777367682675179255508249069206116108008236364688726497066420198915103127328652153920791569475715644224564332100639], [2563221664374872663278726447352893822468787748826688543449083601814070735291152495522031395953021486479126489409553661909467374804495083097067023461101241, 6566088464708310995642409028807288393979344735404620168989682843309896029461182739839950463522656561353959979803920824844492121990544498716716047723977910, 130057529710426488213137583219999255587156240884036482222085445611551740946428211680329413666239014546023650006579524537602274302379152576119520068108319], [5342408465355821539357986311892676556199271023491659460379476187712977833146964566593532451072939601789180818278583745555483090452024642159007064165800081, 3283554726718737444389729631016035434015751338535189074295640854481651942378365746643274759572464743981861848971330295577364787640389158084889350283978821, 3140055548802978995474977115602107560914575889710138407298306721971016304575233705366565976404902888283840198356431969988949513149516351192261087493740890], [599541426740541398930281198217219002055776031533759543636607757629213787169680162194126045830416834733408242600490845122211014165748273997720985171688041, 5957207859384881463025007501710389658802332383558267293322714086358938193388741893071655615153092025747579772703124512208782459441100652478549738180467978, 4682713376946075123598629989240562117774633362251661889503646233262116515006093065833206615375846947185403405658122109052452004335578521197128755538142562], [7103657963548914558151473809474075771611185618134380111586031973749843445270500043215388123926986228575345423314499611151032605087785285456086954143332795, 2437090089471763281003268510083600543608846252680223991273908345135602309589620097292474114081336144065225051782014698516867570373062887759704073445145766, 7263633592969865940568162914112873033425552832716604041970494862239901164707781850676711734033552643405919601738169630448608427244505351343621156673841732], [6787260216003704037436828249042950501442135219256212863721237923906944473725953011789953225572229483386321885419169052842430604831287326826367535177852053, 7289837746969742837562254130441459418716174243333286884721893365447520299330685353689480042055570758502172720594554142917472501623012005474566631566544775, 6581191704328187480538895638259936434391238929209425408851189613318327811764420001620980504352179287185565444922372294504832272119209006602669933898480878], [750395498918226777040527843867196113458405311943647981774216787181612352604554317713785604945826407015377270019505130311300614336277162115563565360618478, 4840449299234867971000534596756931162830835855867819145058680308392558160966470220222109505723871889664721592993291696185055331584842480392441058196006436, 5412702039966146294395879633578487882240433694451709440397732707557193056889334787123501521744362953062885714266204930622216103885338311445206792741932999], [1276816869879639977990203528882856601012474784947810512487591115574428646605781380422735500626575579669016136844540271053533311757951144082015936557489087, 1239916973932615451066506751318691392204788751681844835551848034385300794677700028988929557778553964903346405673924363004228948262352704973820706023958891, 2285860412837188443208576330203052996086133758687332958176255791492234226477257282920036027518499672369420512593972418102867910390592209259341791773808425], [4234783580347301415219055168004953720021990043845525530978728641401141280688765768255841044951798583995682343024907380189589165570451045720056452326485618, 5718235690118251228617104726479064921991314663732805083156370432971341367382827271609557691898846816407222614032051075708178029254271041725207957347236569, 6011203979414507997009462186342176669941053585431071624148473597721460653407597205937696793979140839505480847287174278929294086631363969339351348575352856], [1558327918173916685276061896009146814462087603675562547749464338567789777526157067883836812063086030139306395351744800560094726977076742887829461268635558, 4514148881631515061858934147505049323883430087629553393687379588421262903144178261541888640294288831031133809383907481714613701220966378839463140096771142, 6852227333661582809040997504319324351902752602498116902003495662316181290311509340056889282031693078153608180707421739904104897716102066595433625160283868]]
p= 7591656713055743077369340861541583433090841738590989539280316533530045331013958613146671718809022799047779468311222607020894006899032327866283558110087799
g= 2221154642536617375933147254663757148609834736621720750750043572054496685087600339999953459509198087870095805651320901316659013390557077204194753685935362
R.=Zmod(p)[]                                                           
tg=x                                                                      
for i in range(10): 
     a,b,c=abc[i][0],abc[i][1],abc[i][2] 
     tg=c*x^2+b*tg+a
f=tg-g
f.roots()

从得到的两组解中,选取符合“d是长度40bit素数”的值,所以取d=793009095377
sage中运行结果如图:
DASCTF2022九月赛-Crypto-easySignin_第2张图片
求出了m+d,又求出了d,那么明文就呼之欲出了:

from Crypto.Util.number import *
md=130661655927230795642760431379039778633673372572819159728043876332994399613135476225358
d=793009095377
print(long_to_bytes(md-d))

运行Python脚本输出flag是CBCTF{cjx_H0pe_that_love_1s_forever}

你可能感兴趣的:(偶然遇到的一些CTF题,网络安全,python)