首页
社区
课程
招聘
[原创]KCTF 2026 第二题:巳时·绿光幽语
发表于: 2天前 49

[原创]KCTF 2026 第二题:巳时·绿光幽语

2天前
49

一道"还原代码"题:6 字符 key 还原一段被加密的 Python 字节码。程序问你要 key,却把答案藏在了谁都想不到的地方——Python 解释器自带的 <frozen os> 模块尾部。本文记录完整分析链与三个实战发现,全部步骤可复现。

运行即循环提示:

PyInstaller 解包(pyinstxtractor-ng)后,反编译入口 main.pyc

几乎什么都没做。常规思路直接撞墙——真逻辑不在任何普通脚本里。这是本题第一层伪装:业务代码不在 Python 源码层,而在更底层。

对文件做 GBK/UTF-8/UTF-16 全变体字符串搜索,提示恭喜成功请输入key 全部落空。提示文本不是明文存储——它是加密的。

此时两个方向:

在 wine + gdb 下跟进这个程序,连续踩坑:

一个绕开 stdin 的实用技巧:gdb 直接模拟 read 返回——frame 2(libc read 帧)→ 写缓冲区 → return (long)7,程序就认为读到了任意 key。这比管道喂 stdin 稳定得多。

真正该断的是 Python C-API。对 python313.dll 的导出下断:

逐个 dump 执行到的 code 对象后,<frozen os> 模块的 co_names 尾部混进了一串不属于标准库 os 的名字:

input/key/replace/succ/__code__——一眼就是"读 key → XOR 解密 → 替换 code 对象 → 执行"。业务逻辑被整体塞进了 os 模块的 module 级代码末尾,这就是为什么静态搜索和普通反编译全部失效——它伪装成了标准库的一部分。

反汇编确认结构是 while x < 20: try: ... except: continue(RERAISE/PUSH_EXC_INFO/CHECK_EXC_MATCH 异常处理模式),循环里每次重新定义 my_function(print 666),读 key,长度不等于 6 就 continue。

在 frozen os 数据区(python313.dll 内,docstring 之前)找到连续 8 个 16 字节的 TYPE_STRING 常量,每段之后跟着 int 85(=0x55)和字符串 "utf-8"

解密脚本:

<frozen os> 的 co_consts 里还有一个 26 字节 bytes 常量:

它的作用:用输入的 6 字符 key 做重复 XOR,解密出 my_function 的目标字节码,然后 code.replace(co_code=解密结果, co_consts=(None, 成功串)) 替换并执行。

目标字节码用同版本 Python 3.13 编译得到:

成功字符串同步验证:9fe39b91f5ee9feaa691e9ed96deb7 XOR yb6tcr = "恭喜成功!"

这是本题最漂亮的一点——其实不需要知道目标字节码

Python 3.12+ 字节码的指令带固定 CACHE 槽位(全 0x00):

重复 key XOR 下,明文 0x00 ^ key[i%6] = key[i%6]——密文中与 CACHE 对应的字节就是 key 循环的原样

密文第 6–17 字节 cryb6tcryb6t 直接就是 key 的重复——key 明晃晃嵌在密文里,因为字节码的 CACHE 位全是 0。知道这个规律,光看密文就能拼出 key,连 Python 版本都不用猜。

项目
大小 7,438,179 字节
SHA256 F6B192F9EE87C4AD2BC8681291CA428CF8E98FEC26FA5D7B82C6E791A7A90EAD
类型 64 位 PE Console
打包 PyInstaller onefile + Python 3.13
手段 击破方式
1 PyInstaller onefile,main.pyc 为 sys.exit(0) 空壳 跟进子进程,断 Python C-API
2 业务逻辑伪装进 <frozen os> 模块尾部 逐帧 dump code 对象,看 co_names 尾部异常
3 提示文本分块 XOR 0x55 明文 UTF-8 XOR 0x55 反向搜 DLL,定位 chunk 区
4 目标字节码 XOR 循环 key 已知明文攻击 + CACHE 占位泄露
$ printf 'yb6tcr\n' | wine64 luozi.exe
提示,需要还原的代码

def my_function():
    print("恭喜成功!")

请输入key还原代码(请输入6个字符)
恭喜成功!      ← 还原后的代码真正执行了
提示,需要还原的代码
def my_function():
    print("恭喜成功!")
请输入key还原代码(请输入6个字符)

传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

最后于 2天前 被mb_dcvvjyqc编辑 ,原因: 修改笔误
收藏
免费 0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回