首页
社区
课程
招聘
[原创]第七题:戌时·暗能潜流(AI解析)
发表于: 2026-8-20 14:41 9

[原创]第七题:戌时·暗能潜流(AI解析)

2026-8-20 14:41
9

[KCTF] HexMaze 题解:密钥织墙、长度摘要与两层重排

题型:Crypto / Misc 边界题
密钥:121
Flag:flag{T1u_2026_Kc7f_Crypt0_M4ster!}


0. 题面在说什么

题目给出 4 组明文–密文样例和一个 FLAG 密文,算法声明大致是:

  • 只用字节编码、十六进制位运算、模 16 循环偏移固定位置重排固定摘要扰动
  • 无随机数 / IV / 外部状态
  • 摘要扰动过程只与输入长度有关
  • 需要在 WP 里说明密钥 121 每一位的作用

输出是 0-9A-F,看起来像「把数据塞进十六进制迷宫里」。这题的味道很 Misc:骨架靠观察,核心靠猜对几个小构造,而不是硬刚 AES/RSA。

样例:

明文 密文
TLU 94AA48550495
Hello 34BB405504B5223594B94C53
2026 A48844556485223322356483
abcd! 547B475584B5223564BB4553

FLAG 密文长度 144 hex = 12 段 × 12。


1. 第一步:长度律与分块

观察密文长度:

  • TLU(3 字节)→ 12 hex
  • Hello / abcd!(5 字节)→ 24 hex
  • 2026(4 字节)→ 24 hex

规律很明确:按 3 字节一组切块,每块膨胀成 12 个 hex 字符;余 1 / 余 2 字节走另一套「尾块」模板。

于是:

  • 完整 3 字节主块:墙位固定
  • 余 2(如 Hellolo):另一种骨架
  • 余 1(如 20266):再一种骨架

FLAG 144 hex → 11 个主块 + 1 个 1 字节尾块 → 明文长度 34


2. 第二步:看见「墙」——密钥 121 的第一层作用

把主块 12 个半字节对齐看(以 TLU 为例):

位置: 0 1 2 3 4 5 6 7 8 9 10 11
TLU : 9 4 A A 4 8 5 5 0 4  9  5

所有主块在位置 1,4,6,7,9,11永远是

4 4 5 5 4 5

也就是骨架:

? 4 ? ? 4 ? 5 5 ? 4 ? 5

这和密钥 121 对得太齐了:

  • 数字 d → 墙半字节 d + 3
    • 1 → 42 → 5
  • 按密钥展开成主块墙序列 445545

所以密钥的数值决定墙的颜色(4/5),排列决定墙插在哪(迷宫骨架)。
数据只占自由位:0,2,3,5,8,10 —— 正好 6 个半字节 = 3 字节,和明文半字节数一致。

尾块同理,只是墙型不同:

余数 骨架(示意) 自由位
2 2235?4??4?53 4 个半字节
1 22332235X4Y3 2 个半字节

抽出自由位后,密文就退化成与明文等长的半字节流,后面的变换都作用在这条流上。


3. 第三步:长度摘要 —— 题面最大的提示

提示:摘要扰动只与长度有关

同长度样例 Helloabcd! 可做差分:摘要项相消,用来钉重排;不同长度样例用来钉摘要本身。

最终摘要是一条只依赖长度的半字节串:把周期

4 5 5 4 4 5

重复展开到 n = 2 × len(明文),再与数据流做 mod 16 加法

对照:

长度 L 摘要(前 2L 个半字节)
3 455445
4 45544545
5 4554454554

455445 与主块墙 445545 同源,都来自密钥 121 的 4/5 墙色,只是排法不同。
这正是「固定摘要 + 只跟长度有关」:内容不进摘要,长度只决定展开多长。


4. 第四步:模长循环偏移 + 块内重排

去掉摘要之后,半字节流与明文半字节之间还差两步。

4.1 循环偏移

对长度为 n 的半字节数组做循环移位:

rol(stream, 6 % n)
  • n=6(3 字节)→ 6%6=0,不转
  • n=8,10,... → 转 6 格(等价于字节层面转 3 字节)

这对应题面里的「模 16 / 循环偏移」在变长数组上的落地:偏移常量 6,再对当前长度取模。

4.2 固定位置重排(半字节块)

按「每 3 明文字节 → 6 半字节」切段,段内置换:

段长 置换 字节语义
6 P6 = (5,4,0,1,3,2) (A,B,C) → (swap(C), A, swap(B))
4(余 2) P4 = (3,2,0,1) (A,B) → (swap(B), A)
2(余 1) P2 = (1,0) A → swap(A)

swap = 字节高低半字节对调。

主块三字节的几何图像很「迷宫」:最后一个字节翻过来放到最前,中间字节原样,中间那个字节再翻过来垫后——像在格子里换位。


5. 第五步:外层重排(样例上看不见的坑)

按上面管道解密 FLAG,会得到一串可读乱码:

ste_M4pt0Cry7f__Kc026u_2{T1lagfr!}

它能完美回编成 FLAG 密文,但不是 flag{...}
原因是:还有一层固定位置重排,在 3/4/5 字节样例上恰好是恒等,只有更长明文才暴露。

定义(L = len):

  1. rem = pt[: L%3],其余按 3 字节分块后整块逆序,再把 rem 接到末尾 → rb2(pt)
  2. 再整体 左旋 3 字节 → 得到进入「半字节管道」的中间串

解密时做逆变换。对 FLAG:

中间串  --F-->  flag{T1u_2026_Kc7f_Crypt0_M4ster!}

这层解释了题面强调的「固定位置重排」为何在短样例上几乎无感:余数结构让 F 在样例长度上退化成恒等,属于典型 Misc 假进度陷阱。


6. 完整加密流程(汇总)

对明文 pt

1. mid  = Finv(pt)          # rb2 后左旋 3 字节(样例上常为恒等)
2. x    = 半字节展开(mid)
3. x    = rol(x, 6 % len(x))
4. x    = 分块重排(x)       # P6 / P4 / P2
5. x[i] = (x[i] + Dig[i]) mod 16
         Dig = (455445) 重复到 len(x)
6. CT   = 按密钥墙型织入 x 的自由位

解密逆序即可。FLAG 长度 34,解得:

flag{T1u_2026_Kc7f_Crypt0_M4ster!}

回编与题目 FLAG 密文一致。


7. 密钥 121 各数字作用(WP 必写)

要素 作用
数字 1 / 2 墙半字节 = 值 +34 / 5
数字 顺序 1,2,1 展开主块墙序列 445545,决定骨架 ?4??4?55?4?5
由墙色派生 长度摘要周期 455445(与墙同色不同排)
与「3」相关的节奏 明文按 3 字节分块织墙;半字节偏移常量 6(=2×3);外层也按 3 字节块重排

一句话:121 不是加密密钥流,而是迷宫图纸——决定墙刷什么色、插在哪,并派生出只跟长度走的摘要条纹。


8. 解题路径回顾(踩坑与转折)

  1. 先看骨架再谈密码:主块墙恒为 445545,立刻绑定 121
  2. 自由位长度 = 明文半字节数:排除「每位密钥扩成不等长编码」等过度假设。
  3. 同长度差分钉住「摘要与内容无关」;跨长度钉住 455445 周期。
  4. 短样例过拟合:只有核心管道时 FLAG 回编成功但不是 flag{...}——说明还有样例上恒等的外层重排。
  5. 验证标准:样例加解密 + FLAG 回编 + flag{...} 形态,三线同时满足才收工。

这题像 Misc 的原因也在这里:真正难点不是大数分解,而是分清「墙 / 数据 / 长度摘要 / 两层重排」各自的自由度,并用样例长度故意藏起其中一层。


9. 小结

HexMaze = 密钥织墙的十六进制迷宫 + 长度唯一确定的条纹摘要 + 半字节循环偏移与块内换位 + 对短串隐形的外层块重排

Flag:

flag{T1u_2026_Kc7f_Crypt0_M4ster!}

附:完整可运行求解脚本见同目录 hexmaze_solver.py


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

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