-
-
看雪·2026 KCTF > 第二题:巳时·绿光幽语
-
发表于: 2天前 59
-
采用 Codex + IDA9 + MCP + deepseek-v4-flash
提示词:
AI分析用时 12分钟17秒
在文件尾部 0x717F0B 处找到 PyInstaller 归档魔数 MEI\x0c\x0b\x0a\x0b\x0e,确认是 PyInstaller onefile 打包程序。用 pyinstxtractor-ng 解包:
解包得到的入口 main.pyc 反汇编后却只是:
而 PYZ 中 112 个模块全部是标准库(argparse、base64、socket……),没有任何自定义业务代码。运行程序却会打印:
提示,需要还原的代码
请输入key还原代码(请输入6个字符)
这说明真正逻辑不在常规位置。
在所有 pyc 中都搜不到提示字符串,于是怀疑运行时组件被改动。对比同版本官方 DLL:
自带 DLL 大了约 1MB,且在偏移 0x4DACEE 处直接找到字符串 my_function。用 Python 3.13 的 marshal 加载该偏移附近的代码对象,确认:
<frozen os> 的模块级字节码中,偏移 0xAD2(约 2758)之后是注入的挑战代码。其相关常量如下:
还原后的逻辑为:
关键点:
成功串密文只有 15 字节,而目标明文就是提示里给出的 恭喜成功!(UTF-8 恰好 15 字节)。逐字节异或即可还原重复密钥:
得 6 字符密钥:yb6tcr
验证 co_code 密文用同一密钥解密:
反汇编得到的正是完整有效的 my_function 字节码:
实际运行 题目.exe 并输入 yb6tcr:
程序成功还原代码并打印 恭喜成功!,密钥有效 ✅
| 文件 | 大小 |
|---|---|
| 题目自带的 python313.dll | 7,127,552 B |
| 官方 3.13.5 python313.dll | 6,110,416 B |
| const 索引 | 值 | 含义 |
|---|---|---|
| 142 | 20 | 循环次数(最多重试 20 次) |
| 143 | |
待还原的函数(当前为 print(666)) |
| 145 | 8 个 bytes | 提示文本密文(XOR 0x55) |
| 146 | 85 (0x55) | 提示文本 XOR 密钥 |
| 148 | 6 | key 长度 |
| 149 | b'\xecbmucryb6tcr*c\x03ucryb6tCr\x1eb' | co_code 密文 |
| 150 | ('co_code',) | 关键字参数 |
| 151 | b'\x9f\xe3\x9b\x91\xf5\xee\x9f\xea \xa6\x91\xe9\xed\x96\xde\xb7' |
成功串密文 |
| 152 | ('co_consts',) | 关键字参数 |
这是KCTF2026第二题:巳时·绿光幽语,Reverse,请给出flag。
[+] Python version: 3.13
[+] Found 21 files in CArchive
[+] Possible entry point: main.pyc
[+] Found 112 files in PYZ archive
import sys
sys.exit(0)
def my_function():
print("恭喜成功!")
while x < 20:
# 用 0x55 异或 8 段密文,拼出提示并打印
buffer = b''.join(enc_list) # 8 段密文
w = b''.join(bytes([b ^ 85]) for b in buffer)
print(w.decode('utf-8')) # 提示文本
key = input() # 读取 6 字符 key
if len(key) != 6:
continue # 长度不对则重试
b_key = key.encode()
c = b'\xecbmucryb6tcr*c\x03ucryb6tCr\x1eb'
buf = b''.join(bytes([c[i] ^ b_key[i % 6]]) for i in range(len(c)))
my = my_function.__code__.replace(co_code=buf) # 恢复字节码
succ = b'\x9f\xe3\x9b\x91\xf5\xee\x9f\xea\xa6\x91\xe9\xed\x96\xde\xb7'
buf2 = b''.join(bytes([succ[i] ^ b_key[i % 6]]) for i in range(len(succ)))
my = my.replace(co_consts=(None, buf2.decode('utf-8'))) # 恢复打印内容
my_function.__code__ = my
my_function() # 执行还原后的函数
密文: 9f e3 9b 91 f5 ee 9f ea a6 91 e9 ed 96 de b7
明文: e6 81 ad e5 96 9c e6 88 90 e5 8a 9f ef bc 81 ("恭喜成功!" UTF-8)
密钥: 79 62 36 74 63 72 79 62 36 74 63 72 79 62 36
y b 6 t c r y b 6 t c r y b 6
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。