首页
社区
课程
招聘
[原创]KCTF 2026 第五题 "忆海倒带" WriteUp
发表于: 2026-8-17 12:53 17

[原创]KCTF 2026 第五题 "忆海倒带" WriteUp

2026-8-17 12:53
17

题目说明里提到成功条件是输出 verify success.,所以第一步先在 IDA 里看字符串引用。

关键字符串:

Enter your key:verify success.verify fail.retry it... 做 Xrefs,都会落到 _main,主函数地址为:

F5 后能看到主函数中先输出提示,再读取输入:

这里 sub_403C60(Buffer) 很显眼,但不要急着下结论。

sub_403C60 里面引用了大量提示性字符串,例如:

F5 伪代码如下:

继续看 sub_403230

还有 sub_4032E0

这些函数只制造 admin123r3v3rs3!passwordint3 的干扰。真正的 verify success. 分支不依赖这些字符串,而是在 _main 后半段。

回到 _main,输入会先被复制到一个 std::string 风格对象,然后调用 sub_402100

sub_402100 的核心逻辑是把字符串按 16 进制转成大整数:

之后 _main 检查输入字符和长度:

这里 v76 是大整数 DWORD 数量。n = 8 * v76,最终要求:

也就是说:

注册码最后确实是 88 位十六进制字符串。

程序把大整数按 DWORD 倒序拆成字节,放入 ArgList。简化逻辑如下:

所以 88 个 hex 字符会还原成 44 字节。

接着做两个校验。

IDA F5:

-113unsigned char 看就是:

即:

F5:

v58__int16-16641 对应无符号值:

等价 Python:

第一层通过后,程序会进入最终比较逻辑:

也就是说,每个字节不是直接当 ASCII,而是当成一个 1-based 索引:

sub_404870 不是普通连续数组,它通过偏移表取字符:

sub_4033D0 会构造这个表对象:

实际关系:

目标字符串:

前 28 个字符可以直接反查表,得到前 28 字节:

对应注册码前 56 个 hex 字符:

前面还有一个关键点:最终比较前,程序会对输入后 16 字节做一次变换。

调用点:

sub_403500 内部会:

sub_402510 的结构很像快速模幂:

常量来源在 sub_403500 里构造:

通过 IDA 读取对应表,可还原:

目标字符串后 16 个字符是:

反查字符映射表,得到最终比较期望的后 16 字节:

也就是密文:

因为:

所以需要求:

分解 N

计算:

得到输入后 16 字节:

对应注册码后 32 个 hex 字符:

前 28 字节来自字符表直接反查:

后 16 字节来自 RSA-like 逆运算:

拼接:

再验证第一层校验:

输出:

与程序校验一致。

PowerShell:

输出:

Enter your key:
verify success.
verify fail.retry it...
Welcome to KCTF2026! Come and give it a try.
admin123
r3v3rs3!
password
_main = 0x403D90

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

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