一次脚本投毒,如何同时瞄准用户数据与转账资金?
文章作者、来源:慢雾科技
背景
近日,慢雾安全人员在日常威胁情报挖掘中,监测到一起涉及 Udesk 客服系统相关脚本遭投毒的攻击活动。团队随后获取了 udeskApi.2026-10-16.cached.js 和 deeps.js 两份 JavaScript 样本,并展开分析,追查恶意代码如何借助客服脚本进入页面,以及它对用户数据和业务操作做了什么。
对样本的检查逐步揭示了两类风险:恶意脚本一边采集网页中的会话数据和用户提交的敏感信息,一边按站点规则修改充值地址和复制内容。前者可能使攻击者冒用登录会话或接管账号,后者则可能让用户将充值资金转入被替换的收款地址。我们从客服脚本的加载入口展开,沿着数据读取、网络发送和页面修改逻辑,还原这两类行为的实现方式与触发条件。
MistEye 响应
MistEye 是由 SlowMist 自主研发的 Web3 威胁情报与动态安全监控系统,集成了安全监控与情报聚合能力,为用户提供实时的风险预警与资产守护。
MistEye 已第一时间通过情报推送与客户告警通道同步风险。

恶意加载器与远程载荷加载机制
打开 udeskApi.2026-10-16.cached.js 后,可以看到客服按钮、聊天 iframe、访客跟踪和消息通信等功能代码。继续检查文件尾部,主干结束后还有一个独立函数:它通过 _ud() 解码两个字符串,创建元素并插入当前文档的 head。
这一段没有直接写出标签名和远端 URL。若只搜索明文域名,加载入口容易被漏掉。我们沿着 _ud() 的实现检查,发现它每次取两个十六进制字符,再转换为字符;将常量展开后,加载目标随之明确。
736372697074 解码为 script,另一处常量解码为 https[:]//udeskqlobal[.]com/deeps.js。域名中的 qlobal 以字母 q 开头,检索时应保留这一拼写。加载器将脚本设为异步,再插入页面;执行到该位置且浏览器策略和网络允许时,远端代码便可进入当前文档。
该 URL 对应的载荷为 deeps.js。调查重点从客服 SDK 转向了载荷本身。第三方经典脚本在嵌入文档的上下文执行,它能接触的数据取决于实际运行的页面或 iframe。客服聊天窗口使用 iframe,并不会自动隔离宿主页中加载的脚本。
网页数据采集机制与影响范围
deeps.js 开头先读取 window.location.hostname,并按三个站点规则生成配置 C。要判断哪些页面会被采集,只看这组配置还不够:它限制的是整个脚本,还是其中某个模块,需要继续追踪退出判断的位置。
沿控制流向下检查,我们看到 Cookie 和网页存储读取、启动快照发送,以及表单和认证请求钩子都出现在 if (! C) return; 之前。下面按源码顺序摘取快照发送语句和末尾 XHR 钩子;注释标出了中间省略的代码,对应格式化视图 D:L100、D:L151–L166。
退出判断的位置明确了影响范围:即使 hostname 没有命中三个站点规则,脚本也会先进入数据采集路径并安装钩子,随后才退出地址模块。排查暴露页面时,不能只围绕这三个站点配置查找。
启动时,载荷读取当前网页可访问的 Cookie、localStorage 和 sessionStorage。这些位置可保存登录状态、用户资料和业务数据;如果其中包含仍然有效、可复用的登录令牌,攻击者获取后可能冒用用户会话。脚本还附带顶层页面 URL 和当前文档的 origin,使这些数据与来源页面一起提交。
采集过程逐项容错。跨源读取顶层 URL 失败时,脚本用 x 代替并继续处理其他字段;两类网页存储被序列化为 JSON。Cookie 的范围则以 document.cookie 可读内容为限,HttpOnly Cookie 不在其中。
脚本也为后续提交的数据保留了入口。用户提交表单时,它遍历 input、select 和 textarea,复制非空内容,再继续原提交过程。账号、密码、验证码等页面实际填写的字段都可能进入额外的数据发送路径,泄露后可能被用于登录账户或接管账号。
这条路径通过包装 HTMLFormElement.prototype.submit 和监听捕获阶段的 submit 事件实现。对于直接通过接口提交数据的页面,脚本还包装 fetch 和 XHR:当请求带有正文、URL 命中 login|signin|auth|register|signup|password 等关键词时,复制对应内容并保留原请求调用。fetch 分支另外要求 URL 是字符串,正文来自请求选项;FormData 等对象直接 JSON 序列化时,采集内容可能缺少实际字段。
数据外传机制与后备通道
上述采集入口最终调用同一个 _send()。继续追踪这个函数,可以看到固定接收端 https[:]//udeskqlobal[.]com/c.php。启动快照用 s、o、c、l、ss 字段分别承载页面地址、当前源、可读 Cookie 和两类网页存储;后续表单及认证请求则在各自触发时发送。
函数把 URL 问号后的参数拆出,放入异步 POST 正文,设置 Content-Type: application/x-www-form-urlencoded。下面完整保留发送函数(D:L45–L60):

发送路径还包含图片请求后备:XHR 出错或发送过程发生同步异常时,脚本创建 Image 对象,把带参数的 URL 赋给 src,尝试通过 GET 再次携带数据。URL 被截断为前 8,000 个 JavaScript 字符,较长内容可能不完整。
理解这条路径时,需要区分“请求发送”和“响应读取”。脚本不读取 c.php 的响应;符合简单请求条件的跨源 POST 可以先发出,再由浏览器限制响应读取,因此 CORS 报错与请求发送可以同时发生。排查记录应同时检查 POST 正文和图片 GET 参数,出口策略则分别核对 connect-src 与 img-src。普通表单若引发文档导航,也会影响异步请求能否完成。
至此,网页会话数据和后续提交内容的去向已经清楚。但载荷在站点退出判断之后还保留了另一组操作:识别地址格式、修改页面文字,以及接管复制路径。这些代码把调查进一步引向充值业务。
充值地址替换与剪贴板劫持机制
通过 if (! C) return; 后,脚本进入地址模块。开头的三个 hostname 规则此时有了明确用途:匹配 mgbx[.]com、bikingex[.] 和 bitxex[.]io,为不同页面选择地址和复制按钮的元素选择器。
这些正则没有首尾锚点,匹配范围宽于精确域名比较。页面规则还检查完整 location.href,查询参数或片段里的 deposit、recharge、assets 等关键词也会参与判断。页面、元素和地址格式命中后,脚本每 200 毫秒扫描一次,将识别出的充值地址改为配置值。用户若使用被替换的地址完成有效转账,收款目标就会变为该地址。
三个站点分支共用六个配置值,代码标记为 BTC、EVM、TRON、Solana、LTC 和 DOGE。地址识别只依据字符形态和匹配顺序,不核对用户选择的网络或地址校验码,也可能误识别普通业务标识符。
继续检查复制相关代码,能够看到样本同时干预页面显示与剪贴板内容。这样,用户即使把页面地址与复制结果相互比较,也可能得到一致的篡改值。三条路径分别是:
- 包装剪贴板 API。navigator.clipboard.writeText 先调用 R() 替换参数,再交给原方法。这条路径只受 hostname 配置限制,不再次检查充值页面条件,也不依赖 DOM 扫描已命中元素。
- 替换复制按钮。脚本克隆匹配到的按钮,安装新的 click 监听器并替换原节点。新增监听器阻止默认动作和事件传播,尝试复制共享变量 _cur 中保存的地址。
- 拦截 copy 事件。当 _cur 非空且页面规则成立时,document 上的监听器将复制内容改为 _cur,不检查用户选中的文字是否为地址。
其中,剪贴板 API 包装与 copy 监听器在源码中相邻(D:L260–L275),但触发条件不同:
_cur 保存最后一次实际替换的地址。同屏有多种地址时,后一次替换会覆盖前一次记录,多个按钮可能复制同一个值。若页面初始已经显示配置地址,扫描不会因此初始化 _cur,新增按钮监听器也就不写入内容;克隆保留的 HTML 内联事件属性仍可参与事件处理。
分析中还遇到一处影响行为判断的实现缺陷:脚本试图从 Element.prototype 读取 textContent 的自有属性描述符,而标准属性定义在 Node.prototype。在标准原型关系下,随后访问 .set 会抛出异常。这一分支失败后,catch 会吞掉异常;继续核对其前后的代码可见,轮询已经登记,后续复制钩子仍会按各自条件安装。单个分支的错误没有终止地址劫持模块。
总结
追踪客服脚本尾部的加载器后,我们明确了样本的攻击目标:采集可用于冒用会话或登录账户的数据,同时将充值页面及复制操作中的收款地址改为配置值。前者不受三个站点配置限制,后者按站点和具体复制路径启用,排查时需要覆盖不同的暴露场景。
仍加载相关脚本的业务应停止继续分发,处置暴露凭据,并通过可信后台和交易记录核查充值目标。
建议
- 保全并停止分发污染资源。若生产仍加载相关脚本,保存实际响应、请求发起链、缓存信息和采集时间后尽快阻断;从独立核验的可信版本恢复,并检查站点托管、CDN、构建及标签管理配置。
- 检索加载与外传记录。联合查询恶意域名、两个路径和文件哈希;外传记录同时检查 POST 正文与 GET 参数。排查压缩脚本时也检索加载器中的十六进制 URL,避免只查明文漏检。
- 结束受污染文档并处置暴露凭据。完整关闭相关页面或 WebView 文档,避免重新加载旧资源。根据实际暴露范围,从干净环境撤销会话、轮换令牌和密码;移除 script 标签不会撤销已经安装的钩子和定时器。
- 独立核对充值地址和交易。对执行载荷的页面,以可信渠道核对原始充值地址、相关交易与实际转账目标,依据交易记录评估影响。
- 验证脚本与数据出口限制。结合业务设置脚本来源和完整性控制,分别验证 connect-src、img-src 等策略,针对 udeskqlobal[.]com 限制脚本加载与数据外传。
IOC
域名
udeskqlobal[.]com
URL
https[:]//udeskqlobal[.]com/deeps[.]js
https[:]//udeskqlobal[.]com/c[.]php
钱包地址
BTC: bc1qhzppfj69ywp22swj50jwcfxdamg3ym245srng9
EVM: 0x9B6EcD0023a28E1391c5124eCe578A9751A337b2
TRON: TH4L5YAhhxtC8qALbZKbPZZgausbGi25nF
Solana: AFmCUe3nNbjTaC585CcdA3vvC9iWVR8YunooFKpaQx2Z
LTC: ltc1qwz0zp39ywl34kahvn9lyk7j5x63wsy9tcxhm3w
DOGE: DAoy2w8uvFtZ92q87s9qKEoHbWgV7mVThj
恶意文件
filename: udeskApi.2026-10-16.cached.js
SHA256: 45b4e8f160d8d5177819f6c1dc67acc7abbdc65eeaffc909e668799dc778bcf6
filename: deeps.js
SHA256: 57c1441c4f5bb3260981a2df64f9ff35f117abde0d8667c8c66a047880074c59
关于 MistEye
MistEye 是由 SlowMist 自主研发的 Web3 威胁情报与动态安全监控平台,通过 API 提供开源包生态的恶意活动检测与供应链风险预警能力。
本次行动涉及的全部恶意包及 IOC 已接入 MistEye 威胁检测引擎,开发者可通过 API 对项目依赖进行自动化检测,快速判定是否命中已知恶意包并获取处置建议。