下载文件,打开是一个txt文件,解密工具base64解码,如图:
打开文件看到字符如下:
oknqdbqmoq{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz}
联想到上一题拿到的flag的格式,可以看出是比较规律的一串字符。
上一题flag的格式为cyberpeace{xx_xx_xx_xx},因此猜测本题{}前面的内容为cyberpeace。
题目名字Caesar就是恺撒密码,也就是把每个字母移动相同的位数变成另一个字母,观察比较cyberpeace和oknqdbqmoq也看得出,字母相同的位置变化后的字母也相同,于是数一下移动的位数。
oknqdbqmoq
↓
cyberpeace
c->o后移12位
y->k后移12位
因此要解密就将密文每个字母向前移12位,可以参照前面cyberpeace对应的字母:
{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz}
kag->you
tmhq->have
xqmdzqp->learned
omqemd->caesar
qzodkbfuaz->encryption
得到flag:
cyberpeace{you_have_learned_caesar_encryption}
看到标题名字,大概是摩斯密码,打开文件内容如下:
11 111 010 000 0 1010 111 100 0 00 000 000 111 00 10 1 0 010 0 000 1 00 10 110
摩斯密码在线解密在线摩斯密码翻译器
解密结果:
MORSECODEISSOINTERESTING
转换为小写flag:
cyberpeace{morsecodeissointeresting}
题目提示说留下了明文。
解压下载的文件,打开task.py,直接看到flag:
不懂,这和密码有啥关系
打开文件,代码如下:
from Crypto.Util.number import *
from secret import flag
import random
import hashlib
import os
key=os.urandom(8)
#os.urandom(n)函数用来获取一个指定长度的bytes对象
#返回一个长为n个bytes的string
#本代码中返回一个8个字节的字符串
def rand(rng):
return rng - random.randrange(rng)
#random.randrange([start,] stop [,step]),
#start -- 指定范围内的开始值,包含在范围内。如果 start 参数未传入参数,则采用默认值 0(零)。
#stop -- 指定范围内的结束值,不包含在范围内。
#step -- 指定递增基数。该参数是可选的,如果参数中没有传入宽度参数,则取默认值1
#也就是说,只有一个参数的话,就是stop值,本代码中就是在[0,rng)之间产生随机的整数值
m=[]
random.seed(int(hashlib.md5(key).hexdigest(), 16))
#设置随机种子后,是每次运行test.py文件的输出结果都一样,而不是每次调用随机函数生成的结果一样
#想要每次运行随机函数生成的结果都一样,可以在每个随机函数前都设置一模一样的随机种子
for i in range(len(flag)):
rand(256)
xor=flag[i]^rand(256)
# 把flag的每一个字符和rand出来的值做异或
m.append(xor)
print(m)
print(bytes_to_long(key)>>12)
# [140, 96, 112, 178, 38, 180, 158, 240, 179, 202, 251, 138, 188, 185, 23, 67, 163, 22, 150, 18, 143, 212, 93, 87, 209, 139, 92, 252, 55, 137, 6, 231, 105, 12, 65, 59, 223, 25, 179, 101, 19, 215]
# 2669175714787937
参考博客:
Python——os.urandom生成随机加密字符
Python random randrange()用法及代码示例
【python】random.seed()用法详解
Crypto中常用的数据类型互转方式
知道了输出结果,反过来尝试写解码的脚本:
# coding=gbk
# vscode里把编码改成了gbk,但是因为默认编码环境是utf-8,所以要在第一行加上coding=
from Crypto.Util.number import *
# from secret import flag
import random
import hashlib
key1 = 2669175714787937 << 12
# 由于低12位未知,所以需要低12位遍历每一个值循环爆破
m = [
140, 96, 112, 178, 38, 180, 158, 240, 179, 202, 251, 138, 188, 185, 23, 67,
163, 22, 150, 18, 143, 212, 93, 87, 209, 139, 92, 252, 55, 137, 6, 231,
105, 12, 65, 59, 223, 25, 179, 101, 19, 215
]
def rand(rng):
return rng - random.randrange(rng)
for k in range(1 << 12):
key = long_to_bytes(key1 + k)
random.seed(int(hashlib.md5(key).hexdigest(), 16))
flag = []
for i in range(len(m)):
rand(256)
xor = m[i] ^ rand(256)
flag.append(xor)
if all(ch < 256 for ch in flag):
flag = bytes(flag)
if (flag.startswith(b'flag')):
print("key=", bytes_to_long(key))
print(flag)
运行结果:
key= 10932943727771392887
b'flag{e319a58c-4dd6-4e6a-a3fb-f4b0d339faba}'
Non-UTF-8报错解决方法、append函数、bytes函数、bytes串参考博客如下:
Python出现报错:SyntaxError: Non-UTF-8 code starting with ‘\xa1‘ in file…
Python 列表 append()函数使用详解
python内置函数bytes()用法详解
Python bytes 字节串类型及用法
————待更新————————————————————