CTF逆向新手别怕!用Python脚本搞定AES、Z3和迷宫题(附避坑指南)
CTF逆向实战指南Python脚本破解AES、Z3与迷宫题的黄金法则1. 逆向工程中的密码学识别技巧逆向题目中常见的加密算法往往有鲜明的特征。AES加密通常会出现以下关键线索固定长度的密钥16/24/32字节明显的S盒置换操作SubBytes轮密钥生成过程Key ExpansionECB/CBC等模式标识典型AES特征代码片段from Crypto.Cipher import AES cipher AES.new(key, AES.MODE_CBC, iv) # CBC模式识别点当遇到以下情况时很可能是Z3约束求解题大量线性/非线性方程组合变量间存在数学约束关系题目描述提及求解满足条件的输入Z3题目特征示例from z3 import * solver Solver() solver.add(x y 42) # 典型约束条件2. AES解密脚本的实战应用2.1 标准AES解密流程完整解密脚本应包含以下关键组件from Crypto.Cipher import AES from Crypto.Util.Padding import unpad def aes_decrypt(ciphertext, key, ivNone, modeAES.MODE_ECB): cipher AES.new(key, mode, iv) if iv else AES.new(key, mode) plaintext cipher.decrypt(ciphertext) return unpad(plaintext, AES.block_size) if mode ! AES.MODE_ECB else plaintext常见问题排查表错误类型可能原因解决方案ValueError: Incorrect padding填充模式不匹配尝试禁用unpad或更换填充方案TypeError: Object type class str密钥/密文格式错误确保使用bytes类型(.encode()转换)ValueError: Data must be paddedCBC模式未对齐检查密文是否为16字节倍数2.2 变种AES处理技巧遇到修改S盒或轮函数的题目时定位加密关键函数提取自定义S盒数据逆向实现解密逻辑自定义S盒处理示例custom_sbox [...] # 从逆向代码中提取的S盒 inv_sbox [0]*256 for i, val in enumerate(custom_sbox): inv_sbox[val] i # 构建逆S盒3. Z3约束求解实战指南3.1 方程标准化处理原始题目给出的约束条件往往需要预处理import re def normalize_equations(text): # 统一变量命名v1→v[0] text re.sub(rv(\d), lambda m: fv[{int(m.group(1))-1}], text) # 转换不等式为等式 text text.replace(!, ) # 注意逻辑取反 return text.split() # 按分隔符拆分3.2 多变量求解模板from z3 import * def solve_constraints(equations): solver Solver() vars [Int(fv{i}) for i in range(len(equations))] for eq in equations: solver.add(eval(eq)) # 动态解析方程 if solver.check() sat: model solver.model() return [model[v].as_long() for v in vars] return None性能优化技巧对布尔变量使用Bool而非Int设置求解超时时间solver.set(timeout10000)优先处理简单约束减少搜索空间4. 迷宫路径算法破解4.1 二维迷宫解析典型迷宫题的数据结构处理def parse_maze(maze_str, width, height): return [list(maze_str[i*width:(i1)*width]) for i in range(height)]4.2 BFS路径求解from collections import deque def bfs_solve(maze, start, end, wall#): directions [(0,1),(1,0),(0,-1),(-1,0)] queue deque([(start, [])]) visited set([start]) while queue: pos, path queue.popleft() if pos end: return path for dx, dy in directions: x, y pos[0]dx, pos[1]dy if (0xlen(maze) and 0ylen(maze[0]) and maze[x][y] ! wall and (x,y) not in visited): queue.append(((x,y), path[(dx,dy)])) visited.add((x,y)) return None路径指令转换def path_to_directions(path): dir_map {(0,1):R, (1,0):D, (0,-1):L, (-1,0):U} return .join([dir_map[p] for p in path])5. 实战调试与异常处理5.1 常见错误排查AES解密典型错误try: plaintext aes_decrypt(ciphertext, key) except ValueError as e: print(f解密失败: {str(e)}) # 尝试不同填充方式 plaintext cipher.decrypt(ciphertext) # 不处理填充5.2 动态调试技巧使用print(hexdump(数据))查看二进制结构对关键变量添加类型检查断言assert isinstance(key, bytes), 密钥必须为bytes类型中间结果验证mid_value process(data) assert expected_pattern in mid_value, 处理结果异常6. 性能优化策略6.1 Z3求解加速# 设置并行求解 set_option(parallel.enable, True) set_option(timeout, 60000) # 60秒超时 # 添加约束时优先处理简单约束 solver.add(simple_constraints) solver.add(complex_constraints) # 后处理复杂约束6.2 迷宫算法优化# 双向BFS实现 def bidirectional_bfs(maze, start, end): # 初始化两个方向的队列和访问集 queue_start deque([start]) visited_start {start: None} queue_end deque([end]) visited_end {end: None} while queue_start and queue_end: # 交替扩展两个方向的搜索 ...7. 工具链整合建议构建自动化解题工具包CTF_RE_Toolkit/ ├── crypto/ │ ├── aes_utils.py │ └── rc4_utils.py ├── solvers/ │ ├── z3_wrapper.py │ └── angr_scripts/ ├── misc/ │ ├── maze_solver.py │ └── sudoku.py └── utils/ ├── hexdump.py └── debug_tools.py典型工作流使用file和strings初步分析IDA/Ghidra静态分析定位关键算法选择合适的工具脚本进行破解动态调试验证结果在多次实战中发现约80%的基础逆向题目可以通过标准脚本快速解决关键在于准确识别题目类型并选择合适的工具。遇到变种算法时重点分析其与标准算法的差异点通常只需修改脚本的局部逻辑即可适配。