几道非常有趣的CTF题目Writeup
字数 2103 2025-11-28 12:18:11
CTF题目解析与教学文档
概述
本文档详细分析几道CTF题目的解题思路和方法,涵盖Misc、Web和Crypto三个方向。通过逐步拆解题目,帮助读者掌握相关技术要点。
Misc方向
题目1:音频隐写与AES解密
解题步骤
-
文件分析
- 题目提供
flag.txt和wav文件。 flag.txt末尾包含AES加密数据,开头和结尾有干扰字符串VeHb8c2b4和e2HmCvW10。
- 题目提供
-
隐写信息提取
- 使用
SilentEye从wav文件中提取JPEG隐写数据,得到密钥JnzJcwoi23nDmx。 - 从
wav中进一步提取出一个ELF程序,该程序用于加密数据。
- 使用
-
AES解密
- 分析ELF程序的
asec函数,发现采用AES-128-ECB模式,密钥为2e9a4dcb55be306bdb136d86b8e6ee82。 - 删除干扰字符串后,对剩余数据进行解密:
# 解密流程 1. Base64解码 → AES解密 → Base64解码 2. 使用CyberChef工具链:From Base64 → AES Decrypt (ECB模式) → From Base64 - 最终得到Flag:
DASCTF{23w89c2n2g-8cr57t6bv92-213vf3vb9-13cyn23vb}。
- 分析ELF程序的
技术要点
- 隐写工具:SilentEye可用于音频隐写分析。
- AES-ECB模式:无需IV,直接使用密钥解密。
- 数据清洗:注意去除头尾干扰字符串。
题目2:流量分析与自定义Base64
解题步骤
-
流量提取
- 从HTTP流量中提取
2.cpython-37.pyc文件,反编译后得到源码。 - 源码显示服务端监听3333端口,使用自定义Base64编码通信。
- 从HTTP流量中提取
-
自定义Base64编解码
- 字符集替换:
LMNOPQRSTUVWxyzabcdefghijklmnopqrstuvw0123456789+/XYZABCDEFGHIJK。 - 实现编解码函数:
def custom_base64_decode(encoded_str): # 将自定义字符映射回标准Base64索引 # 解码为二进制后转换为字节
- 字符集替换:
-
解密流量
- 使用
tshark提取3333端口的流量数据:tshark -r Protocol_decryption.pcap -Y "tcp.port==3333" -T fields -e data.data > out.hex - 编写脚本解密流量,得到Flag:
flag{e34f1743c79af05fe922317bd44aaed1}。
- 使用
技术要点
- PyC反编译:使用
uncompyle6等工具还原源码。 - 自定义编码:需理解Base64原理并适配非标准字符集。
- 流量过滤:通过
tshark按端口过滤数据。
题目3:URI流量与Base64
解题步骤
-
数据提取
- 从所有URI流量中提取Base64编码的字符串。
- 删除重复的干扰文本(如
flag is this, flag is here.)。
-
Base64解码
- 直接解码得到Flag:
DASCTF{6ae5c439859ad420e2ce26dcaeed6b20}。
- 直接解码得到Flag:
技术要点
- 数据清洗:正则表达式或字符串匹配去除噪声。
- Base64解码:注意填充字符
=的处理。
Web方向
题目:PHP反序列化漏洞
解题步骤
-
源码分析
- 题目提示Flag在
flag.php中。 - 关键类:
FileReader(文件读取)、DataProcessor(数据处理)、OutputHandler(输出控制)。
- 题目提示Flag在
-
构造POP链
- 利用链:
OutputHandler::__destruct() → render() → DataProcessor::__toString() → process() → FileReader::read() - 序列化Payload构造:
$f = new FileReader("flag.php"); $p = new DataProcessor($f); $o = new OutputHandler($p, "html"); echo serialize($o);
- 利用链:
-
触发漏洞
- 提交序列化数据,触发文件读取,获取Flag。
技术要点
- POP链构造:理解魔术方法(如
__destruct、__toString)的调用链。 - 序列化格式:确保Payload符合PHP序列化语法。
- 输出验证:
OutputHandler的format需设为html以通过检查。
Crypto方向
题目1:PRNG状态破解
解题步骤
-
算法分析
- 自定义PRNG类
rand,状态为4个64位整数。 - 关键方法:
temper(混淆输出)、untemper(逆向混淆)。
- 自定义PRNG类
-
状态恢复
- 通过已知输出反推内部状态:
def untemper(y): x = (y * inv11) % (1<<64) x = rotl64(x, 55) # 64-9=55 x = (x * inv13) % (1<<64) return x
- 通过已知输出反推内部状态:
-
密钥生成
- 恢复状态后,预测下一个随机数作为AES密钥。
- 解密Flag:
DASCTF{fuNn9_r@nd_in_l1n3@r!!!!}。
技术要点
- PRNG逆向:根据输出逆向计算内部状态。
- 模运算:使用模逆元还原线性变换。
- AES密钥推导:确保密钥长度匹配(128位)。
题目2:多项式格攻击
解题步骤
-
问题建模
- 给定多组
(x, y),满足多项式关系:y = ∑a_i * x^i + B * ∑x^i。 - 目标:求解系数
a_i(即Flag的编码)。
- 给定多组
-
格构造
- 使用LLL算法求解格基:
# 构造矩阵,应用LLL规约 L = matrix.LLL() # 提取短向量得到系数
- 使用LLL算法求解格基:
-
数据解密
- 将系数转换为字节,解密AES-GCM模式数据:
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) flag = cipher.decrypt(ct) - 得到Flag:
DASCTF{Y0u_r3@11y_Kn0w_what_your_3V@lu@t3_pO1ynOmi@1!}。
- 将系数转换为字节,解密AES-GCM模式数据:
技术要点
- 格基构造:将多项式问题转化为格问题。
- LLL算法:用于求解近似最短向量。
- AES-GCM模式:注意Nonce和Tag的处理。
总结
通过以上题目的解析,可掌握以下技能:
- 隐写分析:音频/图像隐写工具的使用。
- 流量分析:自定义协议的解密与过滤。
- PHP反序列化:POP链构造与利用。
- 密码学攻击:PRNG状态恢复、格基规约。
实际解题中需结合工具链(如CyberChef、tshark、SageMath)并注重细节处理。