首页
社区
课程
招聘
[原创]KCTF 2026 第五题
发表于: 22小时前 125

[原创]KCTF 2026 第五题

22小时前
125

题目给出 cm.exe,规则很简单:输入 Key,看到 verify success. 就算通过。样本是 x86 PE,
对照一下SHA1是否题面一致:

最终Flag

这题的难点不在爆破,而在于三件事:控制流被 SEH 和运行时跳板打散,输入实际上是 44 字节数据,最后 16 字节还经过了一次小模数 RSA。下面按真实逆向顺序展开。

字符串窗口里有一组很刻意的提示:

如果跟着这些字符串做,会在几个自定义大整数对象里兜圈子。真正应该先盯住的是成功字符串。最终比较的目标位于 .rdata:0x416380

长度恰好是 44 字节。交叉引用落在 0x40454A,关键比较代码非常直白:

因此最稳的路线不是猜密码,而是把这 44 字节目标反推回输入。

主函数 0x403D90 读取输入后,先进行格式检查:

注意这里的字符集表面上允许 0-9A-Z,但后续实际解法使用的是大写十六进制字符。0x402100 把输入按 16 进制解析成 11 个 32 位 limb,随后主函数将 limb 反序导出为连续的 44 字节。

对最终 Key 下断点,0x404112 处的缓冲区内容为:

随后有两道前置校验。它们都在 0x403D90 中,静态和动态结果一致:

最终数据的实际结果是:

只满足这两项仍然会失败。真正的校验从 0x404271 调用 0x403500 后才开始。

0x403500 一开始就建立 SEH 链:

函数体里反复出现这种布局:

再加上进入输入路径前的 sub_4033A0,直接让 IDA 按线性控制流读,很容易把大量 ret 当成函数结束。实际运行时这些块由异常处理和跳板串起来,所以这题不能只盯一份伪代码。

我使用的做法是:静态分析只负责确定输入格式、常量和最终比较;运行时在 0x4041120x4041BC0x40425F0x4035000x404586 下点确认数据确实按预期流动。这样可以避开假控制流,同时不需要 patch 样本。

运行到 0x403500 后,程序会先截取 Key 的后 32 个字符:

它会被解析为 4 个 32 位 limb,也就是 16 字节 RSA 密文块。函数中的查表逻辑最终需要 44 个索引;前 28 个索引直接来自输入,后 16 个索引由 RSA 运算恢复。

把目标 Welcome 串逆查程序的表,得到的索引序列为:

程序对候选密文 c 做的是:

其中:

末 16 个索引正是 m

为了反推 c,分解这个 128 位模数即可:

因此:

得到:

把前 28 个索引和这个密文拼接,就是最终的 44 字节输入数据。

完整脚本:

它包含从目标串使用到的查表项、p/q/d 推导、RSA 逆运算和两个前置校验

输出:

最后用原程序验证:


冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

最后于 22小时前 被TimeQvQ编辑 ,原因:
收藏
免费 0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回