首页
社区
课程
招聘
[原创] KCTF 2026 第五题:申时·忆海倒带 Writeup
发表于: 8小时前 131

[原创] KCTF 2026 第五题:申时·忆海倒带 Writeup

8小时前
131

最终 Key:

该 Key 是 88 个十六进制字符,程序解析后得到 44 字节数据。

题面给的是 Windows 控制台程序,输入 Key 后出现 verify success. 即通过。

基础识别:

工具主要用:

先扫字符串:

admin123password 这类字符串是诱饵。直接查“成功”字符串(verify success.)的引用:

输入点也在 main,所以从 main 反汇编往下看即可。

main 里先用 gets_s 读入字符串,然后调用 fcn.00402100

fcn.00402100 的作用是按 16 进制解析字符串:循环处理每个字符,每次先把当前值乘以 0x10,再加当前 nibble。

后面有长度检查:

var_89ch 是 32-bit limb 数量,var_89ch * 8 == 0x58,即输入解析后为 11 个 DWORD,也就是 44 字节。因此原始 Key 长度应为:

随后程序把这 11 个 DWORD 按大端字节序展开成 44 字节数组 B。关键逻辑在 0x4040c0 附近:

也就是从高 limb 到低 limb,每个 DWORD 按 [b3, b2, b1, b0] 输出。

44 字节数组 B 先过两个约束。

第一个是 XOR:

约束为:

第二个是滚动 checksum:

约束为:

继续往下看,程序并不是直接把 B 和目标字符串比较。

先调用:

var_858h 是原始输入字符串缓冲区,var_820h = var_858h + 0x38。也就是说 fcn.00403500 读取的是输入字符串从偏移 0x38 开始的部分,即最后 32 个 hex 字符。

这 32 个 hex 字符对应 B 的最后 16 字节。

fcn.00403500 内部做了一次 RSA 风格的模幂:

其中:

覆盖位置由 0x40437f0x4043d0 的拷贝逻辑确认,目标地址等价于:

所以最终比较用的数组是:

最终比较前,还有一层查表:

fcn.00404870 是容器索引函数。对应到数据上,查表关系可以写成:

对目标串 "Welcome to KCTF2026! Come and give it a try." 做反向查表,可以得到最终比较前需要的 44 字节:

注意分成两段看:

因此已知:

fcn.00403500 里手工构造了两个大整数容器。数据不是顺序摆放,而是 data[perm[i]]

模数容器:

取出 4 个 32-bit limb:

小端 limb 合成整数:

指数容器:

得到:

分解 N 得到两个 64-bit 素数:

这里我用的是本地 Python 写的 ECM/Pollard 组合脚本。这个模数只有 128 bit,分解成本很低。

计算私钥指数:

得到:

解 RSA:

得到 Key 的最后 16 字节:

拼接:

最终 Key:

等价静态验证结果:


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

收藏
免费 2
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回