CTF攻防世界小白刷题自学笔记16
1.Broadcast,难度:1,方向:Crypto(密码学)
题目来源:2019_Redhat
题目描述:粗心的Alice在制作密码的时候,把明文留下来,聪明的你能快速找出来吗?
给一下题目链接:攻防世界Crypto方向新手模式第4题。
打开下载的附件,发现有一大堆文件,吓我一跳,发现了唯一认识的Python文件。
打开了直接看到了flag,我都有的不相信这么简单,输入后结果还真是,所以说千万不要被随便吓到。
2.hidden key,难度:1,方向:Crypto
题目来源:江苏工匠杯
题目描述:你可以找到合适的key吗?
给一下题目链接:攻防世界Crypto方向新手模式第5题。
打开一看是一个Python文件。
代码解析
-
导入模块:
Crypto.Util.number
:用于数值相关的工具。random
:用于生成随机数。hashlib
:用于计算哈希值。os
:用于生成随机字节。
-
生成密钥:
- 使用
os.urandom(8)
生成了一个8字节的随机密钥。
- 使用
-
随机种子初始化:
- 随机数生成器通过密钥的 MD5 哈希值进行初始化,确保对于相同的密钥,生成的随机数是相同的。
-
标志加密:
- 标志被逐字节加密。
- 对于标志的每个字节,调用
rand(256)
生成一个0到255之间的随机值,然后将这个值与标志字节进行异或(XOR)运算。
-
输出:
- 打印加密后的标志(以整数列表的形式)和一个根据密钥生成的整数。
反向操作
为了找回原始的标志,我们需要:
- 使用提供的密钥重新生成用于加密的随机数。
- 将这些随机数与加密后的字节进行异或运算,得到原始的标志。
解密步骤
-
重新生成随机数:
使用相同的密钥作为种子,重新生成与加密过程中相同的随机数序列。 -
异或解密:
使用得到的随机数与加密值进行异或运算,恢复原始的标志。
几个关键知识点:
1. 异或操作的含义
异或 (XOR) 是一种在数字电路和计算机科学中常用的逻辑运算。其基本规则是:
- 当两个输入相同(0与0或1与1)时,输出为0。
- 当两个输入不同(0与1或1与0)时,输出为1。
用一个简单的真值表表示:
表格
A | B | A XOR B |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
在代码中,行 f = c[i] ^ rand(256)
对于 c[i]
和 rand(256)
进行异或,这说明 f
是从原始密文字节 c[i]
和随机生成的字节组合而来的。这里生成的 rand(256)
是一个随机数,它应当模拟在加密过程中使用的随机数。
恢复的机制
假设我们知道加密过程如下:
-
原始字节
m[i]
与一个随机字节r[i]
异或后得到的密文c[i]
:
c[i]=m[i]⊕r[i]c[i]=m[i]⊕r[i]
在解密时,如果我们知道 r[i]
和 c[i]
,我们可以利用异或的特性来恢复原始字节 m[i]
:
m[i]=c[i]⊕r[i]m[i]=c[i]⊕r[i]
因为异或操作具有以下性质:
- x⊕x=0x⊕x=0 (相同的数异或结果为0)
- x⊕0=xx⊕0=x (与0异或返回自身)
因此,只要我们能够获得正确的 r[i]
,我们就可以恢复出原始数据。
2.random.seed(int(hashlib.md5(key).hexdigest(), 16)) 这句干什么的?为什么感觉后面没有用到?
这段代码 random.seed(int(hashlib.md5(key).hexdigest(), 16))
用于初始化随机数生成器的种子,确保在下面的代码中生成的随机数是可预测的。让我们详细解析一下它的功能和用途:
1. 初始化随机数生成器的种子
-
hashlib.md5(key).hexdigest()
:- 这部分代码计算给定
key
的 MD5 哈希值,并以十六进制字符串形式返回。MD5 哈希函数是确定性的,意味着相同的输入总是产生相同的输出。
- 这部分代码计算给定
-
int(..., 16)
:- 将得到的十六进制字符串转换为一个整数。这一转换是为了使这个哈希值可以作为随机数生成器的种子。
-
random.seed(...)
:- 用这个整数来初始化随机数生成器。这意味着接下来的随机数序列是基于这个种子的,而同样的种子会生成相同的随机数序列。
2. 为什么这句代码重要?
虽然在表面上看,它似乎没有被直接用到,但实际上,这一步是在设置随机数生成器的初始状态,以影响后续所有的 random
函数调用的结果。例如,当你调用 random.randrange(256)
或 rand(256)
(其中 rand
使用了 random.randrange
),生成的数是基于设定的种子的。
- 可重复性:
- 由于种子是基于
key
的哈希值,使用相同的key
每次运行程序都会生成相同的随机数序列,这在某些情况下可以帮助进行调试或复现实验。
- 由于种子是基于
即 相同的秘钥作为种子生成相同的随机数(种子相同,生成的随机数相同)
3.使用vscode等工具打开Python文件时,出现导入库问题。
先安装库在终端下输入命令pip install pycryptodome,
如果还是不行,多半是编译器版本问题,请看下面文章,大佬很厉害,说的清晰透彻。
使用vscode导入库失败解决方法_vscode中编写python 导入manim时报错-CSDN博客
下面是解码代码,不是我写的,是这位大佬写的,放在这里纯粹方便复制查看。
from Crypto.Util.number import *
import random
import hashlib
import os
okey=2669175714787937<<12
c=[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 kk in range(2**12):
key=long_to_bytes(okey+kk)
flag = []
random.seed(int(hashlib.md5(key).hexdigest(), 16))
for i in range(len(c)):
rand(256)
f=c[i]^rand(256)
flag.append(f)
if all(c < 256 for c in flag):
flag=bytes(flag)
if(flag.startswith(b'flag')):
print(flag)
运行完代码直接出现flag了。
总结:Python真的很重要,我后悔之前没有学,根本问题是之前根本不会导入库,很多代码根本运行不了,查了很多解决方法都没有用,非常劝退人,环境不能配置出错,否则出现各种运行不起来,希望以后可以自己总结一个软件环境新人痛苦安装合集。