i春秋CTF实战:破解Crypto ezxor谜题,从异或迷阵到Flag重现

i春秋CTF实战:破解Crypto ezxor谜题,从异或迷阵到Flag重现

在CTF(Capture The Flag)竞赛中,密码学(Crypto)题目常常是选手们既爱又恨的挑战。它既考验逻辑思维,也检验对加密算法底层原理的理解。今天,我们将深入剖析一道典型的Crypto题目------"ezxor",结合i春秋平台常见的出题风格,带你一步步揭开这道看似复杂、实则逻辑清晰的异或加密谜题。


一、题目背景:什么是"ezxor"?

"ezxor"这个名字颇具迷惑性------"ez"暗示"easy",而"xor"则直指核心操作:异或(XOR)。然而,正如许多CTF题目一样,表面的"简单"背后往往隐藏着层层嵌套的加密逻辑。

题目提供了一段Python加密脚本和一段PHP解密脚本,目标是还原出原始的flag。加密过程涉及多个步骤:Base64编码、SM3哈希、随机数生成、位移操作、异或累积等。乍一看眼花缭乱,但只要我们抓住"异或"这一核心线索,就能抽丝剥茧,找到突破口。


二、加密流程深度解析

我们先来梳理Python脚本中的加密逻辑:

1. Flag预处理:Base64编码

python 复制代码
flag = base64.b64encode(flag[5:-1].encode()).decode()
fg = [flag[i:i+4] for i in range(0, len(flag), 4)]
  • 原始flag格式为 flag{...},去除前后5个字符后,对中间内容进行Base64编码。
  • 编码后的字符串被每4个字符分割成一个片段,便于后续逐段加密。

考点1:数据编码与分块处理

CTF中常见将flag进行Base64、Hex、URL等编码后再加密,考察选手对编码格式的识别与处理能力。


2. 密钥生成:SM3哈希

python 复制代码
def generate_key():
    random_string = ''.join(random.choice(letters) for i in range(4))
    hash_key = sm3_hash(random_string.encode('utf-8')).hex()
    return random_string, hash_key
  • 生成一个4位小写字母组成的随机字符串作为密钥。
  • 使用国密算法SM3计算其哈希值(但实际加密中只用了原始字符串,哈希值未使用)。

考点2:国密算法SM3的应用

国内CTF平台如i春秋常引入国密算法,考察选手对SM2/SM3/SM4的熟悉程度。本题虽未直接使用哈希值,但其存在增加了干扰。


3. 加密核心:异或累积 + 位移混淆

python 复制代码
for i, j in enumerate(fg):
    k_box = random_num(i, 10000000, 100000000)
    for z,t in enumerate(k_box):
        shifted_t = t << z
        k_box[z] = shifted_t
    a = (reduce(xor, k_box)) >> 3 ^ s2n(j) ^ s2n(key[0]) >> 5
    a_boxs.append(a)

加密公式可简化为:

复制代码
ciphertext = (XOR(k_box << shifts) >> 3) ^ s2n(plaintext) ^ (s2n(key) >> 5)

其中:

  • k_box 是随机生成的整数列表。
  • 每个元素根据索引左移 z 位,形成位移混淆。
  • 所有元素进行异或累积(reduce(xor, ...))。
  • 最终结果右移3位,再与明文数字值和密钥右移5位后的值异或。

考点3:异或的可逆性与累积操作

异或操作满足交换律、结合律,且 a ^ a = 0,因此具备可逆性。这是解密的关键!

尽管加入了位移和随机数,但只要知道 k_boxkey,就能逆向计算出原始明文。


三、解密思路:逆向推导,逐段还原

PHP脚本已经给出了完整的解密逻辑,我们可以总结出解密步骤:

1. 已知条件

  • 密钥 key = 'vyxj'(由题目或环境给出)
  • k_boxsa_boxs 存储在 random_numbers.txt

2. 逆向公式

由加密公式:

复制代码
a = (xor_result >> 3) ^ s2n(j) ^ (s2n(key) >> 5)

可得:

复制代码
s2n(j) = a ^ (xor_result >> 3) ^ (s2n(key) >> 5)

3. 解密流程

  1. 读取 k_boxsa_boxs
  2. 对每个 k_box
    • 还原位移(但代码中位移已应用在 k_box 中,直接使用即可)
    • 计算 xor_result = k_box[0] ^ k_box[1] ^ ... ^ k_box[n-1]
  3. 计算 s2n(key) >> 5
  4. 代入公式,得到 s2n(j)
  5. 使用 n2s() 将数值转为字符串
  6. 所有片段拼接后进行 base64_decode
  7. 加上 flag{} 格式,得到最终flag

四、CTF考点总结

考点 说明 难度
Base64编码与解码 对flag内容进行编码后再加密,增加识别难度 ★★☆
异或(XOR)加密原理 核心加密操作,考察可逆性理解 ★★★
位移操作混淆 左移/右移增加分析复杂度 ★★☆
s2n / n2s 数值转换 字符串与大整数之间的转换,常见于Crypto题 ★★☆
SM3哈希算法 国密算法引入,提升题目专业性 ★★☆
随机数生成与固定种子 random_num 使用 sample,若无种子则需爆破 ★★★(若无密钥)
多层嵌套加密 多种操作组合,考验逻辑梳理能力 ★★★★

五、实战建议:如何应对类似题目?

  1. 识别加密模式 :看到 xorreduce(xor)^ 等符号,立即想到"异或可逆"。
  2. 关注数据分块[flag[i:i+4] for ...] 是典型分组加密,需逐段处理。
  3. 利用已知密钥 :本题密钥已知(vyxj),极大降低难度;若未知,需考虑爆破4位小写字母(26^4 ≈ 45万种)。
  4. 善用脚本自动化 :编写Python脚本读取 random_numbers.txt,自动解密。
  5. 注意数据类型转换s2nn2s 是关键,避免数值溢出或编码错误。

六、结语:从"ezxor"看CTF Crypto设计哲学

"ezxor"虽名为"ez",实则通过多层混淆 + 标准算法组合,构建了一个看似复杂的加密系统。它的巧妙之处在于:

  • 不依赖高强度算法(如RSA、AES),而是用基础操作堆叠出安全性;
  • 考察选手对异或性质的深刻理解;
  • 结合国密SM3,体现本土化出题趋势。

在i春秋等平台的CTF比赛中,这类题目屡见不鲜。掌握其核心逻辑,不仅能解出flag,更能提升密码学实战能力。

Flag不是终点,而是理解加密世界的起点。


附:快速解密脚本(Python版)

python 复制代码
from libnum import n2s
import base64

# 假设从文件读取
k_boxs = [...]  # 从random_numbers.txt解析
a_boxs = [...]  # 同上
key = 'vyxj'

fragments = []
for i in range(len(a_boxs)):
    xor_result = 0
    for x in k_boxs[i]:
        xor_result ^= x
    plain_num = a_boxs[i] ^ (xor_result >> 3) ^ (int.from_bytes(key.encode(), 'big') >> 5)
    fragments.append(n2s(plain_num))

base64_flag = ''.join(fragments)
real_flag = 'flag{' + base64.b64decode(base64_flag).decode() + '}'
print(real_flag)

i春秋CTF提示:多刷题、多总结、多复盘,每一个"ez"背后,都是通往高手之路的阶梯。

相关推荐
诗人不说梦^3 天前
[NCTF2019]True XML cookbook
web·ctf
诗人不说梦^5 天前
[RCTF2015]EasySQL
web·ctf
Coder_Chang8 天前
hex文件结构速查
ctf
_BlackBeauty15 天前
ctfshow_萌新web9-web15-----rce
ctf·绕过·rce·flag
诗人不说梦^19 天前
[极客大挑战 2019]RCE ME
web·ctf
777sea19 天前
NSS-DAY17 2025SWPU-NSSCTF
网络安全·ctf
print_Hyon24 天前
【CTF-WEB-反序列化】利用__toString魔术方法读取flag.php
ctf
诗人不说梦^1 个月前
[极客大挑战 2019]FinalSQL
web·ctf
Z3r4y1 个月前
【Web】京麒CTF 2025 决赛 wp
web·ctf·wp·京麒ctf2025