当前位置: 首页 > article >正文

CTF攻防世界小白刷题自学笔记16

1.Broadcast,难度:1,方向:Crypto(密码学)

题目来源:2019_Redhat

题目描述:粗心的Alice在制作密码的时候,把明文留下来,聪明的你能快速找出来吗?

给一下题目链接:攻防世界Crypto方向新手模式第4题。

打开下载的附件,发现有一大堆文件,吓我一跳,发现了唯一认识的Python文件。

打开了直接看到了flag,我都有的不相信这么简单,输入后结果还真是,所以说千万不要被随便吓到。

2.hidden key,难度:1,方向:Crypto

题目来源:江苏工匠杯

题目描述:你可以找到合适的key吗?

给一下题目链接:攻防世界Crypto方向新手模式第5题。

打开一看是一个Python文件。

代码解析

  1. 导入模块

    • Crypto.Util.number:用于数值相关的工具。
    • random:用于生成随机数。
    • hashlib:用于计算哈希值。
    • os:用于生成随机字节。
  2. 生成密钥

    • 使用 os.urandom(8) 生成了一个8字节的随机密钥。
  3. 随机种子初始化

    • 随机数生成器通过密钥的 MD5 哈希值进行初始化,确保对于相同的密钥,生成的随机数是相同的。
  4. 标志加密

    • 标志被逐字节加密。
    • 对于标志的每个字节,调用 rand(256) 生成一个0到255之间的随机值,然后将这个值与标志字节进行异或(XOR)运算。
  5. 输出

    • 打印加密后的标志(以整数列表的形式)和一个根据密钥生成的整数。

反向操作

为了找回原始的标志,我们需要:

  1. 使用提供的密钥重新生成用于加密的随机数。
  2. 将这些随机数与加密后的字节进行异或运算,得到原始的标志。

解密步骤

  1. 重新生成随机数
    使用相同的密钥作为种子,重新生成与加密过程中相同的随机数序列。

  2. 异或解密
    使用得到的随机数与加密值进行异或运算,恢复原始的标志。

几个关键知识点:

1. 异或操作的含义

异或 (XOR) 是一种在数字电路和计算机科学中常用的逻辑运算。其基本规则是:

  • 当两个输入相同(0与0或1与1)时,输出为0。
  • 当两个输入不同(0与1或1与0)时,输出为1。

用一个简单的真值表表示:

表格

ABA XOR B
000
011
101
110

在代码中,行 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真的很重要,我后悔之前没有学,根本问题是之前根本不会导入库,很多代码根本运行不了,查了很多解决方法都没有用,非常劝退人,环境不能配置出错,否则出现各种运行不起来,希望以后可以自己总结一个软件环境新人痛苦安装合集。


http://www.kler.cn/a/402454.html

相关文章:

  • Selenium 包介绍
  • Spring Boot 3.0废弃了JavaEE,改用了Jakarta EE
  • 永磁同步电机末端振动抑制(输入整形)
  • Linux系统Docker部署开源在线协作笔记Trilium Notes与远程访问详细教程
  • Docker-Compose 快速部署安装 Nginx 或其他应用
  • svn 崩溃、 cleanup失败 怎么办
  • windows和git不区分文件名大小写问题
  • 字符串加法
  • 用jquery做一个websocket客户端
  • 一.安装版本为19c的Oracle数据库管理系统(Oracle系列)
  • Huggingface load_dataset加载本地数据集
  • 01 P1048 [NOIP2005 普及组] 采药
  • 02 P1734 最大约数和
  • 梧桐数据库加密算法支持与实践应用
  • 印刷物料学习Ⅰ~
  • 【Vue3组件通信方法】
  • elment-ui的折叠tree表单实现纯前端搜索,展开收起功能
  • 【C++习题】5.验证一个字符串是否是回文
  • 详解模版类pair
  • go channel中的 close注意事项 range取数据
  • MySQL数据库4——数据库设计
  • 基于YOLOv8深度学习的医学影像阿尔兹海默症检测诊断系统研究与实现(PyQt5界面+数据集+训练代码)
  • 【设计模式】行为型模式(四):备忘录模式、中介者模式
  • javaweb学习——Day2
  • 原生鸿蒙中实现RN热加载的详细步骤
  • gin源码阅读(2)请求体中的JSON参数是如何解析的?