第四屆 美團MTCTF Write-up (Crypto)
前言
比賽的時候做了兩個Crypto,一個Misc,隊友們做了兩個Pwn,一個RE。
總共241個得分隊伍,最終排第36名,離進決賽還是有挺大距離的。
這里,把我做的兩道Crypto題總結一下。
Symbol
考察的是LaTeX
的字符
一堆不認識的字符,憑着對希臘字母的了解勉強得知其模式為根據其發音得到對應明文
找了很多東西發現這些都是LaTeX
的字符於是很快得到flag{fun_latex_math}
但是md5
之后提交錯誤,注意到字母里有大小寫,於是把L、T、X、M
大寫 -->flag{fun_LaTeX_Math}
md5
后提交正確,多一嘴,md5
默認32位小寫(不用像我一樣把4種都試一遍
hamburgerRSA
題目:
from Crypto.Util.number import *
flag = open('flag.txt').read()
nbit = 64
while True:
p, q = getPrime(nbit), getPrime(nbit)
PP = int(str(p) + str(p) + str(q) + str(q))
QQ = int(str(q) + str(q) + str(p) + str(p))
if isPrime(PP) and isPrime(QQ):
break
n = PP * QQ
m = bytes_to_long(flag.encode())
c = pow(m, 65537, n)
print('n =', n)
print('c =', c)
p,q
中一個為19位一個為20位(因為如果都是20或19位的話PP和QQ肯定不是質數)
顯然N
的前19位就是p*q
的前19位,N
的后19位就是p*q
的后19位
這樣,p*q
的位數是39或40位,只有一位不知道,只要爆破這一位再用sage
的factor
分解就可以了
以下腳本在sage
中運行:
N=177269125756508652546242326065138402971542751112423326033880862868822164234452280738170245589798474033047460920552550018968571267978283756742722231922451193
low=str(N)[-19:]
high=str(N)[:19]
for i in ['']+[str(i) for i in range(10)]:
n=int(high+i+low)
f=factor(n)
if len(f)==2:
print(f)
得到p,q
為 9788542938580474429 , 18109858317913867117
from Crypto.Util.number import*
PP=978854293858047442997885429385804744291810985831791386711718109858317913867117
QQ=181098583179138671171810985831791386711797885429385804744299788542938580474429
phi=(PP-1)*(QQ-1)
n=PP*QQ
c=47718022601324543399078395957095083753201631332808949406927091589044837556469300807728484035581447960954603540348152501053100067139486887367207461593404096
d=inverse(65537,phi)
m=pow(c,d,n)
print(long_to_bytes(m))
得到flag