anthropicclaudecode针对中国用户遥测的分析

admin 2026-07-02 05:02:24 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档通过逆向工程分析ClaudeCode2.1.196版本,发现其针对中国用户进行特殊指纹测绘。当用户设置自定义API端点时,程序会通过Unicode字符编码隐蔽传输三类信息:是否使用已知中国域名、是否包含AI实验室关键词、是否使用中国时区。分析确认了147个监控域名和11个AI实验室关键词列表,测绘数据随模型请求发送而非独立遥测。 综合评分: 85 文章分类: 代码审计,逆向分析,隐私分析,数据安全,应用安全


cover_image

anthropic claude code针对中国用户遥测的分析

原创

闲聊趣说 闲聊趣说

闲聊趣说

2026年7月1日 00:49 河南

在小说阅读器读本章

去阅读

前言

刷推特偶然刷到claude code会针对中国用户进行特殊的指纹测绘,于是赶紧让codex(GPT 5.5)对claude code分析了一下,以下为AI分析结论,全量分析产生的文件可在

https://github.com/Chestnuts4/claude_code_rev

分析下来确实针对中国用户进行了特殊对待,使用prompt隐蔽传输测绘结果,单从域名/流量请求看没办法看出来携带了特殊测绘信息,甚至编码了一个中转站域名list,想来后面想杀的时候直接就可以将对应的账户封禁了。

作为封号的受害者,无数次问候达里奥全家了。

Claude Code 2.1.196 解包与隐私逻辑分析记录

生成日期:2026-06-30(Asia/Taipei)

本报告记录从样本确认、Bun 解包、源码格式化、混淆数据解码、控制流追踪到结论形成的完整过程。分析采用静态读取和本地重建测试,没有让 claude.linux 发起模型或 telemetry 网络请求。

1. 分析目标

  1. 将 Bun 打包的 claude.linux 解包为可审阅的 JavaScript;
  2. 核对 Reddit 帖子所称的自定义代理、时区和中国 AI 实验室标记逻辑;
  3. 确认信号如何进入网络请求;
  4. 区分模型上下文、独立 telemetry、错误报告和用户主动反馈;
  5. 保存可重复执行的脚本和分析产物。

参考帖子:https://www.reddit.com/r/ClaudeAI/comments/1ujila1/anthropic_embedded_spyware_in_claude_code_and/

官方数据使用说明:https://code.claude.com/docs/en/data-usage

官方环境变量说明:https://code.claude.com/docs/en/env-vars

2. 样本确认

执行:

file claude.linux
sha256sum claude.linux
./claude.linux --version

结果:

ELF 64-bit LSB executable, x86-64, dynamically linked, not stripped
SHA-256 eb933c6dd5534db89b83ba09009d5c0932bd1395f7e3bb0f34ba37eec37bbade
2.1.196 (Claude Code)

radare2 MCP 也成功打开样本,并识别出:

format: elf64
arch: x86
bits: 64
entrypoint: 0x01b38e00
compiler: GCC 13.1.0 / LLD 22.1.4

因此本地样本与帖子所指版本一致,而不是把其他版本的逻辑推断到本样本。

3. Bun 打包结构识别

readelf -S claude.linux 显示独立的 .bun section:

[30] .bun PROGBITS
offset 0x05238000
size   0x097bd0d1(约 152 MiB)

提取该 section:

objcopy --dump-section .bun=claude.bun-section.bin claude.linux

在 section 中找到 Bun trailer:

\n---- Bun! ----\n

并找到目标明文字符串:

ANTHROPIC_BASE_URL
Asia/Shanghai
Asia/Urumqi
Today${n}s date is

这证明目标应用代码以 minified JavaScript 存在于 Bun module graph 中,并非只能从 x86 机器码反编译。

4. 通用解包器失败与原因

首先测试了 @shepherdjerred/bun-decompile。它返回:

Corrupt module graph: Pointer extends beyond buffer:
offset=16779776, length=158616795

检查该解包器源码后发现,它按旧版 CompiledModuleGraphFile 的 36 字节记录解析;样本 trailer 中 module table 长度为 0x104(260)字节。实际记录可以稳定分成:

260 / 52 = 5 modules

按 52 字节解析时,各模块的 name pointer 和 contents pointer 均落在合法数据范围,且提取内容能被 file 正确识别。旧解析器把新版记录中的其他字段错当成 bytecode pointer,才造成越界。

5. 自建解包器与提取结果

为保留可重复性,编写了:

tools/extract-bun-1.3.js

该脚本执行以下步骤:

  1. 从文件尾向前寻找 Bun trailer;
  2. 读取 trailer 前 32 字节的 offsets structure;
  3. 计算 dataStart = trailerPos - 32 - byteCount
  4. 读取 module table pointer;
  5. 根据 table 长度选择 52 字节记录格式;
  6. 解析每个模块的 name 和 contents pointer;
  7. 做边界检查后写出模块和 manifest.json

执行:

bun tools/extract-bun-1.3.js \
  claude.linux \
  decompiled-claude-2.1.196

关键 offsets:

trailerPos: 245321921
dataStart: 86212616
byteCount: 159109273
module entry size: 52
entry point id: 0
flags: 15

提取出 5 个模块:

| ID | Bun 内部路径 | 类型 | 大小 | | — | — | — | — | | 0 | /$bunfs/root/src/entrypoints/cli.js | JavaScript,入口 | 18,054,465 | | 1 | /$bunfs/root/image-processor.js | JavaScript | 1,976 | | 2 | /$bunfs/root/audio-capture.js | JavaScript | 1,974 | | 3 | /$bunfs/root/image-processor.node | ELF native addon | 1,464,760 | | 4 | /$bunfs/root/audio-capture.node | ELF native addon | 492,184 |

主模块哈希:

f936de85f33e25bb95c36f1dd3a73471a1c91a6a95ac5a22370f0f21e7a7559d  bundled/0-cli.js

6. 格式化与源码定位

原始主模块是一份 minified JS。使用本地 Prettier 生成:

prettier --write decompiled-claude-2.1.196/claude-2.1.196.formatted.js

结果约 875,183 行,SHA-256:

e85a3592e6844f21848034b6e51bcdba80dd8ed8cbddbd1f8966d6c44226c5a7

目标逻辑位于格式化文件约 274037–274088 行,system context 调用位于约 278990–279016 行。相关 minified 符号为:

| 符号 | 作用 | | — | — | | $la | Base64 解码后逐字节 XOR 91,再按逗号拆分 | | Wup | 读取 ANTHROPIC_BASE_URL 的 hostname | | vrtwrt | 判断是否为默认/官方 api.anthropic.com | | ekt | 读取系统 IANA 时区 | | qup | 生成 known、labKw、cnTZ、host 分类 | | Vup | 根据两个 hostname 分类选择 Unicode 撇号 | | Ola | 生成最终日期句子 |

qup() 在整个主模块中只有定义和 Ola() 中的一次调用。host 没有通过这条路径被其他代码直接上报。

7. 混淆列表解码

程序把两个列表保存为 Base64 字符串,运行时执行:

Buffer.from(encoded, "base64")
byte ^ 91
decoded.split(",")

编写 tools/extract-privacy-marker.js 独立复现该算法,并输出 decoded-marker-lists.json。结果包含:

  • 147 个 known-domain 项;
  • 11 个 AI-lab keyword。

AI-lab keyword 完整列表:

deepseek
moonshot
minimax
xaminim
zhipu
bigmodel
baichuan
stepfun
01ai
dashscope
volces

known-domain 列表包含 .cn 后缀标记、百度、阿里、字节、京东、网易、美团等企业域名,以及大量第三方 API 中转站域名。完整内容保存在 decoded-marker-lists.json,不在报告中重复 147 行。

域名判断为:

host === domain || host.endsWith("." + domain)

关键词判断为:

host.includes(keyword)

因此它只是字符串分类器,不是组织身份或账户隶属关系验证。

8. 精确控制流

8.1 启用条件

vrt() 的语义为:

if (!process.env.ANTHROPIC_BASE_URL) returntrue;
returnnewURL(value).host === "api.anthropic.com";

qup() 开头执行:

if (vrt()) returnnull;

所以以下情况不打标:

  • 没有设置 ANTHROPIC_BASE_URL
  • 设置为 https://api.anthropic.com

启用对象是 Claude Code 的自定义 API base URL,不是通用的 HTTP_PROXYHTTPS_PROXY 或 SOCKS 配置。把它简称为“代理检测”容易误导。

8.2 输入信号

启用后读取:

  1. 自定义 base URL 的 hostname;

  2. Intl.DateTimeFormat().resolvedOptions().timeZone

  3. hostname 是否命中 known-domain;

  4. hostname 是否包含 AI-lab keyword。

时区只判断两个精确值:

Asia/Shanghai
Asia/Urumqi

没有发现此路径进行 IP 定位、GPS 定位或读取真实地理位置。Asia/Taipei 不命中。

8.3 编码方式

| known | labKw | 字符 | Unicode | | — | — | — | — | | false | false | ' | U+0027 | | true | false | | U+2019 | | false | true | ʼ | U+02BC | | true | true | ʹ | U+02B9 |

当 cnTZ=true 时,日期中的 - 被替换为 /

一个看似普通的日期句子因此能编码三个布尔分类位:known-domain、lab-keyword、China-timezone。

8.4 进入请求

Ola(FSe()) 的结果被赋给 user context 的 currentDate

{
  claudeMd,
  userEmail,
  attachedProject,
currentDate: Ola(FSe()),
}

随后该 context 进入 Claude 模型 system prompt。因此分类结果随正常模型请求发送到当前模型端点。它不是独立 telemetry event,也不是单独的 hostname 上传请求。

9. 本地重建验证

为了避免执行原程序网络路径,编写了 privacy-marker.reconstructed.js,只重建上述纯函数逻辑。测试结果:

未设置 base URL + Asia/Taipei
=> Today's date is 2026-06-30.

api.anthropic.com + Asia/Shanghai
=> Today's date is 2026-06-30.

proxyai.com + Asia/Taipei
=> Today’s date is 2026-06-30.      U+2019

deepseek.example + Asia/Taipei
=> Todayʼs date is 2026-06-30.      U+02BC

moonshot.ai + Asia/Shanghai
=> Todayʹs date is 2026/06/30.      U+02B9 + slash date

这些输出与帖子描述的字符映射一致。

10. 会进入模型上下文的其他信息

同一 user_context 构造代码还可能加入:

  • CLAUDE.md、用户 memory、项目 memory 的内容;
  • attached project context;
  • 登录账户邮箱,文本格式为 The user's email address is ...
  • 当前日期及本报告确认的隐藏分类。

正常使用时,下列内容也会按照模型工作流发送给所选 API 端点:

  • 用户输入;
  • 用户明确附加的文件;
  • 工具读取并加入会话上下文的代码和文件内容;
  • 工具结果;
  • 对话历史和模型输出。

这类“模型推理所需上下文”应与独立的产品 telemetry 区分。若使用自定义 ANTHROPIC_BASE_URL,该网关本身通常也能看到转发的模型请求正文。

11. 独立网络上报分类

根据本地源码开关和 Claude Code 官方说明:

| 类型 | 内容/行为 | 关闭方式 | | — | — | — | | Anthropic operational telemetry | 延迟、可靠性、使用模式;官方称不含代码和文件路径 | DISABLE_TELEMETRY=1 | | Sentry error reporting | 运行错误报告 | DISABLE_ERROR_REPORTING=1 | | /feedback | 用户主动提交时可包含会话历史和代码 | DISABLE_FEEDBACK_COMMAND=1 | | Session quality survey | 会话质量调查 | CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY=1 | | WebFetch safety preflight | 把待访问 URL 的 hostname 发给 api.anthropic.com | skipWebFetchPreflight: true | | Auto updater | 版本检查/更新 | DISABLE_AUTOUPDATER=1 |

CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 等价关闭 updater、feedback、error reporting 和 telemetry,但:

  • 不关闭 WebFetch hostname 安全预检;
  • 不关闭本报告确认的 system-prompt 日期标记;
  • 不阻止正常模型请求携带会话上下文。

DISABLE_TELEMETRY 也不会关闭日期标记,因为目标代码路径没有检查该变量,且标记属于模型请求正文。

12. 对 Reddit 指控的逐项判断

| 指控 | 判断 | 依据 | | — | — | — | | 自定义 endpoint 会触发隐藏检测 | 属实 | vrt()qup() 控制流 | | 检测 HTTP/HTTPS 代理 | 不准确 | 实际只读 ANTHROPIC_BASE_URL | | 检测用户是否在中国 | 夸大 | 只检查 Shanghai/Urumqi 时区,无 IP 定位 | | 检测是否隶属中国 AI 实验室 | 夸大 | 只做 hostname 关键词包含判断 | | 分类被隐式传给服务端 | 属实 | Unicode 撇号和日期格式进入 currentDate system prompt | | 完整自定义 hostname 被此路径直接上传 | 未发现 | host 仅供本地分类,qup() 只有一个消费者 | | 可用 DISABLE_TELEMETRY 关闭 | 不属实 | 标记不走 telemetry 开关 | | 代码经过刻意隐藏 | 有事实基础 | 域名与关键词使用 Base64 + XOR 91;但 minification 本身不能单独证明主观意图 |

13. 最终结论

样本中确实存在一个未在正常 UI 中披露的环境分类机制。当用户配置非官方 ANTHROPIC_BASE_URL 时,它根据自定义 hostname 和两个中国时区生成三个分类位,并通过肉眼不易区分的 Unicode 撇号及日期格式嵌入 system prompt。该标记会随模型请求到达用户配置的 API 端点。

把这称为“完整代理地址或个人文件的秘密独立上报”并不准确:在已追踪的目标路径中,完整 hostname 不进入请求,只进入本地分类;代码和文件是否发送取决于正常模型上下文和工具使用。把它称为“检测用户真实位于中国或确认实验室隶属关系”同样超过代码证据。

更准确的表述是:Claude Code 2.1.196 对自定义 API endpoint 及特定系统时区进行本地分类,并将分类结果隐写进模型 system prompt;这一机制不受 telemetry opt-out 控制。

13.1 中转域名与 AI Lab 关键词的行为差异

有区别,但区别仅体现在隐藏 system-prompt 标记上。其他功能变化由“是否为非官方 ANTHROPIC_BASE_URL”决定。

| 域名分类 | 日期文本 | | — | — | | 两类都未命中 | Today's date is 2026-07-01. | | 仅命中中转域名名单 | Today’s date is 2026-07-01. ,U+2019 | | 仅包含 AI Lab 关键词 | Todayʼs date is 2026-07-01. ,U+02BC | | 两类同时命中 | Todayʹs date is 2026-07-01. ,U+02B9 |

例如:

  • proxyai.com

    :在 147 个域名名单中,通常是“仅中转域名”;

  • deepseek.example

    :包含 deepseek,但不一定在域名名单中,属于“仅 AI Lab”;

  • moonshot.ai

    :既在域名名单中,又包含 moonshot,属于“两者同时命中”。

如果系统时区是 Asia/Shanghai 或 Asia/Urumqi,以上日期还会变成:

2026/07/01

需要注意:

  • “AI Lab 域名”并不是独立的精确域名表,而是 11 个 hostname 子串关键词;
  • Remote Control 禁用、ToolSearch 默认关闭、部分 first-party 能力失效等行为,对所有非官方 base URL 都相同,不区分中转名单或 AI Lab;
  • GrowthBook 上报完整 apiBaseUrlHost 时也不区分这两个分类;服务端可以直接看到实际 hostname;
  • 没发现根据两类标记切换模型、降低回答质量、改变价格或直接封号的客户端逻辑。标记在服务端如何使用,无法从客户端二进制确定。

14. 局限性

  • 本报告是目标逻辑的静态分析和纯函数重建,没有使用抓包对真实 Anthropic 服务端行为做动态验证;
  • 没有声称穷举 18 MB 主模块中的每一种业务网络请求;
  • Sentry 在具体异常下可能包含哪些堆栈字段,需要独立动态触发和抓包才能完整枚举;
  • 本结论严格对应所列 SHA-256 的 Linux 2.1.196 样本,后续版本可能改变;
  • 对开发者主观动机(反蒸馏、风控或其他用途)不从代码作无证据推断。

15. 落盘产物

decompiled-claude-2.1.196/
├── ANALYSIS.zh-CN.md                 本完整报告
├── manifest.json                     Bun 模块清单和 offsets
├── bundled/
│   ├── 0-cli.js                      原始 minified 主模块
│   ├── 1-image-processor.js
│   ├── 2-audio-capture.js
│   ├── 3-image-processor.node
│   └── 4-audio-capture.node
├── claude-2.1.196.formatted.js       格式化完整主模块
├── decoded-marker-lists.json         147 个域名和 11 个关键词
└── privacy-marker.reconstructed.js   可读重建及本地测试目标

tools/
├── extract-bun-1.3.js                Bun 1.3 module graph 解包脚本
└── extract-privacy-marker.js         混淆列表解码脚本

复现核心过程:

bun tools/extract-bun-1.3.js claude.linux decompiled-claude-2.1.196
cp decompiled-claude-2.1.196/bundled/0-cli.js \
   decompiled-claude-2.1.196/claude-2.1.196.formatted.js
prettier --write decompiled-claude-2.1.196/claude-2.1.196.formatted.js
bun tools/extract-privacy-marker.js \
  decompiled-claude-2.1.196/claude-2.1.196.formatted.js

16. 全部静态加密字符串解码

进一步扫描完整格式化主模块中的以下模式:

  • Buffer.from(..., "base64")

  • atob(...)

  • String.fromCharCode(... ^ key)

  • crypto.subtle.decrypt

    、AES、JWT 与通用 decrypt helper;

  • 静态常量到解码函数的调用关系。

扫描后,应用自身用于隐藏静态文本的解码器只有 $la(),调用关系只有:

$la(Uup)
$la(Fup)

因此可静态解密的应用字符串常量总数为 2:

| 常量 | 算法 | 解码结果 | | — | — | — | | Uup | Base64 decode,然后每字节 XOR 91 (0x5b) | 147 个域名 | | Fup | Base64 decode,然后每字节 XOR 91 (0x5b) | 11 个 AI lab 关键词 |

已生成:

static-decoding/
├── all-decrypted-strings.txt
├── all-decoded-static-payloads.json
├── claude-2.1.196.deobfuscated.js
└── binary-assets/
    └── FNf.glyph-table.bin

claude-2.1.196.deobfuscated.js 是完整 875,341 行分析副本,其中:

  • Uup

    的密文被替换为 147 项明文数组;

  • Fup

    的密文被替换为 11 项明文数组;

  • $la(Uup)

    和 $la(Fup) 被替换为数组直接引用;

  • 文件已通过 node --check 语法验证。

完整明文也单独保存在 all-decrypted-strings.txt,便于不加载 27 MiB JS 时直接审阅。

非字符串静态 payload

扫描还发现 FNf

inflateRawSync(Buffer.from(FNf, "base64"))

它是终端截图渲染所用的压缩 glyph bitmap table,不是加密文本。为了完整处理静态编码 payload,已执行 Base64 解码和 raw-deflate 解压,输出为 FNf.glyph-table.bin。解压后首字段可解析为 glyph 数量;该二进制没有被错误转换成乱码文本。

无法预先解密的运行时数据

主模块包含 AES、JWT、WebCrypto 和通用 Base64 库代码,但这些函数的 ciphertext、key、IV 或 token 来自运行时参数。样本中没有与其配对的静态 ciphertext/key 常量,因此不存在可在静态分析阶段合法求值的更多明文。此类库函数被记录在 JSON 清单的 unresolved 字段,而不是虚构解密结果。

复现命令:

bun tools/decode-all-static-payloads.js \
  decompiled-claude-2.1.196/claude-2.1.196.formatted.js
node --check \
  decompiled-claude-2.1.196/static-decoding/claude-2.1.196.deobfuscated.js

文件哈希:

cf4f0c125d534377352039a5785891a61164e1929202ee3367b29fec6961228c  all-decoded-static-payloads.json
7d418ad4ed87ced629393e981f29e8670fd51e08bc25921bc0e553b2772dd31f  all-decrypted-strings.txt
05fa6754f8ed16ec84925c32c92eb35e525378c1e837228b9e0d78d8a02e9e34  claude-2.1.196.deobfuscated.js
f0980417a011379fab891fb38a92101ff83663b9633697512362c68c53db73cf  FNf.glyph-table.bin

#


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:闲聊趣说 闲聊趣说 闲聊趣说《anthropic claude code针对中国用户遥测的分析》

ClaudeCode后门事件分析 网络安全文章

ClaudeCode后门事件分析

文章总结: 文档分析ClaudeCode客户端存在隐蔽检测机制,通过检查系统时区是否为中国时区、代理域名是否命中黑名单及是否包含AI实验室关键词来识别用户。检测
评论:0   参与:  0