浙江省省赛2022决赛复现

Re

ezAndroid

逆向密码,因为密文都是偶数所以可以直接逆,如果有奇数的话还得爆破

1
2
3
4
5
6
a=[404, 220, 436, 368, 220, 436, 412, 452, 432, 200, 412]
s=''
for i in range(len(a)):
s+=chr((a[i]>>2)^3)
print(s)
#f4n_4ndro1d

然后模拟器输入账号密码就可以得到flag

EzMath2

upx魔改

脱壳后发现一开始的一个函数修改了密文

1
2
3
4
5
a=[0x3A, 0x3A, 0x61, 0x07, 0x51, 0x4E, 0x43, 0x2B, 0x51, 0x29,
0x6A, 0x3E, 0x52, 0x3A, 0x2F, 0x79, 0x29, 0x69]
for i in range(len(a)):
a[i]=(a[i]*43)%127
print(a)

遇到花指令

nop ret之后删除两个函数再创建函数即可去除花指令

可以直接爆破或者逆

这题无法动态调试,只能静态分析了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
a=[81, 81, 107, 47, 54, 52, 87, 71, 54, 112, 113, 126, 97, 81, 116, 123, 112, 70]
s=''
for i in range(0,len(a),2):
a[i]=(a[i]+1)^7
a[i+1]=(a[i+1]*inverse(57,127)%127)&0x7f
s+=chr(a[i])
s += chr(a[i+1])
print(s)
# for i in range(len(a)):
# for j in range(32,127):
# k=j
# if i%2:
# k=57*k%127
# if a[i]==k:
# print(chr(j),end="")
# else:
# k=(k^7)-1
# if a[i] == k:
# print(chr(j), end="")
DASCTF{U_kn0w_M0du1e_rEv~}

Crypto

math

不知道factorial的含义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from Crypto.Util.number import *
import math
import m
flag='DASCTF{'+m+'}'
str = 'abcdefghijklmnopqrstuvwxyz0123456789+='
n = getPrime(1024)
print(n)
#176778040837484895481963794918312894811914463587783883976856801676290821243853364789418908640505211936881707629753845875997805883248035576046706978993073043757445726165605877196383212378074705385178610178824713153854530726380795438083708575716562524587045312909657881223522830729052758566504582290081411626333
key=math.factorial(n-1)%n
c=''
for i in m:
k=(str.index(i)*key+7)%37
c+=str[k]

print(c)
#u66hp7nuh01puoaip10pi6o0vzavnu11

但是可以本地模拟看函数解释,发现是求阶层,试了几个素数发现key等于n-1

那么直接正向爆破即可

1
2
3
4
5
6
7
8
9
10
11
12
13
str = 'abcdefghijklmnopqrstuvwxyz0123456789+='
n=176778040837484895481963794918312894811914463587783883976856801676290821243853364789418908640505211936881707629753845875997805883248035576046706978993073043757445726165605877196383212378074705385178610178824713153854530726380795438083708575716562524587045312909657881223522830729052758566504582290081411626333
key=n-1
c='u66hp7nuh01puoaip10pi6o0vzavnu11'
for i in range(32):
for j in str:
k=j
k=(str.index(k)*key+7)%37
if c[i]==str[k]:
print(j,end="")
break

#799a03b7a82076f5028059681df1b72

rssssa5-1

知道p的低560位,但是最多未知位是454位,也就是至少要爆破10位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Util.number import *
from secret import flag
p = getPrime(1024)
q = getPrime(1024)
n = p*q
m = bytes_to_long(flag)
e = 65537
c = pow(m, e, n)

print("n =", n)
print("c =", c)
print("p =", p&((1<<560) - 1))

'''
n = 21595945409392994055049935446570173194131443801801845658035469673666023560594683551197545038999238700810747167248724184844583697034436158042499504967916978621608536213230969406811902366916932032050583747070735750876593573387957847683066895725722366706359818941065483471589153682177234707645138490589285500875222568286916243861325846262164331536570517513524474322519145470883352586121892275861245291051589531534179640139953079522307426687782419075644619898733819937782418589025945603603989100805716550707637938272890461563518245458692411433603442554397633470070254229240718705126327921819662662201896576503865953330533
c = 1500765718465847687738186396037558689777598727005427859690647229619648539776087318379834790898189767401195002186003548094137654979353798325221367220839665289140547664641612525534203652911807047718681392766077895625388064095459224402032253429115181543725938853591119977152518616563668740574496233135226296439754690903570240135657268737729815911404733486976376064060345507410815912670147466261149162470191619474107592103882894806322239740349433710606063058160148571050855845964674224651003832579701204330216602742005466066589981707592861990283864753628591214636813639371477417319679603330973431803849304579330791040664
p = 1426723861968216959675536598409491243380171101180592446441649834738166786277745723654950385796320682900434611832789544257790278878742420696344225394624591657752431494779
'''

这里爆破了15位,当然12位或者其他可能也行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Util.number import *
import tqdm
n = 21595945409392994055049935446570173194131443801801845658035469673666023560594683551197545038999238700810747167248724184844583697034436158042499504967916978621608536213230969406811902366916932032050583747070735750876593573387957847683066895725722366706359818941065483471589153682177234707645138490589285500875222568286916243861325846262164331536570517513524474322519145470883352586121892275861245291051589531534179640139953079522307426687782419075644619898733819937782418589025945603603989100805716550707637938272890461563518245458692411433603442554397633470070254229240718705126327921819662662201896576503865953330533
c = 1500765718465847687738186396037558689777598727005427859690647229619648539776087318379834790898189767401195002186003548094137654979353798325221367220839665289140547664641612525534203652911807047718681392766077895625388064095459224402032253429115181543725938853591119977152518616563668740574496233135226296439754690903570240135657268737729815911404733486976376064060345507410815912670147466261149162470191619474107592103882894806322239740349433710606063058160148571050855845964674224651003832579701204330216602742005466066589981707592861990283864753628591214636813639371477417319679603330973431803849304579330791040664
PR.< x > = Zmod(n)[]
for i in tqdm.tqdm(range(2**15)):
i = Integer(i)
p = 1426723861968216959675536598409491243380171101180592446441649834738166786277745723654950385796320682900434611832789544257790278878742420696344225394624591657752431494779
f = p + i*2**(560) + x*2**(560+i.nbits())
res = f.monic().small_roots(X=2^(1024-560-i.nbits()), beta=0.4)
if res:
print(res)
p = p + i*2**(560) + int(res[0])*2**(560+i.nbits())
q = n // p
if p * q==n:
d = inverse(65537,(p-1)*(q-1))
print(long_to_bytes(int(pow(c,d,n))))
# b'DASCTF{ce73935b2e83a78aa5079a9e59ae4980}'

浙江省省赛2022决赛复现
https://j1ya-22.github.io/2024/10/25/浙江省省赛2022决赛复现/
作者
j1ya
发布于
2024年10月25日
许可协议