-
-
[原创]KCTF 2026 - Rosetta Calibration Writeup
-
发表于: 2天前 111
-
题目名称:Rosetta Calibration
类型:Reverse / Keygen
文件:kctf_rosetta.exe (PE32+ x86-64, 3 sections)
已知:一组有效对 Name: CAAA1C964B15D9B3, Serial: $/.;-):,(-#!%*-&?+@
目标:求 Name 为 KCTF 时的 Serial
运行程序,输出如下:
程序先提示输入 Name,再提示输入 Serial,验证后给出通过或拒绝的反馈。
用 strings 提取关键字符串:
程序从 stdin 逐字节读取 Name,存入 rsp+0x80,长度存入 rbx。
校验逻辑(0x14000123E–0x140001286):
结论:Name 长度 1–32,每个字符必须在 0x21–0x7E(可打印 ASCII)范围内。
Serial 逐字节读入 rsp+0x50,长度存入 r12。
Serial 中每个非 - 字符通过函数 0x140001520 映射为 0–15 的值。该函数内部调用 0x140001540:
从 .rdata 段 0x140002000 处提取 32 项 int32 查找表(0xFFFFFFFF 表示无效):
注意:( 查表得 3,但 map_char 中 XOR 1 修正为 2。
整理出的 值→字符 反向映射:
0x4210 = 0100 0010 0001 0000 二进制,置位的位置为 4、9、14。
所以 Serial 格式为:VVVV-VVVVV-VVVVV-VV(19 字符,第 4/9/14 位为 -)。
16 个非 - 字符映射后必须恰好覆盖 0–15 各一次。
核心函数位于 0x1400013e0,签名:
逐字节处理 Name:
从置换后的 S-box 中按累加器偏移提取 16 字节:
用 SSE pcmpeqb + pmovmskb 做 16 字节批量比较,全部匹配才通过。
用已知对 Name: CAAA1C964B15D9B3, Serial: $/.;-):,(-#!%*-&?+@ 验证逻辑:
用 Name "CAAA1C964B15D9B3" 执行派生函数,输出恰好为 [12,10,8,5,11,15,13,2,7,4,1,14,9,0,6,3],与 Serial 映射结果一致
对 Name "KCTF" 执行密钥派生:
逐步执行 S-box 置换:
累加器 accum = 0x129,accum & 0xf = 9。
从 S-box 中提取输出:
计算结果:
将值反查字符表,并在位置 4/9/14 插入 -:
本题是一道典型的 Keygen 类型逆向题,核心考点:
自定义字符编码:16 个特殊符号与 0–15 的双射映射,( 的 XOR 修正增加了一点混淆
Serial 格式约束:19 字符、固定破折号位置、值 0–15 各出现一次(类似 16 进制 UUID 的思路)
密钥派生算法:类 RC4 的 S-box 置换 + 累加器偏移提取,但 S-box 只有 16 字节且索引计算中混入了 r9 递增计数器
SSE 批量比较:用 pcmpeqb + pmovmskb 做 16 字节一次性比较,属于常见的反调试/优化手法
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。