CTFshow月饼杯Crypto2_月自圆WP
加密脚本Baby(Don't)Cry.py
:
# -*- coding:utf-8 -*-
#Author: Lazzaro
from itertools import *
from random import *
from string import *
def encrypt(m, a, si):
c=""
for i in range(len(m)):
c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
return c
if __name__ == "__main__":
m = '****************************************************flag{*************}'
assert(len(m)==71)
a = randint(50,100)
salt = ''.join(sample(ascii_uppercase, 4))
si = cycle(salt.lower())
c=encrypt(m, a, si)
print(c)
#3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a
根据加密程序可以知道明文长度为71
位,加密后为142
位。
这里由于a不大,salt长度也不长,且明文m中存在flag,正好可以用这几位去爆破出a和salt。
flag在明文m中的位置是53,对应密文c中的位置是105。flag出现的位置正好对应salt的位置。
爆破a:
from random import *
from string import *
from itertools import *
def decrypt(m, a, si):
c=""
for i in range(len(m)):
c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
return c
if __name__ == "__main__":
for i in range(50,100):
for j in ascii_uppercase:
si = cycle(j.lower())
# if encrypt('f', i, si)=='1c':
# print('i =',i,'\tj =',j)
if decrypt('l', i, si)=='29':
print('i =',i,'\tj =',j)
满足encrypt('f', i, si)=='1c'
的结果:
i = 52 j = D
i = 57 j = F
i = 62 j = H
i = 67 j = J
i = 72 j = L
i = 77 j = N
i = 82 j = P
i = 87 j = R
i = 92 j = T
i = 97 j = V
满足encrypt('l', i, si)=='29'
的结果:
i = 54 j = A
i = 55 j = U
i = 61 j = M
i = 67 j = E
i = 68 j = Y
i = 74 j = Q
i = 80 j = I
i = 86 j = A
i = 87 j = U
i = 93 j = M
i = 99 j = E
相同的i只有67,说明随机数a=67
。
然后拿着a去继续爆salt的后两位:
if decrypt('a', 67, si)=='56':
print('j =',j)
if decrypt('g', 67, si)=='66':
print('j =',j)
最终得出salt='JESQ'
。
知道了随机出a和salt,这道题就出来了:
exp:
from random import *
from string import *
from itertools import *
def decrypt(m, a, si):
c=""
for i in range(len(m)):
c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
return c
if __name__ == "__main__":
a=67
salt = 'JESQ'
si = cycle(salt.lower())
c = '3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a'
q=len(c)//2
s=''
for i in range(q):
b=c[:2]
c=c[2:]
sm=next(si)
for k in range(1,126):
m=chr(k)
c1=hex(((ord(m)) * a + ord(sm)) % 128)[2:].zfill(2)
#print(m,c1,int(c1,base=16)==int(b,base=16))
if(int(c1,base=16)==int(b,base=16)):
s+=m
break
print(s)
得到:
now_is_7fad9fcb-d361-4964-821c-177c906b8d20_flag_is_flag{md5(now-salt)}
根据要求md5加密now-salt
即可得到flag。
now-salt:7fad9fcb-d361-4964-821c-177c906b8d20-JESQ
最终flag为:
flag{1efce62ee0a96e39149e2179db1dd04c}