首页
社区
课程
招聘
[原创]第七题:戌时·暗能潜流wp
发表于: 2026-8-20 19:09 43

[原创]第七题:戌时·暗能潜流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内核攻防全技术栈,打造具备自动化能力的内核开发高手。

收藏
点赞 ・0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回