2024年第九届“楚慧杯”湖北省网络与数据安全实践能力竞赛-RE
字数 806 2025-08-22 12:22:42

"楚慧杯"湖北省网络与数据安全竞赛逆向工程题目解析

题目1:go_bytes

加密逻辑

  1. 使用初始值 tmp = 0xDEAD 和线性同余算法生成密钥流:tmp = (291 * tmp + 1110) & 0xFFFF
  2. 加密数据为8字节一组的数组,每组包含两个小端序存储的4字节数值(实际仅低2字节有效)
  3. 解密步骤:
    • 对每组数据,将两个字节组合成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

二叉树遍历

  1. 给定中序和后序遍历结果(实际解题时仅需中序)
  2. 已知flag格式以"DASCTF{"开头
  3. 通过中序遍历重建二叉树后层次遍历即可得flag

解题技巧

  • 利用已知前缀定位节点位置
  • 手工绘制二叉树结构可快速推导完整flag

题目3:zistel

加密算法分析

  1. 密钥初始化:使用固定字符串"love"生成12字节key
  2. 加密流程:
    • 将输入分成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

完整解题流程

  1. go_bytes

    • 逆向处理字节序
    • 注意4位nibble的传递关系
  2. bouquet

    • 中序:左根右
    • 后序:左右根
    • 通过前缀确定根节点位置
  3. zistel

    • 动态提取轮密钥
    • 逆序执行加密步骤
    • 注意swap操作的对称性

关键知识点

  1. 流密码的逆向计算
  2. 二叉树遍历的重建技巧
  3. Feistel结构的对称特性
  4. 小端序数据处理
  5. 动态调试提取加密参数

注意事项

  • go_bytes的初始nibble值(0x40)需要硬编码
  • bouquet可仅用中序遍历快速求解
  • zistel的box表实际是简单的模4运算
  • 所有加密操作都需要注意字节序处理

附:完整EXP代码建议参考原文,其中包含详细的字节操作和循环逻辑实现。

"楚慧杯"湖北省网络与数据安全竞赛逆向工程题目解析 题目1:go_ bytes 加密逻辑 : 使用初始值 tmp = 0xDEAD 和线性同余算法生成密钥流: tmp = (291 * tmp + 1110) & 0xFFFF 加密数据为8字节一组的数组,每组包含两个小端序存储的4字节数值(实际仅低2字节有效) 解密步骤: 对每组数据,将两个字节组合成16位数值(小端序) 与密钥流异或得到中间值 当前字符的高4位来自前一个字符的低4位(初始为0x40) 解密脚本 : 题目2:bouquet 二叉树遍历 : 给定中序和后序遍历结果(实际解题时仅需中序) 已知flag格式以"DASCTF{"开头 通过中序遍历重建二叉树后层次遍历即可得flag 解题技巧 : 利用已知前缀定位节点位置 手工绘制二叉树结构可快速推导完整flag 题目3:zistel 加密算法分析 : 密钥初始化:使用固定字符串"love"生成12字节key 加密流程: 将输入分成8字节块(两个4字节DWORD) 进行20轮Feistel结构加密 每轮使用key的4字节(循环选取)作为轮密钥 核心函数 : 解密脚本 : 完整解题流程 go_ bytes : 逆向处理字节序 注意4位nibble的传递关系 bouquet : 中序:左根右 后序:左右根 通过前缀确定根节点位置 zistel : 动态提取轮密钥 逆序执行加密步骤 注意swap操作的对称性 关键知识点 流密码的逆向计算 二叉树遍历的重建技巧 Feistel结构的对称特性 小端序数据处理 动态调试提取加密参数 注意事项 go_ bytes的初始nibble值(0x40)需要硬编码 bouquet可仅用中序遍历快速求解 zistel的box表实际是简单的模4运算 所有加密操作都需要注意字节序处理 附:完整EXP代码建议参考原文,其中包含详细的字节操作和循环逻辑实现。