
题目给出了一个名为 HexMaze 的确定性字符串变换算法。
已知条件:
已知明文 / 密文:
目标密文:
目标:恢复 FLAG。
这道题真正耗时间的部分并不是最后的逆运算,而是确定“哪些十六进制位属于数据,哪些属于扰动,以及数据到底经过了什么顺序的重排”。
本次分析记录中的总推理时间约为:
大致可以复盘为:
所以这题的突破点其实比较靠后。
首先看最简单的一组:
TLU 是 3 个 ASCII 字符,也就是:
但是密文却有:
长度恰好翻倍。
一开始很自然会猜:
每个明文字节是不是被变成了两个密文字节?
于是我最开始尝试按照:
这种方式拆。
但很快发现不对。
因为对 Hello、abcd! 做相同位置比较时,相同字符位置的输出没有形成简单的逐字节映射。
因此第一版假设:
失败。
密钥是:
首先自然想到十进制:
于是尝试过一些比较常见的构造:
甚至继续测试了:
以及各种简单组合。
例如:
这些结果和:
都没有直接对应关系。
这一阶段花了比较多时间,因为题目明确写了:
十六进制位运算
很容易让人过度关注 0x79。
后来才意识到:
真正重要的不是直接拿 ASCII 字节和 121 做一次运算,而是先把结果降到 4 bit 半字节层面观察。
重新观察:
拆成半字节:
能明显看到:
出现得非常规律。
再观察其它样本的某些完整块,也能看到类似结构。
于是开始怀疑:
输出的 12 个半字节并不全部是明文数据,其中一部分是固定扰动。
对第一组完整结构进一步比较后,发现可以抽出:
即:
而其余位置形成非常明显的固定骨架:
也就是:
至此有了一个非常重要的判断:
一个完整块中的 12 个半字节,只有 6 个半字节真正携带数据。
而:
刚好对应 3 个 ASCII 字符。
这也解释了为什么 TLU 恰好对应一个 12-nibble 块。
发现:
之后,我一度认为已经解决了大部分问题,于是直接对:
的所有 12 位分组都套这个位置。
结果并没有全部恢复出可读 ASCII。
例如 Hello 的第二段和 2026 的尾段就明显不符合完整块模式。
这说明:
和:
必须分开分析。
这个地方其实正好对应题目的提示:
摘要扰动过程只与输入长度有关。
也就是说,长度不是无关信息。
反而是破解尾块的关键。
Hello 与 abcd! 都是:
因此如果摘要扰动:
那么它们的长度相关部分应该一致。
所以我开始重点比较:
而不是把所有四组样本混在一起。
这是第二个比较重要的转折。
通过同长度样本比较,可以发现:
由此基本确认:
摘要扰动只是穿插在数据中的固定结构,而不是类似 hash 那样把所有明文重新混合。
因此整个算法仍然高度可逆。
接下来重新计算 ASCII。
以:
为例:
拆成高低半字节:
然后去寻找一个非常简单的模 16 偏移。
最终发现:
可以得到:
所以:
经过模 16 偏移之后得到:
即:
这个结果非常关键。
因为密文中真正的数据半字节恰好也是:
只是顺序完全不同。
也就是说:
数值变换已经找到了,剩下的问题只是 permutation。
TLU 偏移后的半字节流:
发现算法先把整体顺序反转:
记:
而从密文:
抽取真实数据位置:
得到:
于是可以推出:
即固定排列:
反向解密:
即:
到这里已经基本恢复了完整块的逆算法。
加密方向:
ASCII:
模 16 偏移:
半字节:
整体逆序:
固定排列:
插入固定扰动:
得到:
与题目完全一致。
这一刻基本可以确认:
的方向是正确的。
FLAG:
每 12 个半字节切分:
由于之前已经确定:
所以真正恢复明文时,应先从后面的完整块开始。
暂时跳过最后的长度扰动块 12。
从 Block 11 开始向前解。
完整块的解密流程:
得到:
拼起来:
到这里其实已经很明显:
只缺最开头:
但不能直接靠 FLAG 格式猜。
还需要把最后的长度扰动块逆出来。
FLAG 最后的特殊块:
无法直接使用完整块:
的结构。
这正是前面曾经导致解码失败的地方。
此时利用题目最关键的提示:
摘要扰动过程只与输入长度有关。
我们需要找一个已知样本,它的尾部形态与 FLAG 相同。
观察:
长度为 4。
由于完整块每次可以承载:
那么 2026 在整体逆序以后同样会出现:
它的密文:
拆成:
其中:
解出来正好是:
所以特殊尾块:
必然携带最前面的字符:
已知 2026:
FLAG:
排在一起:
可以看到:
完全相同。
末尾:
也保持不变。
真正变化的只有:
这两个位置正好可以存储一个 ASCII 字节的两个半字节。
2026 中需要恢复的首字符:
ASCII:
高低半字节:
按照已经得到的模 16 变换:
因此:
尾块中恰好出现:
即数据位置是:
说明尾块同样受到整体逆序影响。
FLAG 尾块:
抽取:
逆向模 16 偏移:
所以原字节:
ASCII:
于是完整明文为:
得到:
最后把规律写成脚本验证。
输出:
仅仅得到一个看起来像 FLAG 的字符串还不够。
为了避免因为:
格式产生误判,还需要把最终明文重新按推导出的规则进行正向验证。
恢复出的字符串长度:
完整块:
剩余:
这与密文结构:
完全对应。
同时用逆向规则测试题目提供的四组样例:
均能恢复出原始明文。
因此不是单纯通过 FLAG 格式猜测,而是算法结构和全部已知样本都能够闭环验证。
这题最大的坑是信息量其实非常有限:
但是可能的组合却很多。
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
最后于 16小时前
被shuax编辑
,原因: