Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
claude-awm — 通过注入 Unicode 变体选择符来规避 LLM 文本水印;包含 SynthID 生成器、mean-g 检测器、归一化防御和熵实验。 | Kitploit
工具/GitHubGitHub/aloshdenny/claude-awm
隐写术隐私保护机器学习AI 安全对抗性攻击
GitHubaloshdenny/claude-awm

claude-awm

通过注入 Unicode 变体选择符来规避 LLM 文本水印;包含 SynthID 生成器、mean-g 检测器、归一化防御和熵实验。

查看仓库
899821个月前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

claude-awm:你能通过编辑文本抹除 SynthID 文本水印吗?

the dream, allegedly

能,但只有一类攻击有效,而且并不是大家通常以为的那一类。

Unicode 变体选择符(Mn 类别,U+FE00 至 U+FE0F 以及 U+E0100 至 U+E01EF)能将检测器压到阈值以下,并且保持在该水平。我尝试过的其他所有不可见字符攻击,都会被一行输入归一化完全还原。变体选择符则不会,因为它们是有意义的码点(emoji 呈现形式、CJK 变体),NFKC 不会也不应该将它们折叠掉。

跨模型、跨领域复现结果:

模型领域基线 z应用 vs16_30 后编辑率
gpt-oss-20b散文45.030.7257%
gpt-oss-20b代码37.240.6858%
Qwen3.8-27B散文35.50-0.6757%

阈值为 z = 2.33。三者均在攻击后降至阈值以下,且在归一化后仍保持在阈值以下(分别为 0.09、0.45、-0.78)。文本对人类读者而言渲染结果完全相同。

第二个真正重要的发现完全不需要任何攻击:低熵文本从一开始就几乎没有被水印标记。 在关闭思考模式的情况下,Qwen3.8-27B 的纯代码输出在未受攻击时得分为 z = 4.31,在未做任何处理的情况下已接近 2.33 的阈值。重新开启思考模式后,同一模型、同一领域、同一长度达到 z = 25.53,因为推理前言是普通散文,会正常携带水印标记。

测试的模型

本仓库中的所有内容均在这些模型上测量,除此之外没有别的:

模型参数量运行位置运行内容
Qwen3.5-0.8B0.8BMac (MPS)完整攻击阶梯,1k-8k
Qwen3.5-4B4BMac / 4090完整攻击阶梯 + 熵实验 + 隐写原始/归一化
DeepSeek-R1-Distill-Qwen-14B14BMac (MLX, 4-bit)水印 + 检测,推理轨迹
gpt-oss-20b20B3090 / 4090 / RunPod完整攻击阶梯至 32k,散文 + 代码,变体选择符,插入率缩放律至 131k
Qwen3.8-27B27BRunPod H100 / Modal H100散文 + 代码,变体选择符,思考模式对比
gpt-oss-120b120BModal H100 (MXFP4) / RunPod H100散文 + 代码 + 推理,2k / 8k / 32k,部分插入率缩放至 65k
DeepSeek-V4-Flash284B MoERunPod 2x H200 (FP8)散文 + 代码,2k / 8k

并非每个实验都在每个模型上运行,下面的表格说明了哪些实验在哪些模型上运行。随着有趣的问题逐渐收窄,加入了更大的模型,因此攻击阶梯在小模型上覆盖较广,而长度和领域方面的工作则集中在大模型上。

这是什么

Anthropic(以及在他们之前的 Google DeepMind,即 SynthID-Text 论文)通过带密钥的锦标赛来偏置 token 采样,从而对生成文本进行水印标记。信号存在于哪些 token 被选中,而非任何隐藏字符中。我想知道,对于一个有动机使用查找替换的人来说,这种水印有多脆弱,因此我构建了生成器以及一个未经训练的均值-g 检测器,并向其发起攻击。

检测器阈值为 z = 2.33(1% 假阳性率)。高于该值 = 检测到水印。我生成带水印的文本,对其发起攻击,重新分词,然后评分。每个结果表都带有一个 roundtrip 对照(未受攻击的带水印文本),以便你能看到检测器在该行中确实在工作。本研究中有两次 bug 导致所有 z 值归零,而对照组是唯一发现该问题的手段。

攻击范围:什么真正有效

攻击面按 Unicode 类别清晰划分,事实证明这就是全部关键所在。

有效(Mn 类别,非间距标记):

攻击作用编辑率是否在归一化后存活?
vs16_30在约 30% 的字符后插入变体选择符57%是
vs16在约 10% 的字符后插入变体选择符23%是(z 3.46)
vs_supp补充平面选择符(U+E0100+)24%是(z 3.40)
homoglyph用西里尔字母 а 替换拉丁字母 a(Ll 类别)9%是,但效果较弱

不起作用(类别 Cf,格式字符):

攻击原始 z归一化 z判定
zwsp_30-0.0935.68完全还原
combo0.9235.68完全还原
bidi24.3735.68完全还原
nbsp41.0446.51几乎无变化

Cf 字符是纯格式字符,不含任何语义内容,因此归一化器可以将其整体剥离而不损失任何信息。Mn 变体选择符在 emoji 和 CJK 文本中承载真实语义,因此一刀切地剥离它们会破坏合法文档。正是这种不对称性,使得一类字符的剥离是合理的,而另一类则不是。

实际范围: 这需要触及大约 20% 或更多的字符,才能将强基线推至阈值以下,但插入的字符是不可见的,因此无论编辑率多高,文本读起来都正常。已通过视觉验证确认完全一致,参见 src/fidelity_check.py。四个类别只插入不渲染任何内容的字符;同形异义字是诚实的例外(依赖字体,不保证不可见)。

不起作用的部分:显而易见的手段

我最初的担忧是最无聊的那种:破折号、"and" 改成 "&"、剥离 markdown 就能奏效,水印最终不过是安全剧场。网上很多人都这么认为。

事实并非如此。在 gpt-oss-20b 上,完整的表层编辑阶梯测试,延伸至 32k tokens:

攻击编辑率z @ 1kz @ 32k
往返(对照)0%25.7104.3
破折号改连字符~0%26.4113.7
剥离所有 markdown13.6%27.2103.3
美式英语改英式英语 + 缩写1.3%~28~100
删除每个词的 40%38%4.925.4

在该阶梯测试所运行的三个模型上(0.8B、4B、20B = 294 个单元格),恰好有一个单元格越过阈值:在 4B 模型的最短长度下删除每个词的 39%。那不是攻击,那是把文档撕碎。

整个研究中测量的单元格总数:440(294 个来自上述攻击阶梯,加上 146 个来自下文将散文延伸至 131072 tokens 的缩放定律扫描)。

有两件事让我意外:

  • 编辑数量不能预测损害,编辑几何分布才能。 剥离所有 markdown(13.6% 的 tokens)毫无效果;它甚至得分略高于基线。以 1.6% 的比例注入零散空格,每次编辑造成的损害却高出 25 倍。Markdown 标记聚集在一起,因此它们的破坏窗口相互重叠,而它们之间的长段散文则持续完整地重放水印种子。分散的编辑使分词器失步,每次都会命中新的窗口。
  • 长度有利于检测器,而非攻击者。 z 的增长近似 sqrt(tokens)。"在长上下文中欺骗它"是反过来的,32k 是最难攻击的情况,而非最容易的。

完整机制和逐攻击表格见 docs/FINDINGS.md。

检测器靠等待取胜

水印强度与上下文的关系

水印置信度随上下文增长,而每 token 信号保持平稳,因此更长的文档更难攻击,而非更容易。散文在每种长度下都携带最强的标记;DeepSeek-V4-Flash(虚线)在 284B MoE 上重现了相同的攀升趋势。

攻击成本与上下文的关系

而且攻击必须跟得上。每个单元格表示 8 个随机插入种子中有多少个击败了检测器。10% 的插入率能通过 1k tokens,但到 4k 时完全失败。所需的插入率随上下文长度上升,这就是为什么该攻击并非上下文无关的。

一项专门的后续扫描精确锁定了这一点:在 gpt-oss-20b 上,从 1024 tokens 到 131072(该模型的最大上下文),所需插入率遵循 p*(L) ≈ 2.37·log2(L) − 14.6 —— 从 1k tokens 时的 9.3% 攀升至 131k 时的 25.0%。

但它永远不会反超

攻击效率至 1M tokens

那么,显而易见的后续问题就是:如果只是把文档做得足够长,检测器最终会彻底胜出吗?我们把扫描范围扩大到 1,048,576 个 token 来一探究竟。三个模型 × 每个上下文长度 × 插入率;上表中的每个单元格都是 5 个随机种子下检测器 z 值的中位数,青色表示攻击获胜(z < 2.33),橙色表示水印存活。

答案是不会。防御方的领先优势在扩大,但攻击方的成本增长得更慢:

模型测量长度最短长度下的 p*最长长度下的 p*每翻倍
gpt-oss-20b16k – 131k19.0%24.5%+1.86 pp
gpt-oss-120b16k – 131k14.2%19.5%+1.91 pp
Qwen3.8-27B16k – 1,048,57614.7%22.4%+1.21 pp

基线水印强度按 √n 增长,但抹除它所需的插入率在上下文每翻倍时仅上升约 1.2–1.9 个百分点。在 135 个已测量的攻击单元格中,35% 及以上插入率的全部 45 个单元格都低于阈值——最差情况为 35% 时 z = 0.31,40% 时 z = 0.60。实际所需的最高插入率是 24.5%,出现在 131k 上下文下的 gpt-oss-20b 上。从 16k 到 1M token——64 倍的增长——只为检测器换来了约 8 个百分点。

有两点需要明确说明。gpt-oss-120b 早先的“部分运行”现已完成,其在 131k 下测得的 19.5% 取代了此前从 4 个长度中的 3 个外推得到的约 20–23% 数值。而 Qwen3.8-27B 的基线 z 在所有七个长度上都稳定在 14.85——这是真实的文档退化伪影,因此其绝对强度数值不可靠;它展示的长度缩放趋势与其他两个模型一致,上表采用的正是这一趋势。完整表格、拟合结果与注意事项见 docs/FINDINGS.md § 14。

交互版本 →

试用交互版本 → 包含带前后对比切换的真实研究样本,以及一个可在你自己的文本上运行攻击变换的演练场。它不会告诉你任意粘贴的文本是否真的带有水印(那需要我们没有的密钥),并且它会明确说明这一点;生成脚本见 site/。

无需攻击即可发现的结论

水印依赖于模型对每个 token 的不确定性。当模型对下一个 token 有把握时,锦标赛没有空间去偏置它,因此不会注入任何信号。这意味着该标记在低熵文本上很弱,而代码就是低熵的。

Qwen3.5-4B,散文 vs 代码,512 token 样本,完全无攻击:

领域熵z
散文1.19 bits/tok11.1
代码0.55 bits/tok5.0

z 比值为 0.45x,熵比值为 0.46x,二者同步变化,这正是机制本身的体现。8 个代码样本中有 3 个自行降至或低于检测阈值。 最紧凑的一个(一个裸算法,0.2 bits/token)得分为 1.7,未命中。

在更大规模下情况更加极端。完全无攻击时的基线 z:

模型散文代码比值
gpt-oss-20b45.0337.240.83
Qwen3.8-27B35.504.310.12

Qwen3.8-27B 的代码输出模板化程度如此之高,以至于干净、未受攻击的水印仅处于 z = 4.31,勉强高于 2.33 的阈值。无需任何对手。

这说明:跨领域使用单一置信度阈值是不安全的,而短代码片段几乎无法加水印。这一结论可推广到 JSON、配置、结构化提取和样板文本。

防御要点

如果你部署了这类检测器,输入归一化能解决大部分问题,但并非全部:

  1. 剥离 Cf 类别字符。可消灭零宽字符、双向控制符及其组合。这是最大的收益点。
  2. NFKC 折叠。处理 nbsp 和兼容形式。
  3. 显式剥离变体选择符范围。 NFKC 不会替你完成这一步,而这正是当前敞开的缺口。
  4. 保留 Unicode 混淆字符映射表(UTS-39)以应对同形异义字符。NFKC 同样不会处理这一点。

第 3 步和第 4 步正是朴素归一化器会遗漏的地方。

这项工作的不足 / 我未能完成的部分

坦诚说明这些缺口。

  • 27B 的代码数字作为攻击结果没有参考价值。 那里的未受攻击基线为 z = 4.31,因此你无法证明攻击能击败一个本就几乎失明的检测器。我保留了这些行,但对其进行了标注;有意义的信号是基线,而不是攻击增量。
  • 27B 代码结果究竟是熵还是模型风格,目前尚无定论。 这需要像 4B 那样进行逐 token 熵测量,而我没有对该模型运行此测量。
  • Qwen3.8-27B 的三个社区量化检查点加载失败(FP8 需要我们没有的 torch dtype,两个 AWQ/compressed-tensors 重新打包存在打包不匹配)。改为在 H100 上以 bf16 运行。如果你要复现,请跳过这些重新打包。
  • 检测器是未训练的 mean-g 评分器,而不是论文中训练的贝叶斯检测器。 贝叶斯检测器可能更敏感,因此这些 z 值是一个下限,但我没有测量它。
  • 我的同形异义字保真度声明是“典型读者”,而非经过证明。 西里尔字母 а 属于 Ll 类别,因此其不可见性是字体属性,而非 Unicode 保证。
  • n 很小,阶梯每格 2 个文档,熵每个域 8 个样本。对于这里的效应量(它们很大)足够,但对于紧密的逐攻击误差棒不够。
  • 我不提供调优的规避配方,这是有意为之。这里的每个攻击都与能或不能击败它的归一化结果一起报告。重点是测量前沿在哪里,而不是打包一个绕过方案。

layout

下载工具