-
-
[原创]KCTF2026 第5题 解析
-
发表于: 1天前 61
-
附件给出一个 Windows 32 位控制台程序 cm.exe,运行后要求输入序列号。题目目标是构造正确 Key,使程序输出:
最终可用序列号为:
首先查看压缩包内容,可以看到主要文件为:
readme.txt 中说明需要输入一个序列号,成功后程序会输出 verify success.。
使用 file 或者 PE 工具查看 cm.exe,可以确认它是一个 32 位 Windows 控制台程序。随后直接使用 IDA 打开程序。
在字符串窗口中可以看到一些比较明显的字符串,例如:
一开始容易被 admin123、password 这类字符串误导,但交叉引用后可以发现它们不是最终序列号校验的关键,真正的校验逻辑在后面的输入处理和大整数运算部分。
从 verify success. 字符串入手查看交叉引用,可以定位到主校验函数。程序整体逻辑大致如下:
关键长度检查可以整理为:
也就是说,输入必须是 88 个十六进制字符,转换后正好是 44 字节。
程序将 88 位十六进制字符串转换成 44 字节后,会先进行两个整体约束检查。
第一个是异或校验:
第二个是加权和校验:
这两个检查不是最终求解的核心,但可以用于验证构造出来的 Key 是否满足程序要求。
继续分析可以看到,程序将前 28 字节经过某种表映射后,与目标字符串的一部分进行比较。
目标明文字符串为:
由于这里的变换本质上是固定表映射,因此可以通过构造逆表,将目标字符反推回输入字节。
逆推后得到前 28 字节为:
这部分长度为 56 个十六进制字符,也就是 28 字节。
剩下的 16 字节进入大整数校验函数。该函数核心形式类似 RSA 加密:
其中:
也就是程序会把输入后 16 字节当作大整数 m,计算 m^0x10001 mod n,再与程序内部的目标值比较。
程序内部目标密文为:
因此需要对这个 RSA-like 过程求逆。
对模数 n 分解:
计算:
得到私钥指数:
于是可以解出明文:
运行结果:
因此后 16 字节为:
将前 28 字节和后 16 字节拼接即可得到完整序列号:
长度检查:
正好满足程序要求的 88 位十六进制输入。
将该序列号输入程序:
程序输出:
说明序列号构造正确。
本题表面上出现了 admin123、password 等诱导字符串,但真正逻辑并不是普通账号密码比较,而是分为两段进行校验:
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。