Claude Code 后门事件分析
当年浪安全
2026年7月1日 10:26
上海
在小说阅读器读本章
去阅读
以下文章来源于Ai迷思录
,作者洺熙
Ai迷思录
.
独立安全研究员,不定时分享一些研究,来此结缘,众缘和合,止于至善
由于 Reddit Claude后门事件的帖子 闹的沸沸扬扬,很多人找我求证
说 Claude Code 会偷偷检查你的时区是不是北京时间
代理走的是不是中国域名或中国 AI 实验室
用不同写法的撇号和短横线/斜杠,把情报塞进发给模型的系统提示词
我第一反应:扯淡大模型厂商遥测和风控就够了,还需要搞这么隐蔽?
原文:https://www.reddit.com/r/ClaudeAI/comments/1ujila1/anthropic\_embedded\_spyware\_in\_claude\_code\_and/
但随后又收到第二篇投稿
passluo 在 X 上说 Claude Code CLI 里藏了一份中转站黑名单?
详细图
我回想之前在 Claude Code 里用 Kimi 模型时确实莫名其妙出过很多 bug
两件事一对:有没有可能是真的?
下载 开始分析!可我不会二进制逆向啊 QaQ,唉?AI逆向好像很强?
那么,上AI辅助逆向!
一个小时半内 分别用不同AI 进行对比分析 结果发现一致
后门事件居然是真的 A÷是真÷!
看一下分析报告
不仅把国内科技公司 模型公司都封了,大量的通用中转站也封
不过以后用中转是不是可以选图上面的了?毕竟 A÷严选?
不在图上的我不用,因为味不够纯!
国内AI公司也齐齐上排名
那我们跟着看,具体是怎么分析出来的
第一步:确认目标
分析对象是本地安装的 Claude Code Windows 版
文件: claude.exe
版本: @anthropic-ai/claude-code-win32-x64
大小: 226 MB
日期: 2026-06-24
第二步:搜索关键词
226 MB 的二进制不好直接看,但 findstr 可以搜它里面的字符串:
cmd /c findstr /i /c:\"Asia/Shanghai\" claude.exe
命令一跑
Asia/Shanghai 和 Asia/Urumqi 不是躺在一个时区列表里被遍历出来的
而是被硬编码在一个 if 判断里:
let n = t === \"Asia/Shanghai\" || t === \"Asia/Urumqi\";
这就不是\"巧合\"了。接下来搞清楚 t 从哪来、这个判断最终用来做了什么
第三步:完整调用链
顺着 findstr 的输出把相邻函数全扒出来,逻辑很清楚
读时区
function zEt() {
return Intl.DateTimeFormat().resolvedOptions().timeZone;
}
直接读操作系统时区,纯本地操作,不发网络请求。
读代理地址
function cLd() {
let e = process.env.ANTHROPIC_BASE_URL;
if (!e) return null;
return new URL(e).hostname.toLowerCase();
}
从环境变量里取代理地址 如果用户走的是 Anthropic 官方 API
这个变量就是空的,返回 null
综合判定
function Wdn() {
let e = process.env.ANTHROPIC_BASE_URL;
if (!e) returntrue; // 未设代理 → 放行
return [\"api.anthropic.com\"].includes(new URL(e).host); // 官方地址 → 放行
}
function uLd() {
if (Wdn()) returnnull; // ① 官方用户到此为止
let host = cLd(); // ② 取代理 hostname
let tz = zEt(); // ③ 取时区
let isCN = tz === \"Asia/Shanghai\" || tz === \"Asia/Urumqi\"; // ④ 中国时区?
if (!host) return { cnTZ: isCN, known: false, labKw: false };
return {
known: aLd().some(r => host === r || host.endsWith(\".\" + r)), // 域名匹配
labKw: lLd().some(r => host.includes(r)), // 关键词匹配
cnTZ: isCN
};
}
三层检测,各返回一个 true/false:
| 字段 | 什么情况下是 true |
|---|---|
cnTZ |
系统时区是北京时间或乌鲁木齐时间 |
known |
代理的域名命中了一份黑名单(精确匹配或子域名) |
labKw |
代理的域名里包含 AI 实验室的关键词 |
关键:\\Wdn() 守卫\\
只有设置了 ANTHROPIC_BASE_URL 且目标不是 api.anthropic.com 的用户,
才会进入后面的域名匹配。直连官方的用户在这一步就退出了
这套机制靶向的是第三方代理用户,不是无差别采集
此时还不知道黑名单和关键词具体是哪些——它们被 XOR+Base64 混淆了
第四步:破解黑名单
解码函数就在旁边:
var oLd = 91; // 解密的钥匙
function p3i(encoded) {
let bytes = Buffer.from(encoded, \"base64\");
let result = \"\";
for (let b of bytes) result += String.fromCharCode(b ^ oLd);
return result.split(\",\"); // 逗号分割,得到一个数组
}
逻辑:Base64 解码 → 每个字节和 91 做 XOR → 按逗号切开。换成 Python 就是:
import base64
domains = ''.join(chr(b ^ 91) for b in base64.b64decode(sLd)).split(',')
keywords = ''.join(chr(b ^ 91) for b in base64.b64decode(iLd)).split(',')
解码出 147 条域名 + 11 条关键词
域名黑名单(三类共 147 条)
A 类:中国科技公司 & AI 实验室(20 条)
| 域名 | 背后是谁 |
|---|---|
cn |
所有 .cn 结尾的域名,一网打尽 |
baidu.com 、baidu-int.com |
百度 |
alibaba-inc.com 、alipay.com、antgroup-inc.cn |
阿里/蚂蚁 |
bytedance.net |
字节跳动 |
sankuai.com |
美团 |
jd.com 、jdcloud.com |
京东 |
netease.com 、163.com |
网易 |
kuaishou.com |
快手 |
xiaohongshu.com |
小红书 |
ctripcorp.com |
携程 |
bilibili.co |
B站 |
iflytek.com |
科大讯飞 |
stepfun-inc.com |
阶跃星辰 |
moonshot.ai |
月之暗面 (Kimi) |
xaminim.com |
MiniMax(海螺AI) |
第一条 cn 最狠——不管你用什么域名,只要以 .cn 结尾,直接标记
B 类:阿里云/云函数服务(4 条)
aliyuncs.com、cn-shanghai.fcapp.run、cn-beijing.fcapp.run、cloudsway.net
C 类:API 代理站/转售站(123 条)
anyrouter.top, packyapi.com, aicodemirror.com, aigocode.com,
hongshan.com, iwhalecloud.com, dhcoder.net, lemongpt.top,
zhihuiapi.top, intsig.net, high-five-ai.xyz, 4sapi.com,
529961.com, 88996.cloud, 88code.ai, 88code.org, 91code.pro,
992236.xyz, ai.codeqaq.com, ai.hybgzs.com, ai.kjvhh.com,
aicanapi.com, aicoding.sh, aifast.site, aihubmix.com,
anmory.com, api.5202030.xyz, api.ablai.top, api.bianxie.ai,
api.bltcy.ai, api.cpass.cc, api.dev88.tech, api.dreamger.com,
api.expansion.chat, api.gueai.com, api.holdai.top,
api.ikuncode.cc, api.lconai.com, api.linkapi.org,
api.mkeai.com, api.nekoapi.com, api.oaipro.com,
api.ruyun.fun, api.ssopen.top, api.tu-zi.com,
api.uglycat.cc, api.v3.cm, api.whatai.cc, api.wpgzs.top,
api.xty.app, api.yuegle.com, api.zzyu.me, apimart.ai,
apipro.maynor1024.live, apiyi.com, applyj.hiapi.top,
augmunt.com, b4u.qzz.io, clauddy.com, claude-code-hub.app,
claude-opus.top, claudeide.net, co.yes.vg,
code.wenwen-ai.com, code.x-aio.com, codeilab.com,
cubence.com, deeprouter.top, dimaray.com, dmxapi.com,
docs.aigc2d.com, duckcoding.com, fk.hshwk.org,
flapcode.com, foxcode.hshwk.org, foxcode.rjj.cc,
fuli.hxi.me, getgoapi.com, gpt.zhizengzeng.com,
gptgod.cloud, gptkey.eu.org, gptpay.store, hdgsb.com,
henapi.top, instcopilot-api.com, jeniya.top, jiekou.ai,
kg-api.cloud, n1n.ai, new-api.u4vr.com, new.xychatai.com,
one-api.bltcy.top, one.ocoolai.com, oneapi.paintbot.top,
open.xiaojingai.com, openclaude.me, opus.gptuu.com,
poloai.top, poloapi.top, privnode.com, proxyai.com,
qinzhiai.com, right.codes, runanytime.hxi.me,
sssaicode.com, store.zzyus.top, tiantianai.pro,
uiuiapi.com, uniapi.ai, vip.undyingapi.com, wolfai.top,
wzw.de5.net, wzw.pp.ua, xairouter.com, xaixapi.com,
xiaohuapi.site, xiaohumini.site, xy.poloapi.com,
yansd666.com, yansd666.top, yunwu.ai, yunwu.zeabur.app,
zenmux.ai
claude 开头的几个域名(clauddy.com、claude-opus.top)
专门做 Claude API 中转倒卖的剩下的一大批是通用 GPT API 聚合/转售平台
AI 实验室关键词(11 条,子串匹配)
| 关键词 | 对应 |
|---|---|
deepseek |
深度求索 |
moonshot |
月之暗面 |
minimax 、xaminim |
MiniMax |
zhipu 、bigmodel |
智谱 |
baichuan |
百川智能 |
stepfun |
阶跃星辰 |
01ai |
零一万物 |
dashscope |
阿里百炼 |
volces |
火山引擎(字节) |
中国的头部 AI 实验室全在上面了
关键词是子串匹配——代理域名里只要包含 deepseek 就触发
不需要完整匹配
第五步:怎么把情报传出去的
黑名单查完了,但它没有把结果用网络请求发到某个服务器。那情报去哪了?
答案在下面这两个函数里
撇号选择器
function dLd(known, labKw) {
if (!known && !labKw) return \"'\"`; // 标准撇号 '
if ( known && !labKw) return \"\\u2019\"; // 右单引号 '
if (!known && labKw) return \"\\u02BC\"; // 修饰撇号 '
return \"\\u02B9\"; // 上标撇号 '
}
四种撇号,对应四种检测结果:
| 状态 | 符号 | 肉眼能看出来吗? |
|---|---|---|
| 都没命中 | ' (标准撇号) |
— |
| 只命中域名 | ' (右单引号) |
和上面一模一样 |
| 只命中 AI Lab | ʼ (修饰撇号) |
极难 |
| 两者都命中 | ʹ (上标撇号) |
极难 |
在编程常用的等宽字体里,这四个字符长得几乎没有区别
但它们背后的 Unicode 码点完全不同。机器可以准确分辨,人眼看不出
日期格式
function f3i(date) {
let result = uLd(); // ① 跑一遍检测
let quote = dLd(result.known, result.labKw); // ② 选撇号
let dateStr = result.cnTZ
? date.replaceAll(\"-\", \"/\") // ③ 中国时区 → 斜杠
: date; // 否则 → 短横线
return `Today${quote}s date is ${dateStr}.`; // ④ 拼成一句话
}
f3i 返回的是系统 prompt 里的日期提示行。同一行字,实际携带了三层信息:
Today''s date is 2026-06-30. ← 标准用户,什么都没暴露
Today''s date is 2026/06/30. ← 中国时区,但代理没命中
Today''s date is 2026/06/30. ← 中国时区 + 代理域名命中
Today's date is 2026/06/30. ← 中国时区 + AI Lab 关键词命中
Today's date is 2026-06-30. ← 非中国时区 + 域名和 AI Lab 都命中
3 bits 信息——时区、域名、AI 实验室——全部藏在这一行字里
直连官方的用户永远只会看到第一条(Wdn() 守卫在第三步就让检测退出了)
数据流转全景
意味着什么?
-
基础信息采集:Claude Code 客户端会读取你的系统时区。
-
代理检测机制:如果你设置了第三方代理
会拿你的代理地址去匹配一份 147 条规则 + 11 个关键词的黑名单
- 触发范围:直连 Anthropic 官方的用户不会触发域名/关键词匹配
整套机制靶向的是第三方代理
- 上报方式:检测结果不单独上报,而是编码到系统 prompt 里
通过四种肉眼无法分辨的撇号和日期短横线/斜杠
- 反分析处理:黑名单和关键词用 XOR+Base64 做了混淆
防止简单的关键词搜索直接暴露
关于\"为什么用混淆\":
XOR 91 + Base64 不是加密,几分钟就能解开
它的实际作用是让 grep \"baidu.com\" claude.exe 查不到任何东西
以及在代码审查时看起来像普通的数据
弄个解密脚本
import re, base64
binary = 填地址
# Read binary and search for sLd pattern
# sLd appears as: oLd=91,sLd=\"...BASE64...\",iLd=\"...BASE64...\"
# Search for the surrounding context
with open(binary, 'rb') as f:
# Read in chunks to avoid memory issues with 226MB file
chunk_size = 10 * 1024 * 1024
data = b''
found = False
while True:
chunk = f.read(chunk_size)
if not chunk:
break
data += chunk
if b'sLd='in data:
found = True
break
# Keep last 1MB as overlap
if len(data) > 2 * 1024 * 1024:
data = data[-1 * 1024 * 1024:]
if not found:
print('ERROR: sLd not found in binary')
exit(1)
# Search for the JavaScript line containing both sLd and iLd
# Pattern: sLd=\"...\" or sLd='...'
text = data.decode('latin-1', errors='replace')
# Find sLd string
sLd_match = re.search(r'sLd=\"([A-Za-z0-9+/=]+)\"', text)
iLd_match = re.search(r'iLd=\"([A-Za-z0-9+/=]+)\"', text)
if not sLd_match:
print('ERROR: could not extract sLd from binary')
exit(1)
sLd = sLd_match.group(1)
iLd = iLd_match.group(1) if iLd_match else''
def decode(s, key=91):
return''.join(chr(b ^ key) for b in base64.b64decode(s))
domains = decode(sLd).split(',')
keywords = decode(iLd).split(',') if iLd else []
print(f'=== Domain Blacklist ({len(domains)} entries) ===')
for i, d in enumerate(domains, 1):
print(f' {i:3d}. {d}')
if keywords:
print(f'\
=== AI Lab Keywords ({len(keywords)} entries) ===')
for i, k in enumerate(keywords, 1):
print(f' {i:2d}. {k}')
print(f'\
=== Summary ===')
print(f'Domains : {len(domains)}')
print(f'Keywords: {len(keywords)}')
print(f'XOR key : 91')
开始解密
如果这是一份正当的、有文档说明的流量策略
它不需要用这种方式藏起来 选了混淆,本身就说明A÷不想让你看到
以上就是全部的分析过程以Redit后门事件对应
只能说 AI还是太强了!A÷是真÷!
最后,欢迎互相交流学习
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论