2024年第九届“楚慧杯”湖北省网络与数据安全实践能力竞赛-RE
字数 806 2025-08-22 12:22:42
"楚慧杯"湖北省网络与数据安全竞赛逆向工程题目解析
题目1:go_bytes
加密逻辑:
- 使用初始值
tmp = 0xDEAD和线性同余算法生成密钥流:tmp = (291 * tmp + 1110) & 0xFFFF - 加密数据为8字节一组的数组,每组包含两个小端序存储的4字节数值(实际仅低2字节有效)
- 解密步骤:
- 对每组数据,将两个字节组合成16位数值(小端序)
- 与密钥流异或得到中间值
- 当前字符的高4位来自前一个字符的低4位(初始为0x40)
解密脚本:
enc = [0xB9, 0x22, 0xF8, 0xC9, ..., 0x79, 0xEB] # 完整数组见原题
tmp = 0xDEAD
flag = []
prev_nibble = 0x40
for i in range(0, len(enc), 8):
tmp = (291 * tmp + 1110) & 0xFFFF
xor_val = (enc[i+1] << 8) | enc[i]
ans = xor_val ^ tmp
flag.append(prev_nibble ^ (ans >> 4))
prev_nibble = (ans & 0xF) << 4
print(bytes(flag))
题目2:bouquet
二叉树遍历:
- 给定中序和后序遍历结果(实际解题时仅需中序)
- 已知flag格式以"DASCTF{"开头
- 通过中序遍历重建二叉树后层次遍历即可得flag
解题技巧:
- 利用已知前缀定位节点位置
- 手工绘制二叉树结构可快速推导完整flag
题目3:zistel
加密算法分析:
- 密钥初始化:使用固定字符串"love"生成12字节key
- 加密流程:
- 将输入分成8字节块(两个4字节DWORD)
- 进行20轮Feistel结构加密
- 每轮使用key的4字节(循环选取)作为轮密钥
核心函数:
def encrypt(key, next):
v10 = key ^ next
arr = [(v10 >> (8*i)) & 0xFF for i in range(4)]
# 基于key的置换操作(box表为i%4)
for i in range(4):
swap_idx = key_byte[i] % 4
arr[i], arr[swap_idx] = arr[swap_idx], arr[i]
return (arr[0] | (arr[1]<<8) | (arr[2]<<16) | (arr[3]<<24)) ^ key
解密脚本:
def decrypt_block(prev, next, round_keys):
for key in reversed(round_keys):
tmp = prev
prev = next ^ encrypt(key, tmp)
next = tmp
return prev, next
完整解题流程
-
go_bytes:
- 逆向处理字节序
- 注意4位nibble的传递关系
-
bouquet:
- 中序:左根右
- 后序:左右根
- 通过前缀确定根节点位置
-
zistel:
- 动态提取轮密钥
- 逆序执行加密步骤
- 注意swap操作的对称性
关键知识点
- 流密码的逆向计算
- 二叉树遍历的重建技巧
- Feistel结构的对称特性
- 小端序数据处理
- 动态调试提取加密参数
注意事项
- go_bytes的初始nibble值(0x40)需要硬编码
- bouquet可仅用中序遍历快速求解
- zistel的box表实际是简单的模4运算
- 所有加密操作都需要注意字节序处理
附:完整EXP代码建议参考原文,其中包含详细的字节操作和循环逻辑实现。