首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
CTF对抗
发新帖
0
0
[原创] KCTF2602 第二题 绿光幽语 Writeup
发表于: 2026-8-11 17:24
250
[原创] KCTF2602 第二题 绿光幽语 Writeup
HHHso
26
2026-8-11 17:24
250
# 【前言】 分析报告分两部分,第一部分总结走过的弯路,第二部分总结攻下的路径。 实际走过的弯路肯定不止,本文给出的是Cursor与主力Grok 4.5的分析。 实际另一个Hermes + GLM 5.2 的兜了大半圈都没找到切入点,果断截断了。 各个Agent有30%问题是工具环境没配置对,找不到,我们注意到了,及时暂停指示其正确配置使用工具。 值得参考的点: AI最后的成功突破的闪光点是发现了my_function在python*.dll中,及时改变策略,然后使用Frida的方式dump python对象。 | 项目 | 内容 | |------|------| | 题目 | 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 | --- ## 0. 模型与计价说明 | 项 | 说明 | |----|------| | 主模型 | **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 订阅场景下仅为对照,非实际扣费单) | > 下文「消耗」均为估算,保留数量级供复盘,不作为精确账单。 --- ## 1. 失败弯路(弯路与代价) ### 1.1 时间线 | 阶段 | 时间(UTC+8) | 墙钟约 | |------|----------------|--------| | 初探 / 弯路主导 | 14:51 → 15:02 | **≈ 11 分钟** | | (弯路惯性延续) | 子代理启动后前半程仍在 IDA/Frida/对比 PE 上打转 | 计入第 2 部分前的试错,见下节重叠说明 | 本节聚焦「方向性错误」本身;子代理前半程的同类试错在第 2 部分用时里一并统计。 ### 1.2 走过的失败路径 1. **把题目当成「改过的 PyInstaller bootloader 原生逻辑」** - 依据:`main.pyc` 仅 `sys.exit(0)`,运行时却有中文提示与 6 字符输入。 2. **错误 Python / idalib 环境** - 初期用 `py -3`(Python 3.12)+ 自拼 `IDADIR`,与本机配置的 `d:\py94.bat` 环境不一致。 - 全库式 `ida_find_io.py` 扫描易卡住;用户纠正后才改为 Anaconda311 + IDA94 idalib。 3. **图标 / 字符串 / 单字节 XOR 全盘盲扫** - `extracted_icon.png` 无隐藏 key;对 GBK 提示做单字节 XOR 全文件搜索无命中(因字符串在 **冻结模块常量** 中,且编码为 UTF-8 XOR,不是裸 GBK)。 4. **死磕 `main.pyc` 解密** - 假设 6 字节 key 加密了 entry pyc;实际 entry 仍是平凡的 `sys.exit`,挑战不在此处。 5. **Frida 挂错进程** - onefile 解压出子进程跑真正的 Python;只 hook 父进程只能看到循环写提示,拿不到业务栈与 code object。 6. **误判「业务在 native 自定义段」** - 长时间在 `0x14002E200` 一带与 bootloader 反编译上消耗轮次,延误发现 **deepfreeze 的 `os` 模块注入**。 ### 1.3 弯路消耗(估算) | 指标 | 估算 | |------|------| | 有效弯路墙钟 | **≈ 25–35 分钟**(含前台 11 分钟 + 子代理前半程同向试错) | | Transcript 落盘 | 前台相关约 **35–40 KB**;弯路相关工具回合约占子代理前部 | | 估算 Token | **约 18–28 万 tokens**(落盘 ×≈8–10,再计工具输出) | | 估算费用(API 等价) | **约 \$0.9 – \$1.4** | ### 1.4 弯路结论 题目表面是「原生校验 / bootloader 补丁」,实质是 **Python 3.13 冻结标准库(`os`)里插入的挑战脚本**。继续只做 PE 差分与 boot 反编译收益极低;应尽早对 **运行中的 `python313.dll` / 子进程** 做 code object / 模块源码转储。 --- ## 2. 成功路径:拿到 Key 与业务逻辑 ### 2.1 时间线与模型 | 项 | 内容 | |----|------| | 模型 | **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` | ### 2.2 关键分析步骤 1. **运行行为确认** - GBK 控制台输出: ``` 提示,需要还原的代码 def my_function(): print("恭喜成功!") 请输入key还原代码(请输入6个字符) ``` - 输入须 **恰好 6 字符**;错误则循环提示。 2. **PyInstaller 结构** - 解包得 `main.pyc`、`python313.dll`、`PYZ` 等;entry 无业务。 - 业务不在 PYZ 用户脚本,而在 **嵌入 DLL 的 deepfreeze 标准库**。 3. **动态:对子进程注入** - Frida 附着真正加载 `python313.dll` 的进程,`PyRun_SimpleString` + `gc` 扫描。 - 发现挑战逻辑挂在 **`os` 模块**,执行点约在模块体 **line 1188–1206**(导入 `os` 时跑完)。 - 现场可见:`my_function`(初始 `co_consts` 含占位 `666`)、大块 bytes 常量、常量 **`85`(即 `0x55`)**。 4. **提示串:单字节 XOR `0x55`** - 8×16 字节密文拼接后与 `0x55` XOR,再按 **UTF-8** 解码,即完整提示(128 字节)。 - 对应复现脚本思路见仓库内 `xor55.py`。 5. **Key:6 字节循环 XOR(已知明文)** - 另一段 15 字节密文:`9fe39b91f5ee9feaa691e9ed96deb7` - 明文 crib:`恭喜成功!`.encode('utf-8') - ```text key[i] = enc[i] ⊕ plain[i] (i = 0..5) → key = b'yb6tcr' ``` - 用 `yb6tcr` 循环 XOR 校验整段密文,得到完整 UTF-8「恭喜成功!」。 6. **代码还原业务** - 用同一 key 循环 XOR 还原 `my_function` 的 `co_code`(以及相关常量)。 - 经 `types.CodeType.replace` / 替换 `my_function.__code__` 后调用,打印成功信息。 - 语义上:「输入 key → 解密被篡改的函数体与字符串 → 执行还原后的 `my_function`」。 7. **验证** ```text 提示,需要还原的代码 def my_function(): print("恭喜成功!") 请输入key还原代码(请输入6个字符) 恭喜成功! ``` - Key:`yb6tcr`,exit code 0(见 `verify_out.txt`)。 ### 2.3 业务逻辑摘要(等价伪代码) ```python # 位于冻结 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 恭喜成功! ``` **静态一句话**:`enc ⊕ UTF-8("恭喜成功!")` 的前 6 字节即 key **`yb6tcr`**。 ### 2.4 成功阶段消耗(估算) | 指标 | 估算 | |------|------| | 墙钟 | **≈ 69 分钟**(15:02–16:11) | | Transcript 落盘 | 子代理约 **167 KB** / ~59 条消息 | | 估算 Token | **约 55–85 万 tokens** | | 估算费用(API 等价) | **约 \$2.8 – \$4.3** | ### 2.5 成功阶段小结 | 项 | 结果 | |----|------| | Key | **`yb6tcr`** | | 存放位置 | `python313.dll` deepfreeze 的 **`os`**,非 `main.pyc` | | 提示加密 | 单字节 XOR **`0x55`**,UTF-8 | | 代码/串还原 | **6 字节 key 循环 XOR** + 替换 code object | | 决定性手法 | 子进程 Frida → dump 冻结 `os` → 常量 crib | --- ## 3. 全程汇总 | 阶段 | 模型 | 墙钟(约) | 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** | ### 经验教训 1. PyInstaller +「空 main」→ 优先怀疑 **冻结 stdlib / runtime hook**,不要只盯 bootloader。 2. onefile 必须分析 **子进程**。 3. 中文提示可能是 **UTF-8 密文** 而非 GBK 静态串。 4. 已知明文(界面已打印的「恭喜成功!」)可直接求出循环 XOR key,无需爆破。 5. idalib 须对齐 `py94.bat`:Anaconda 3.11 + `d:\IDA94`。 --- ## 4. 附录 ### 4.1 快速验证 ```powershell # 向题目喂入 key(注意控制台代码页;也可用重定向文件) "yb6tcr" | .\target.exe ``` ### 4.2 关键产物(目录内) | 文件 | 作用 | |------|------| | `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 载体 | 相关文件参考附件,python313.dll 这些不提供,可以使用常规工具从exe中释放,或直接监控进程读写文件记录,从临时目录中获取。 ### 4.3 Flag / Key ``` yb6tcr ``` ---
登录后可查看完整内容
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
上传的附件:
KCTF2602_AI_files.zip
(20.59kb,5次下载)
收藏
・
0
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
HHHso
26
75
发帖
84
回帖
2198
RANK
关注
私信
他的文章
[原创] KCTF260A 第十题 曦光初现 Writeup
3860
[原创] KCTF2609 第九题 同墟·星海抉择 Writeup
31
[原创] KCTF2607 第七题 暗能潜流 Writeup
52
[原创] KCTF2605 第五题 忆海倒带 Writeup
102
[原创] KCTF2602 第二题 绿光幽语 Writeup
250
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
谁下载
×
huangyalei
AaronS
pzhxbz
mb_lthgjpwj
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部