-
-
[原创] KCTF2602 第二题 绿光幽语 Writeup
-
发表于: 2天前 167
-
下文「消耗」均为估算,保留数量级供复盘,不作为精确账单。
本节聚焦「方向性错误」本身;子代理前半程的同类试错在第 2 部分用时里一并统计。
把题目当成「改过的 PyInstaller bootloader 原生逻辑」
错误 Python / idalib 环境
图标 / 字符串 / 单字节 XOR 全盘盲扫
死磕 main.pyc 解密
Frida 挂错进程
误判「业务在 native 自定义段」
题目表面是「原生校验 / bootloader 补丁」,实质是 Python 3.13 冻结标准库(os)里插入的挑战脚本。继续只做 PE 差分与 boot 反编译收益极低;应尽早对 运行中的 python313.dll / 子进程 做 code object / 模块源码转储。
运行行为确认
PyInstaller 结构
动态:对子进程注入
提示串:单字节 XOR 0x55
Key:6 字节循环 XOR(已知明文)
代码还原业务
验证
静态一句话:enc ⊕ UTF-8("恭喜成功!") 的前 6 字节即 key yb6tcr。
相关文件参考附件,python313.dll 这些不提供,可以使用常规工具从exe中释放,或直接监控进程读写文件记录,从临时目录中获取。
| 项目 | 内容 |
|---|---|
| 题目 | KCTF 2026 · 第二题 · 绿光幽语 |
| 样本 | 题目.exe / target.exe(PyInstaller onefile,内嵌 Python 3.13) |
| 目标 | 输入 6 字符 key,还原并执行被加密的 my_function |
| 答案 Key | yb6tcr |
| 验证输出 | 提示后打印 恭喜成功!,进程 exit 0 |
| 分析日期 | 2026-08-11 |
| 分析环境 | Windows 10/11 · IDA 9.4(idalib)· Frida · Anaconda Python 3.11 |
| 项 | 说明 |
|---|---|
| 主模型 | Cursor Grok 4.5(Cursor 产品内置;SpaceXAI × Cursor) |
| 协作形态 | 前台会话探索 + 后台子代理 [CTF序列号逆向分析](0acc855a-6d51-4db6-90b8-b86ec65a45b9) 完成关键路径 |
| Token 统计方式 | 会话侧无官方账单导出;按 agent transcript 落盘体积 × 多轮上下文放大系数 估算(工具回传会反复进入上下文,落盘远小于实际计费量) |
| 单价假设(API 等价粗算) | Input ≈ $3 / 1M tokens,Output ≈ $15 / 1M tokens;按混合均价约 $5 / 1M tokens 估算费用(Cursor 订阅场景下仅为对照,非实际扣费单) |
| 阶段 | 时间(UTC+8) | 墙钟约 |
|---|---|---|
| 初探 / 弯路主导 | 14:51 → 15:02 | ≈ 11 分钟 |
| (弯路惯性延续) | 子代理启动后前半程仍在 IDA/Frida/对比 PE 上打转 | 计入第 2 部分前的试错,见下节重叠说明 |
| 指标 | 估算 |
|---|---|
| 有效弯路墙钟 | ≈ 25–35 分钟(含前台 11 分钟 + 子代理前半程同向试错) |
| Transcript 落盘 | 前台相关约 35–40 KB;弯路相关工具回合约占子代理前部 |
| 估算 Token | 约 18–28 万 tokens(落盘 ×≈8–10,再计工具输出) |
| 估算费用(API 等价) | 约 $0.9 – $1.4 |
| 项 | 内容 |
|---|---|
| 模型 | Cursor Grok 4.5(后台子代理同模型族) |
| 环境纠正后 | 按 d:\py94.bat 配置:IDADIR=d:\IDA94,CONDA_ROOT=D:\Anaconda311_64,PYTHONPATH→IDAXT,不执行 bat,用该 Python import idapro |
| 成功阶段 | 15:02 → 16:11(UTC+8),墙钟 ≈ 69 分钟(含弯路收敛 + 关键突破 + 验证) |
| 其中有效突破段 | 约最后 15–20 分钟:Frida 注入子进程 → dump os → XOR 0x55 → crib 出 yb6tcr |
| 指标 | 估算 |
|---|---|
| 墙钟 | ≈ 69 分钟(15:02–16:11) |
| Transcript 落盘 | 子代理约 167 KB / ~59 条消息 |
| 估算 Token | 约 55–85 万 tokens |
| 估算费用(API 等价) | 约 $2.8 – $4.3 |
| 项 | 结果 |
|---|---|
| Key | yb6tcr |
| 存放位置 | python313.dll deepfreeze 的 os,非 main.pyc |
| 提示加密 | 单字节 XOR 0x55,UTF-8 |
| 代码/串还原 | 6 字节 key 循环 XOR + 替换 code object |
| 决定性手法 | 子进程 Frida → dump 冻结 os → 常量 crib |
| 阶段 | 模型 | 墙钟(约) | Token(约) | 费用(约,API 等价) |
|---|---|---|---|---|
| 失败弯路 | Cursor Grok 4.5 | 25–35 min | 18–28 万 | $0.9–$1.4 |
| 成功分析 | Cursor Grok 4.5 | 69 min | 55–85 万 | $2.8–$4.3 |
| 合计 | 同上 | ≈ 1.5–1.7 h | ≈ 73–113 万 | ≈ $3.7–$5.7 |
| 文件 | 作用 |
|---|---|
xor55.py / xor55_out.txt |
0x55 解密提示串 |
os_challenge_dump.txt |
运行时 os 模块转储 |
run_dump_os.py / run_dump_code.py |
Frida 注入转储 |
verify_out.txt |
key 验证输出 |
target.exe_extracted/python313.dll |
deepfreeze 载体 |
分析报告分两部分,第一部分总结走过的弯路,第二部分总结攻下的路径。
实际走过的弯路肯定不止,本文给出的是Cursor与主力Grok 4.5的分析。
实际另一个Hermes + GLM 5.2 的兜了大半圈都没找到切入点,果断截断了。
各个Agent有30%问题是工具环境没配置对,找不到,我们注意到了,及时暂停指示其正确配置使用工具。
值得参考的点:
AI最后的成功突破的闪光点是发现了my_function在python*.dll中,及时改变策略,然后使用Frida的方式dump python对象。
提示,需要还原的代码
def my_function():
print("恭喜成功!")
请输入key还原代码(请输入6个字符)
key[i] = enc[i] ⊕ plain[i] (i = 0..5)
→ key = b'yb6tcr'
提示,需要还原的代码
def my_function():
print("恭喜成功!")
请输入key还原代码(请输入6个字符)
恭喜成功!
# 位于冻结 os 模块导入尾部(示意)
XOR_BYTE = 0x55 # 常量 85
cipher_chunks = [b"...", ...] # 8 × 16 bytes
prompt = bytes(b ^ XOR_BYTE for chunk in cipher_chunks for b in chunk).decode("utf-8")
print(prompt) # 展示「需还原的代码」与输入要求
key = input()
assert len(key) == 6
kb = key.encode("utf-8") # b'yb6tcr'
def rol_xor(data: bytes, k: bytes) -> bytes:
return bytes(data[i] ^ k[i % len(k)] for i in range(len(data)))
# 还原字符串常量 → 「恭喜成功!」
msg = rol_xor(MSG_CIPHER, kb).decode("utf-8")
# 还原 bytecode,写回 my_function.__code__(CodeType.replace 等)
my_function.__code__ = restore_code(CODE_CIPHER, kb, msg)
my_function() # print 恭喜成功!
# 向题目喂入 key(注意控制台代码页;也可用重定向文件)
"yb6tcr" | .\target.exe
yb6tcr
下文「消耗」均为估算,保留数量级供复盘,不作为精确账单。
| 项目 | 内容 |
|---|---|
| 题目 | KCTF 2026 · 第二题 · 绿光幽语 |
| 样本 | 题目.exe / target.exe(PyInstaller onefile,内嵌 Python 3.13) |
| 目标 | 输入 6 字符 key,还原并执行被加密的 my_function |
| 答案 Key | yb6tcr |
| 验证输出 | 提示后打印 恭喜成功!,进程 exit 0 |
| 分析日期 | 2026-08-11 |
| 分析环境 | Windows 10/11 · IDA 9.4(idalib)· Frida · Anaconda Python 3.11 |
| 项 | 说明 |
|---|---|
| 主模型 | Cursor Grok 4.5(Cursor 产品内置;SpaceXAI × Cursor) |
| 协作形态 | 前台会话探索 + 后台子代理 [CTF序列号逆向分析](0acc855a-6d51-4db6-90b8-b86ec65a45b9) 完成关键路径 |
| Token 统计方式 | 会话侧无官方账单导出;按 agent transcript 落盘体积 × 多轮上下文放大系数 估算(工具回传会反复进入上下文,落盘远小于实际计费量) |
| 单价假设(API 等价粗算) | Input ≈ $3 / 1M tokens,Output ≈ $15 / 1M tokens;按混合均价约 $5 / 1M tokens 估算费用(Cursor 订阅场景下仅为对照,非实际扣费单) |
| 阶段 | 时间(UTC+8) | 墙钟约 |
|---|---|---|
| 初探 / 弯路主导 | 14:51 → 15:02 | ≈ 11 分钟 |
| (弯路惯性延续) | 子代理启动后前半程仍在 IDA/Frida/对比 PE 上打转 | 计入第 2 部分前的试错,见下节重叠说明 |
| 指标 | 估算 |
|---|---|
| 有效弯路墙钟 | ≈ 25–35 分钟(含前台 11 分钟 + 子代理前半程同向试错) |
| Transcript 落盘 | 前台相关约 35–40 KB;弯路相关工具回合约占子代理前部 |
| 估算 Token | 约 18–28 万 tokens(落盘 ×≈8–10,再计工具输出) |
| 估算费用(API 等价) | 约 $0.9 – $1.4 |
| 项 | 内容 |
|---|---|
| 模型 | Cursor Grok 4.5(后台子代理同模型族) |
| 环境纠正后 | 按 d:\py94.bat 配置:IDADIR=d:\IDA94,CONDA_ROOT=D:\Anaconda311_64,PYTHONPATH→IDAXT,不执行 bat,用该 Python import idapro |
| 成功阶段 | 15:02 → 16:11(UTC+8),墙钟 ≈ 69 分钟(含弯路收敛 + 关键突破 + 验证) |
| 其中有效突破段 | 约最后 15–20 分钟:Frida 注入子进程 → dump os → XOR 0x55 → crib 出 yb6tcr |
| 指标 | 估算 |
|---|---|
| 墙钟 | ≈ 69 分钟(15:02–16:11) |
| Transcript 落盘 | 子代理约 167 KB / ~59 条消息 |
| 估算 Token | 约 55–85 万 tokens |
| 估算费用(API 等价) | 约 $2.8 – $4.3 |
| 项 | 结果 |
|---|---|
| Key | yb6tcr |
| 存放位置 | python313.dll deepfreeze 的 os,非 main.pyc |
| 提示加密 | 单字节 XOR 0x55,UTF-8 |
| 代码/串还原 | 6 字节 key 循环 XOR + 替换 code object |
| 决定性手法 | 子进程 Frida → dump 冻结 os → 常量 crib |
| 阶段 | 模型 | 墙钟(约) | Token(约) | 费用(约,API 等价) |
|---|---|---|---|---|
| 失败弯路 | Cursor Grok 4.5 | 25–35 min | 18–28 万 | $0.9–$1.4 |
| 成功分析 | Cursor Grok 4.5 | 69 min | 55–85 万 | $2.8–$4.3 |
| 合计 | 同上 | ≈ 1.5–1.7 h | ≈ 73–113 万 | ≈ $3.7–$5.7 |
| 文件 | 作用 |
|---|---|
xor55.py / xor55_out.txt |
0x55 解密提示串 |
os_challenge_dump.txt |
运行时 os 模块转储 |
run_dump_os.py / run_dump_code.py |
Frida 注入转储 |
verify_out.txt |
key 验证输出 |
target.exe_extracted/python313.dll |
deepfreeze 载体 |
- 依据:
main.pyc仅sys.exit(0),运行时却有中文提示与 6 字符输入。
- 初期用
py -3(Python 3.12)+ 自拼IDADIR,与本机配置的d:\py94.bat环境不一致。 - 全库式
ida_find_io.py扫描易卡住;用户纠正后才改为 Anaconda311 + IDA94 idalib。
extracted_icon.png无隐藏 key;对 GBK 提示做单字节 XOR 全文件搜索无命中(因字符串在 冻结模块常量 中,且编码为 UTF-8 XOR,不是裸 GBK)。
- 假设 6 字节 key 加密了 entry pyc;实际 entry 仍是平凡的
sys.exit,挑战不在此处。
- onefile 解压出子进程跑真正的 Python;只 hook 父进程只能看到循环写提示,拿不到业务栈与 code object。
- 长时间在
0x14002E200一带与 bootloader 反编译上消耗轮次,延误发现 deepfreeze 的os模块注入。
- GBK 控制台输出:
提示,需要还原的代码 def my_function(): print("恭喜成功!") 请输入key还原代码(请输入6个字符) - 输入须 恰好 6 字符;错误则循环提示。
- 解包得
main.pyc、python313.dll、PYZ等;entry 无业务。 - 业务不在 PYZ 用户脚本,而在 嵌入 DLL 的 deepfreeze 标准库。
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
赞赏
他的文章
谁下载
赞赏
雪币:
留言: