首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
CTF对抗
发新帖
0
0
[原创]第八题:亥子合辰·塔影迷楼 Writeup
发表于: 2026-8-21 12:24
8
[原创]第八题:亥子合辰·塔影迷楼 Writeup
F1ux_Team
1
2026-8-21 12:24
8
# 第八题:亥子合辰·塔影迷楼 ## 基本信息 附件中的程序是 64 位 Windows PE,SHA-256 为: ```text b0dae7a21b059805a35fc5490f84a607d00afb28ad6b5b9f9ebc31574c382ea1 ``` 程序只接受 16 字节输入。导入表很小,文件读写、进程退出和时间查询均通过解析 `ntdll` 中的系统调用号后直接执行 `syscall`。 ## 两层代码解密 入口首先读取 `.tgt` 中的偏移和长度,得到第一层区域: ```text RVA = 0x1800 size = 0x510 ``` 程序将该区域改成可写权限,每个字节异或 `0x5A`,刷新指令缓存后进入 `0x1400018D0`。 第一层代码对自身计算两组 FNV 风格的 64 位哈希。两个初值分别为 `0xCBF29CE484222325` 和 `0x9E3779B97F4A7C15`,乘数均为 `0x100000001B3`,最终结果为: ```text h0 = 0x73FB4F498AAB364F h1 = 0xB157C7E044B966DF ``` 随后解密第二层区域: ```text RVA = 0x1D10 size = 0x4962 ``` 标量路径可以写成: ```python MASK = (1 << 64) - 1 G = 0x9E3779B97F4A7C15 M = 0xFF51AFD7ED558CCD for i in range(0x4962): t = h0 ^ h1 ^ ((G * i) & MASK) t ^= t >> 33 key = ((M * t) & MASK) >> 56 code[i] ^= key ``` 程序还包含向量化实现,两条路径生成的密钥流相同。解密后,核心校验函数位于 `0x140004380`。 ## 反调试和上下文生成 核心函数先检查以下状态: - PEB 的 `BeingDebugged` 和 `NtGlobalFlag`; - `Dr0` 至 `Dr3`、`Dr7` 硬件断点寄存器; - `ProcessDebugPort` 与 `ProcessDebugObjectHandle`; - 扫描代码段前后的 `RDTSC` 差值。 这些状态合并成一个掩码。正常运行时掩码为 0。核心代码再次对已解密的第二层区域计算哈希,得到: ```text hash_golden = 0x4AEEE52B5738EB8F hash_fnv = 0x553D3C5EF6EE11FF ``` 两个哈希与反调试掩码进入 SplitMix64 风格的生成器,循环 43 次,产生 86 个 64 位字。后续数据全部来自这组确定性上下文: - 第 0 至 9 个字组成五个素域多项式系数; - 第 10、11 个字组成轮函数乘数; - 第 12 至 43 个字组成 256 字节替换表; - 第 44 至 83 个字组成两组各 20 个轮密钥; - 最后两个字用于解开目标值和最终哈希。 ## 素域与输入编码 所有 128 位运算都在以下素域中进行: ```text p = 2^127 - 39 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFD9 ``` 输入首先满足字节和检查: ```text sum(input[0:16]) = 0x500 ``` 随后把可打印字符按 94 进制编码: ```python x = 0 for ch in input_bytes: x = (x * 94 + ch - 33) % p ``` 字符范围为 `0x21` 至 `0x7E`,所以每一位正好落在 0 至 93。`94^16` 小于 `p`,最终可以直接用 94 进制无歧义还原。 五个上下文字段记作 `c0` 至 `c4`。核心函数用 Horner 形式计算: ```text y = (((((x + c0)·x + c1)·x + c2)·x + c3)·x + c4) mod p ``` ## 简化 20 轮变换 反编译结果将 128 位乘法和模约减完全展开,主体超过两千条指令。把重复片段合并后,每轮是两次 Feistel 更新。 设 `C` 为上下文生成的 128 位乘数,`S` 为逐字节替换表,定义: ```text t = (((A << 64) | k) · C) mod p z = low64(t) XOR k XOR ROR64(high64(t), 47) F(A, k) = S(z) XOR ROR64(z, 51) ``` 单轮正向运算为: ```text A' = B XOR F(A, k) B' = A XOR F(A', k XOR 0x9E3779B97F4A7C15) ``` 因此可以直接逆运算: ```text A = B' XOR F(A', k XOR 0x9E3779B97F4A7C15) B = A' XOR F(A, k) ``` 两组 20 轮使用不同轮密钥和不同交替哈希,初始输入都是多项式结果 `y`。解开上下文掩码后的两个目标分别为: ```text target1 = 0x0C14DB1C20DD97A8B8FD0694401D3D03 target2 = 0x9A2789B6DE31C2DCACA5240A53FB78A6 ``` 分别逆转两组 20 轮,独立得到相同结果: ```text y = 0x4BE831B0AD3A2D361489375BBA3FB8DE ``` ## 五次多项式求根 将 Horner 表达式展开后得到有限域上的五次多项式: ```text f(X) = X^5 + c0·X^4 + c1·X^3 + c2·X^2 + c3·X + c4 - y ``` 先计算: ```text gcd(f(X), X^p - X) ``` 这样可以保留 `F_p` 中的一次因子,再用 Cantor-Zassenhaus 方法确定性拆分。多项式只有一个域内根: ```text x = 0x174A5E1D4CF4F146E72F70092AC ``` 把 `x` 连续除以 94,取 16 个余数并各加 33,得到: ```text kanxue@2o26o8!@# ``` 该字符串满足全部条件:字节和为 `0x500`,多项式结果正确,两组 20 轮输出正确,两组最终 FNV 校验正确。原程序输出 `correct`。 ## Flag ```text kanxue@2o26o8!@# ```
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
上传的附件:
solve.py
(9.35kb,2次下载)
收藏
・
0
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
F1ux_Team
1
10
发帖
0
回帖
70
RANK
关注
私信
他的文章
[原创] 第十题:卯时·曦光初现
325
[原创] 第九题:丑寅同墟·星海抉择 Writeup
18
[原创]第五题 申时·忆海倒带 Writeup
834
[原创]第六题:酉时·书院迷局 Writeup
587
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
谁下载
×
huangyalei
pzhxbz
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部