HITCTF2022 revcalc
import string
p = 2**607 - 1
def s(a, b):
return (a + b) % p
def u(a, b):
return (a - b) % p
def m(a, b):
return a * b % p
def scan(s):
while s:
if s[0] in string.ascii_letters:
yield globals()[s[0]]
s = s[1:]
elif s[0] == '[':
s = s[1:]
num = s[:s.index(']')]
yield int(num)
s = s[len(num) + 1:]
else:
raise AssertionError
def calc(s):
stack = []
for token in scan(s):
if type(token) == int:
stack.append(token)
else:
b, a = stack.pop(), stack.pop()
stack.append(token(a, b))
assert len(stack) == 1
return stack[0]
assert calc('[114514][1919810]s') == 2034324
assert calc('[114514][1919810]u') == 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219029922831
assert calc('[114514][1919810]m') == 219845122340
assert calc('[456][789][123]um') == 303696
from secret import flag
flag = int(flag.encode().hex(), base=16)
assert flag < p
cmd = open('cmd.txt', encoding='utf8').read()
cmd = cmd.replace('#', str(flag))
assert calc(cmd) == 211628186767393818556251909887187904577210135303836860239435739472106633529410929587038047765313010325750338075891823682635502490521440215978665151485743439682336190814184610992830040
定义了p元域下加减乘三种运算,遇到字符进行弹栈操作,flag藏在中间某个数据中,栈之间有相互嵌套的情况,以#分割上下两端数据,分别进行题目定义中的运算,将数据化简到十二组。然后手动模拟一下弹栈过程进行m s u三种运算的逆运算。
exp:
p = 2**607 - 1
def s(a, b):
return (a + b) % p
def u(a, b):
return (a - b) % p
def m(a, b):
return a * b % p
list=[]
def rev_calc(ss):
while ss:
if ss[0] in string.ascii_letters:
list.append(ss[0])
ss=ss[1:]
elif ss[0]=='[':
ss=ss[1:]
num=ss[:ss.index(']')]
list.append(int(num))
ss=ss[len(num)+1:]
else:
print("error")
exit(0)
i=0
while True:
if type(list[i])==int and type(list[i+1])==int and type(list[i+2])==str:
if list[i+2]=='s':
list[i]=s(list[i],list[i+1])
elif list[i+2]=='u':
list[i]=u(list[i],list[i+1])
elif list[i+2]=='m':
list[i]=m(list[i],list[i+1])
del list[i+1]
del list[i+1]
i=-1
i+=1
if i>len(list)-3:
print(list)
break
cmd = open('cmd1.txt', encoding='utf8').read() #前后两端数据
#cmd = open('cmd2.txt', encoding='utf8').read()
rev_calc(cmd)
from Crypto.Util.number import *
import gmpy2
cur=[0,
411462633351188704608772808736605191389923045827641716511469308371854121046362931301201375260845451848982856577009623299816324457739774142518892624317933419004496564018161840092441609,
405277799051970673662801377723672963663731597810359617329765419659576945597240297480269578668417239423727580929070705786881955931110402398335890389099929008486871336532303266008184849,
266786049503793180671593180171285607267937291386517024152767948485542129161609474025939244637171224835933234460786246192462321233844724721442838436104220216301662441280032397322012869,
329413142624682830072062312344664670657676804598199974252482170738455671758477066245274544233089658385383771602659521107081460343229409192986193619974433238593388986719171190288572226,
142121702801478829020260933003861049247883466530930799943577455779988122604459669110334205260923754356449343846208954099483456230863726350624778551913564131383628808003460154339600404,
183071373516520549207577402797386102692277431976907349274136009719534503668840785924520834697959249645197750171829448025189506854326750416465015622082002300707311266953797519604299392,
84814702442206743141315418314363700843763684274888674447614037562848731974003165144242888622700246417328307742191053416029770031887073881821630737367508536343638035495945224940047233,
81400841347738205877353746324299277291277356563154583584412416913743196467840261318987244863470045052929898762129171746639696678721661976384989764957120352119094038687040657495882525,
393926316432640484766273060620865379785410111973395923709856173813361374147800349857401893990151884942524826629432805076866870155732114631381903699794058108179098102490606577881709383,
165839131146163706086115367996555974012081654422136256245648685955916878221421477398411421659597644170978751681140704059146026898331248207774348535156605590710456443740029571361676159,
509747518370752815356459801084195729310089672054058702183281061987169033803508549887738101604685367942973008687501702092204264485750605361311969988578288525486444957877546554793693797,
357912307834259213653128634794940914596507256175506043013473144575889601751685024934341011218038398747178612125892760523871786468537993455666648592264307733564175853226677357748565113
]
p = 2**607 - 1
ans=211628186767393818556251909887187904577210135303836860239435739472106633529410929587038047765313010325750338075891823682635502490521440215978665151485743439682336190814184610992830040
ans=(ans-cur[12])%p
ans=(ans*gmpy2.invert(cur[1],p))%p
ans=(ans-cur[2])%p
ans=(ans*gmpy2.invert(cur[3],p))%p
ans=(ans-cur[4])%p
ans=(ans*gmpy2.invert(cur[11],p))%p
ans=(ans+cur[10])%p
ans=(ans*gmpy2.invert(cur[5],p))%p
ans=(ans*gmpy2.invert(cur[6],p))%p
ans=(cur[7]-ans)%p
ans=(ans*gmpy2.invert(cur[9],p))%p
ans=(ans-cur[8])%p
print(hex(ans))
print(long_to_bytes(ans))
标签:cmd,cur,ss,2023,list,趣题,ans,密码学,def
From: https://www.cnblogs.com/App1eTree/p/17069496.html