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}

参考链接

DASCTF密码第一题

posted @ 2021-10-19 18:10  404p3rs0n  阅读(129)  评论(0编辑  收藏  举报