首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
CTF对抗
发新帖
0
0
[原创]第七题:戌时·暗能潜流
发表于: 2026-8-21 12:22
41
[原创]第七题:戌时·暗能潜流
F1ux_Team
1
2026-8-21 12:22
41
四组样例的密文长度都是明文长度的四倍:一个明文字节最终对应四个十六进制字符。将密文每 12 个字符分组,正好对应三个明文字节。 先比较所有完整三字节块: ```text TLU -> 94AA48550495 Hel -> 34BB405504B5 202 -> A48844556485 abc -> 547B475584B5 ``` 这些块的第 `1、4、6、7、9、11` 位始终不变,其结构为: ```text q0 4 q1 q2 4 q3 5 5 q4 4 q5 5 ``` 提取位置是: ```text [0, 2, 3, 5, 8, 10] ``` 再比较两个剩余两字节的尾块: ```text lo -> 223594B94C53 d! -> 223564BB4553 ``` 可以得到两字节尾块结构: ```text 2 2 3 5 q0 4 q1 q2 4 q3 5 3 ``` 提取位置是: ```text [4, 6, 7, 9] ``` `2026` 最后的单字节尾块为: ```text 223322356483 ``` 对应结构: ```text 2 2 3 3 2 2 3 5 q0 4 q1 3 ``` 提取位置是: ```text [8, 10] ``` 三类固定结构只是外层包装。去掉包装后,每个明文字节均剩下一对十六进制半字节。 ## 恢复内部变换 从样例中提取出的半字节对如下: ```text TLU -> 9A A8 09 Hello -> 3B B0 0B 9B 9C 2026 -> A8 84 68 68 abcd! -> 57 B7 8B 6B BB ``` 密钥为 `121`。把每个半字节对看成长度为 2 的循环序列:旋转 1 位会交换两个半字节,旋转 2 位则回到原序。因此逆向时按输出位置循环执行: ```text 1 -> 交换 hi、lo 2 -> 保持 hi、lo 1 -> 交换 hi、lo ``` 每三个字节对还存在一次固定位置重排: ```text [0, 2, 1] ``` 该排列是自身的逆排列。还原分组顺序后,再将整个字节对数组逆序。 以 `TLU` 为例,首先从包装中提取: ```text 9A A8 09 ``` 逆密钥 `121`: ```text A9 A8 90 ``` 逆 `[0, 2, 1]` 重排: ```text A9 90 A8 ``` 整体逆序: ```text A8 90 A9 ``` 此时与明文 `54 4C 55` 的关系已经很明显:每个高半字节都增加了 5,每个低半字节都增加了 4,运算均在模 16 下进行。 ```text A8 - (5,4) = 54 = 'T' 90 - (5,4) = 4C = 'L' A9 - (5,4) = 55 = 'U' ``` 用 `Hello` 继续验证。提取结果是: ```text 3B B0 0B 9B 9C ``` 依次逆密钥、逆分组重排、整体逆序后得到: ```text 9C B9 B0 B0 B3 ``` 分别对高、低半字节减去 5 和 4: ```text 48 65 6C 6C 6F -> Hello ``` 其余两组样例也能得到原始明文,说明完整逆变换已经确定。 ## 解密流程 完整解密顺序如下: 1. 每 12 个十六进制字符划分一个外层块; 2. 按完整块、两字节尾块或单字节尾块的位置提取 `q`; 3. 按密钥 `121` 循环交换对应字节对的高、低半字节; 4. 每三个字节对执行 `[0, 2, 1]`; 5. 将整个字节对数组逆序; 6. 高半字节减 5,低半字节减 4,全部按模 16 计算; 7. 合并半字节并按 ASCII 解码。 ## Exp ```python FLAG_CIPHER = ( "14CC4655547594BC475584C5848A43551495448C445584C5D4C9475564C534A84B55A4B574BA4355F495" "A48844556485648C495534A5548C4F5584A5B4BB405554B522332235A4B3" ) FULL_POS = (0, 2, 3, 5, 8, 10) TAIL2_POS = (4, 6, 7, 9) TAIL1_POS = (8, 10) def decrypt(ciphertext): blocks = [ciphertext[i:i + 12] for i in range(0, len(ciphertext), 12)] if blocks[-1].startswith("22332235") and blocks[-1].endswith("3"): tail = 1 elif blocks[-1].startswith("2235") and blocks[-1].endswith("53"): tail = 2 else: tail = 0 q = [] full_blocks = blocks if tail == 0 else blocks[:-1] for raw in full_blocks: q.extend(int(raw[i], 16) for i in FULL_POS) if tail == 2: q.extend(int(blocks[-1][i], 16) for i in TAIL2_POS) elif tail == 1: q.extend(int(blocks[-1][i], 16) for i in TAIL1_POS) ordered = [] for i in range(0, len(q), 2): hi, lo = q[i], q[i + 1] if (1, 2, 1)[(i // 2) % 3] == 1: hi, lo = lo, hi ordered.append((hi, lo)) reversed_pairs = [] for i in range(0, len(ordered), 3): group = ordered[i:i + 3] if len(group) == 3: reversed_pairs.extend((group[0], group[2], group[1])) else: reversed_pairs.extend(group) plain = [] for hi, lo in reversed(reversed_pairs): value = (((hi - 5) & 0xF) << 4) | ((lo - 4) & 0xF) plain.append(value) return bytes(plain) flag = decrypt(FLAG_CIPHER) print(flag.decode()) ```
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
收藏
・
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、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部