首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
CTF对抗
发新帖
0
0
[原创]第七题:戌时·暗能潜流wp
发表于: 2026-8-20 19:09
28
[原创]第七题:戌时·暗能潜流wp
viper333
2026-8-20 19:09
28
# Writeup ## 题目信息 题目提供了 4 组已知明文/密文: ```text TLU -> 94AA48550495 Hello -> 34BB405504B5223594B94C53 2026 -> A48844556485223322356483 abcd! -> 547B475584B5223564BB4553 ``` 以及待解密文: ```text 14CC4655547594BC475584C5848A43551495448C445584C5D4C9475564C534A84B55A4B574BA4355F495A48844556485648C495534A5548C4F5584A5B4BB405554B522332235A4B3 ``` 题目还提示摘要扰动只与输入长度有关,因此长度相同的 `Hello` 和 `abcd!` 可以用来消除扰动并寻找真正的数据位置。 ## 1. 确定分块方式 观察密文长度: ```text TLU 3 字符 -> 12 个十六进制字符 Hello 5 字符 -> 24 个十六进制字符 2026 4 字符 -> 24 个十六进制字符 abcd! 5 字符 -> 24 个十六进制字符 ``` 可以判断: - 每 3 个明文字符对应一个 12 位密文块; - 块数为 `ceil(len(plaintext) / 3)`; - 明文从右向左分块,密文块的顺序也被反转; - 开头不足 3 个字符的残块被放在密文末尾。 例如: ```text Hello = He | llo ``` 因此密文为: ```text encode(llo) | encode(He) ``` 确实对应: ```text 34BB405504B5 | 223594B94C53 ``` ## 2. 半字节循环偏移 把一个字节写成两个十六进制半字节: ```text byte = (high, low) ``` 结合所有已知样本,可以反推出与密钥及位运算层等价的变换: ```text high' = (high + 5) mod 16 low' = (low + 4) mod 16 ``` 逆变换则是: ```text high = (high' - 5) mod 16 low = (low' - 4) mod 16 ``` 例如字符 `T`: ```text 'T' = 0x54 high' = 5 + 5 = A low' = 4 + 4 = 8 ``` 所以 `T` 经过半字节偏移后得到 `A8`。 在等价解密中不需要再次使用数字 `121`,因为它所产生的固定效果已经包含在 `+5/+4` 及后面的固定排列中。 ## 3. 完整三字符块的排列 设三个字符经过半字节偏移后依次为: ```text (a,b), (c,d), (e,f) ``` 12 位输出块的排列为: ```text f 4 e a 4 b 5 5 d 4 c 5 ``` 其中真正携带数据的位置是: ```text 1, 3, 4, 6, 9, 11 ``` 其余位置为固定扰动: ```text 4, 4, 5, 5, 4, 5 ``` 所以从一个完整密文块 `x[1..12]` 中恢复三个字符时: ```text a = x4 b = x6 c = x11 d = x9 e = x3 f = x1 ``` 然后分别执行半字节逆偏移。 以 `TLU` 为例: ```text T -> A8 L -> 90 U -> A9 ``` 于是: ```text (a,b,c,d,e,f) = (A,8,9,0,A,9) ``` 代入排列: ```text f 4 e a 4 b 5 5 d 4 c 5 9 4 A A 4 8 5 5 0 4 9 5 ``` 正好得到: ```text 94AA48550495 ``` 说明规律正确。 ## 4. 解出 FLAG 各块 将目标密文每 12 位分块: |密文块|解密结果| |---|---| |`14CC46555475`|`r!}`| |`94BC475584C5`|`ste`| |`848A43551495`|`_M4`| |`448C445584C5`|`pt0`| |`D4C9475564C5`|`Cry`| |`34A84B55A4B5`|`7f_`| |`74BA4355F495`|`_Kc`| |`A48844556485`|`026`| |`648C495534A5`|`u_2`| |`548C4F5584A5`|`{T1`| |`B4BB405554B5`|`lag`| |`22332235A4B3`|`f`| 最后一块是只有一个字符的残块。该类残块的数据位是: ```text low' = x9 high' = x11 ``` 对于: ```text 22332235A4B3 ``` 得到: ```text high' = B low' = A ``` 逆偏移: ```text high = B - 5 = 6 low = A - 4 = 6 ``` 所以原字节为: ```text 0x66 = 'f' ``` 由于密文块顺序与明文块顺序相反,需要从最后一块向前拼接: ```text f + lag + {T1 + u_2 + 026 + _Kc + 7f_ + Cry + pt0 + _M4 + ste + r!} ``` 最终得到: ```text flag{T1u_2026_Kc7f_Crypt0_M4ster!} ``` ## 5. 解题脚本 ```python ciphertext = ( "14CC4655547594BC475584C5848A4355" "1495448C445584C5D4C9475564C534A8" "4B55A4B574BA4355F495A48844556485" "648C495534A5548C4F5584A5B4BB4055" "54B522332235A4B3" ) def restore_byte(high_shifted, low_shifted): high = (high_shifted - 5) % 16 low = (low_shifted - 4) % 16 return chr((high << 4) | low) def decrypt_full_block(block): x = [int(c, 16) for c in block] # 1-based: # a=x4, b=x6, c=x11, d=x9, e=x3, f=x1 char1 = restore_byte(x[3], x[5]) char2 = restore_byte(x[10], x[8]) char3 = restore_byte(x[2], x[0]) return char1 + char2 + char3 def decrypt_one_char_block(block): x = [int(c, 16) for c in block] # high'=x11, low'=x9 return restore_byte(x[10], x[8]) blocks = [ ciphertext[i:i + 12] for i in range(0, len(ciphertext), 12) ] # 最后一块是明文开头的单字符残块 flag = decrypt_one_char_block(blocks[-1]) # 其余完整块需要逆序处理 for block in reversed(blocks[:-1]): flag += decrypt_full_block(block) print(flag) ``` 运行结果: ```text flag{T1u_2026_Kc7f_Crypt0_M4ster!} ```
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
收藏
・
0
点赞
・
0
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
viper333
3
发帖
2
回帖
10
RANK
关注
私信
他的文章
[原创]第七题:戌时·暗能潜流wp
28
[分享]KCTF 2026 Reverse:巳时·绿光幽语
89
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部