首页
社区
课程
招聘
[原创]KCTF2026 第9题 ICTFForCausalLM 模型逆向 WriteUp
发表于: 2026-8-22 12:18 20

[原创]KCTF2026 第9题 ICTFForCausalLM 模型逆向 WriteUp

2026-8-22 12:18
20

ICTFForCausalLM 模型逆向 WriteUp

【题目概述】
附件是一个字符级因果语言模型 ICTFForCausalLM(MLP)及其权重。
模型输入不超过 16 个字符的字符串,输出一个预测字符(id 62 为
<success>,id 63 为 <fail>)。目标是恢复能令模型输出 <success>
的真实 flag。

【代码关键】
model_def.py: dense = Linear(16, 21); act=ReLU; lm_head=Linear(21,64)
输入 input_ids 直接转 float 作为 x,无 embedding。
tokenizer 字符集: 0-9 a-z A-Z(62 个字符),补零到 16。
inference.py: 取最后位置 logits 的 argmax 作为预测字符。

【权重逆向(手工解析 safetensors)】
用纯 Python 解析 model.safetensors 明文格式,得到 4 个张量:
dense.weight [21,16] -> W1
dense.bias [21] -> b1
lm_head.weight[64,21] -> W2
lm_head.bias [64] -> b2
前向: h = ReLU(W1x + b1); logits = W2h + b2。

观察权重的强结构特征:

  1. b2[i] = -10000 对所有 i != 62,63;b2[62]=-376131;b2[63]=0.4
    -> 除 success/fail 外所有输出 logits 恒为 -10000,永不成为最大值。
  2. W2[62] = [1, -1e10, -1e10, ..., -1e10];W2[63] 及其余行全 0
    -> logits[62] = h[0] - 1e10 * sum(h[1..20]) - 376131
    因为 h[j]>=0,只要任一 j>=1 的隐藏单元 >0,logits[62] 立即跌到
    约 -3.5e14,必然失败。
  3. 结论: 成功 当且仅当 h[1..20] 全部 == 0 且 h[0] > 376131.4。
    等价于(记 row = W1 的行,b = b1):
    对全部 j=1..20: row_j*x + b1[j] <= 0 (trap 隐藏单元关闭)
    且 row_0*x > 64572.68 (h[0] 拉高)
    其中 x 为 16 个 token,取值 {0..61}。

【整数线性规划求解】
用 scipy.optimize.milp 求解:
变量 x ∈ {0..61}^16(取整)
目标 最大化 row_0x
约束 row_j
x <= -b1[j] (j=1..20)
row_0*x >= 64573
求得唯一可行整数解:
x = [15,1,10,16,2,0,2,6,12,7,15,10,1,6,6,6]

再对每一位在 {0..61} 内逐位可行性探测,结果每一位都只有唯一可用
token(改变任一位都会开启 trap 单元导致失败),因此解是唯一的,
即作者植入的真实 flag。

【结果】
按字符集 0..61 解码得到明文:
f1ag2026c7fa1666

【验证】
用与 inference.py 完全一致的前向复算:
输入 "f1ag2026c7fa1666"
h[0] = 376131.7, 其余 h[j] = 0
logits[62] = 0.50 > logits[63] = 0.4 (> 其他 -10000)
argmax = 62 -> 输出 <success> ✅
改动任意一位字符均输出 <fail>,与唯一性一致。

最终 flag: f1ag2026c7fa1666


传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

最后于 2026-8-23 12:03 被kanxue编辑 ,原因:
收藏
免费 0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回