-
-
[原创]第七题:戌时·暗能潜流wp
-
发表于: 2026-8-20 19:09 43
-
Writeup
题目信息
题目提供了 4 组已知明文/密文:
TLU -> 94AA48550495
Hello -> 34BB405504B5223594B94C53
2026 -> A48844556485223322356483
abcd! -> 547B475584B5223564BB4553
以及待解密文:
14CC4655547594BC475584C5848A43551495448C445584C5D4C9475564C534A84B55A4B574BA4355F495A48844556485648C495534A5548C4F5584A5B4BB405554B522332235A4B3
题目还提示摘要扰动只与输入长度有关,因此长度相同的 Hello 和 abcd! 可以用来消除扰动并寻找真正的数据位置。
1. 确定分块方式
观察密文长度:
TLU 3 字符 -> 12 个十六进制字符
Hello 5 字符 -> 24 个十六进制字符
2026 4 字符 -> 24 个十六进制字符
abcd! 5 字符 -> 24 个十六进制字符
可以判断:
每 3 个明文字符对应一个 12 位密文块;
块数为
ceil(len(plaintext) / 3);明文从右向左分块,密文块的顺序也被反转;
开头不足 3 个字符的残块被放在密文末尾。
例如:
Hello = He | llo
因此密文为:
encode(llo) | encode(He)
确实对应:
34BB405504B5 | 223594B94C53
2. 半字节循环偏移
把一个字节写成两个十六进制半字节:
byte = (high, low)
结合所有已知样本,可以反推出与密钥及位运算层等价的变换:
high' = (high + 5) mod 16
low' = (low + 4) mod 16
逆变换则是:
high = (high' - 5) mod 16
low = (low' - 4) mod 16
例如字符 T:
'T' = 0x54
high' = 5 + 5 = A
low' = 4 + 4 = 8
所以 T 经过半字节偏移后得到 A8。
在等价解密中不需要再次使用数字 121,因为它所产生的固定效果已经包含在 +5/+4 及后面的固定排列中。
3. 完整三字符块的排列
设三个字符经过半字节偏移后依次为:
(a,b), (c,d), (e,f)
12 位输出块的排列为:
f 4 e a 4 b 5 5 d 4 c 5
其中真正携带数据的位置是:
1, 3, 4, 6, 9, 11
其余位置为固定扰动:
4, 4, 5, 5, 4, 5
所以从一个完整密文块 x[1..12] 中恢复三个字符时:
a = x4
b = x6
c = x11
d = x9
e = x3
f = x1
然后分别执行半字节逆偏移。
以 TLU 为例:
T -> A8
L -> 90
U -> A9
于是:
(a,b,c,d,e,f) = (A,8,9,0,A,9)
代入排列:
f 4 e a 4 b 5 5 d 4 c 5
9 4 A A 4 8 5 5 0 4 9 5
正好得到:
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 |
最后一块是只有一个字符的残块。该类残块的数据位是:
low' = x9
high' = x11
对于:
22332235A4B3
得到:
high' = B
low' = A
逆偏移:
high = B - 5 = 6
low = A - 4 = 6
所以原字节为:
0x66 = 'f'
由于密文块顺序与明文块顺序相反,需要从最后一块向前拼接:
f
+ lag
+ {T1
+ u_2
+ 026
+ _Kc
+ 7f_
+ Cry
+ pt0
+ _M4
+ ste
+ r!}
最终得到:
flag{T1u_2026_Kc7f_Crypt0_M4ster!}
5. 解题脚本
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)
运行结果:
flag{T1u_2026_Kc7f_Crypt0_M4ster!}
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
赞赏
他的文章
赞赏
雪币:
留言: