攻击者用泄露的内部凭证入侵了共享集群与 GCP 专用服务器,最终读取了存放在 Zeabur 平台数据库中的环境变量。本文说明事件经过、受影响的数据、我们的处置,以及你需要做的事。
本文亦提供 English、繁體中文、日本語、Español和Bahasa Indonesia。
本文所有时间均为协调世界时,即 UTC。
2026 年 10 月 15 日 13:56,我们收到用户反馈,启动调查。事后比对记录才发现,攻击者早在 10 月 14 日 01:36 就开始使用 Zeabur 的内部凭证,比我们发现早了约 36 小时。这段时间里,攻击者用的都是有效凭证,走的也是 Zeabur 正式的访问渠道,没有触发任何告警。
攻击者从两条路径进入,10 月 15 日在 Zeabur 的内部网络会合,读取了平台数据库。这次被使用的凭证,都不在八月事件后的轮换范围内。
| 项目 | 内容 |
|---|---|
| 状态 | 最终版 |
| 你需要做什么 | 更换存放在 Zeabur 的所有密码与密钥,八月事件后换过的也要再换一次,见你需要做什么 |
| 事件持续时间 | 10 月 14 日 01:36 至 10 月 15 日 21:05(记录中攻击者最后的活动) |
| 发现 | 10 月 15 日 13:56 收到用户反馈,距攻击者首次使用凭证约 36 小时,见检测 |
| 遏制 | 10 月 15 日 17:58 移除攻击者的内网节点,20:36 封禁 GCP 专用服务器的公网 SSH,所有用户均已退出登录 |
| 影响 | 平台数据库中的环境变量与账号数据、共享集群上的服务与数据库、101 台 GCP 专用服务器。八月后已迁移到自己服务器的环境变量不在读取范围内,见影响范围 |
| 最可能的原因 | Zeabur 的私有配置仓库泄露,泄露途径无法确认。仓库中的凭证以明文保存、长期有效,集群管理接口也对公网开放,见根本原因 |
| 用语 | 含义 |
|---|---|
| 已确认 | 有日志直接记录 |
| 研判 | 时间与内容吻合,但缺少直接记录 |
| 无法确认 | 没有记录可查,我们一律按已泄露处理 |
| 推测 | 只有间接证据支持的可能解释,集中列在尚未证实的推测 |
请现在就处理,不必等通知邮件。已泄露的数据仍可能被利用,八月事件后换过的凭证也要再换一次。
把服务器视为已遭入侵:
/root/.ssh/authorized_keys 中注释为 @zeabur-pentest 或你不认识的密钥。google-sudoers 用户组、系统账号、crontab、systemd 服务与 k3s 工作负载。在控制台检查 10 月 14 日之后 root 密码是否遭到重置、系统是否遭到重装,并按上方 GCP 的检查项,确认没有不明的登录方式。
| 系统 | 受影响的数据 | 范围 | 确定程度 |
|---|---|---|---|
| 平台数据库 | 存放在 Zeabur 的服务环境变量(名称与值) | 3,218,965 条 | 已确认 |
| 平台数据库 | 账号(电子邮箱、用户名、手机号码等)、项目、环境与服务数据 | 账号 321,810 条 | 已确认 |
| 平台数据库 | zSend API 密钥(明文) | 566 个,已撤销 | 已确认 |
| 平台数据库 | 平台访问令牌 | 11,536 条,仅存哈希值,无法还原,已全部撤销 | 已确认 |
| 共享集群 | 所有服务的环境变量与机密 | 9 个区域 | 部分已确认,其余无法确认 |
| 共享集群 | 数据库内容 | 865 个数据库服务 | 研判(见下方说明) |
| GCP 专用服务器 | 服务器上的所有数据 | 101 台,92 位用户 | 已确认登录 |
| Hetzner、DigitalOcean 专用服务器 | 服务器的管理权限 | 359 台与 48 台 | 无法确认是否遭使用 |
| GitHub App | 访问用户授权的 GitHub 仓库 | 10/15 15:05 至 18:54 | 无法确认是否遭使用 |
| 用户数据库备份 | 台北(tpe1)与香港(hkg1)区域的备份 | 两个区域 | 无法确认是否遭下载 |
各系统的详细情况如下。
10 月 15 日 16:10 至 16:47,攻击者读取了上表列出的数据。账号数据包括个人主页上的信息,例如电子邮箱、用户名与手机号码。双因素认证与通行密钥的数据表只被查询了统计信息,没有读取内容的记录。平台访问令牌只存哈希值,我们仍已全部撤销。
攻击者的主要目标是能直接使用的 API 密钥,尤其是 AI 服务的密钥:在环境变量与配置文件中搜索 API 密钥与私钥,大量读取 n8n 与 new-api/one-api 中的凭证,还尝试用 Zeabur 的 AWS 密钥调用 Amazon Bedrock。这是我们从命令内容与后续行为中观察到的。攻击者也读取了账号数据,凡是读到的数据,我们都按已泄露处理。
八月事件后,Zeabur 为专用服务器用户提供了指引与一键迁移功能:轮换凭证,删除存放在 Zeabur 的环境变量与配置文件,改存到自己的服务器上。已完成迁移的项目,这些数据只存在用户自己的服务器上,不在这次的读取范围内。尚未迁移的项目,环境变量仍存放在 Zeabur,这次也遭到读取。主机本身遭入侵造成的泄露不在此列,遭入侵的 GCP 专用服务器仍要按你需要做什么处理。
10 月 15 日 16:12 至 17:19,攻击者以两个账号的身份调用 Zeabur API,读取账号与项目列表,其中一个是 Zeabur 员工的账号。这些请求没有修改任何资源。
攻击者读取了用来签发登录凭证的密钥,我们研判登录凭证是用这把密钥伪造的。平台访问令牌只存哈希值,攻击者又到 16:47 才大量读取令牌,无法解释 16:12 就开始的冒用。20:25,我们轮换了签名密钥,所有用户均已退出登录。
攻击者在 865 个数据库的容器里执行了读取命令。审计日志只记录命令、不记录输出,部分命令也因报错而失败,所以每个数据库实际被读走多少,无法确认。下表是我们根据命令内容做出的判断:
| 对象 | 数量 | 被读取的数据 |
|---|---|---|
| 使用 PostgreSQL 的 n8n | 736 | 第三方凭证、用户、项目、变量与 workflow |
| PostgreSQL(逐表读取) | 211 | 每张表最多 50,000 条,台北(tpe1)区域没有 |
| new-api/one-api | 10 | AI 服务密钥、访问令牌与用户 |
| Redis | 1 | 名称含 token、secret 等字样的键 |
| MongoDB、MariaDB | 各 1 | 台北(tpe0)没有命令内容,按全部泄露处理 |
使用 PostgreSQL 的 n8n 中,我们检查了 607 个,其中 602 个把加密密钥写在环境变量里,因此 n8n 内的第三方凭证相当于以明文泄露。这些读取发生在容器内部,八月事件后轮换的数据库密码挡不住这类读取。
另外,东京(hnd1)区域至少有 2 个 PostgreSQL 自 10 月 14 日 01:51 起被植入了会回连外部的程序,其中一个到 10 月 15 日 16:24 仍在回连。入口是否为八月泄露的密码,无法确认。我们发现时已通知受影响的用户更换凭证。
攻击者曾以 root 权限登录 101 台服务器,最后一次登录是 10 月 15 日 20:36。攻击者在其中 50 台上加入了自己控制的 SSH 公钥,为之后再次登录留了通道,还在 Zeabur 的 GCP 项目内创建了 5 台虚拟机,挂载了 16 份客户服务器的磁盘拷贝。
这 101 台服务器,我们都按数据可能已泄露、也可能留有后门处理。我们已发邮件通知受影响的用户,并重置了这些服务器的 root 密码。
用来管理 Hetzner 与 DigitalOcean 客户服务器的令牌写在内部代码与环境变量中,随平台数据库一起泄露。持有令牌就能重置密码、重装系统或复制磁盘。我们在 10 月 16 日 01:09 撤销了全部令牌。两家都没有提供操作审计 API,令牌是否遭使用无法确认。我们只排除了一件事:10 月 15 日 Hetzner 上的重置密码与创建镜像操作,是客户本人和系统定时任务所为。DigitalOcean 没有比对结果。
Linode 的 890 台服务器中,有记录的 847 台没有攻击者登录。腾讯云的管理凭证没有遭使用的记录。
10 月 15 日 15:05,攻击者读取了 Zeabur GitHub App 的私钥。持有这把私钥,就能访问用户授权 Zeabur 访问的仓库。我们在 18:54 轮换了私钥。私钥是否遭使用无法确认:我们没有拿到 GitHub 组织的完整审计日志,向 GitHub Support 申请的记录也始终没有回复。
攻击者使用了多组 Zeabur 的 AWS 密钥。大多数请求遭到拒绝,但攻击者列出了两个区域的用户数据库备份与源代码上传的内容,是否下载无法确认。攻击者调用 Amazon Bedrock 的尝试全部失败,没有产生费用。
| 功能 | 影响时段(UTC) | 当前状态 |
|---|---|---|
| 登录 | 10/15 20:25 起需重新登录 | 正常 |
| zSend 与系统邮件(含登录链接) | 10/15 20:00–22:02 | 已恢复,zSend 密钥需重新创建 |
| GitHub 登录与部署 | 10/15 18:54–22:49 | 已恢复 |
| 构建 | 10/15 20:05–22:56,中国区至 10/16 01:44 | 已恢复 |
| 数据库备份 | 10/15 20:33–22:13 | 已恢复 |
| GCP 专用服务器管理 | 10/15 17:31–20:35 | 已恢复,只能使用网页 SSH |
| 专用服务器自动续费 | 腾讯云 10/15 22:55–10/16 01:08 失败 154 次 | 已恢复,扣款已退回账户余额 |
| 腾讯云重置密码、SSH 登录记录 | 10/15 起 | 已恢复 |
| Linode 专用 Kubernetes 集群 | 10/15 起 | 已恢复 |
攻击者走了两条路径:路径 A 从共享集群进入 Zeabur 的 AWS 与机密管理服务,路径 B 取得了 GCP 专用服务器的 root 权限。10 月 15 日,两条路径在 Zeabur 的内部网络会合。各步骤对应的 MITRE ATT&CK 技术,见附录。
这批登录发生在 10 月 14 日,比路径 A 已知最早的生产环境机密读取(10 月 15 日 14:52)早了一天多,所以路径 B 的起点无法用路径 A 读到的机密来解释。同一批服务器在 9 月 1 日至 5 日也曾有不明来源用 root 密码登录,9 月 5 日当天约 98 台。是否为同一攻击者,无法确认。
平台数据库遭读取的结论,来自内部网络两端的连接记录与数据库日志:这段时间的 29 个数据库连接都能对应到这个节点,连接中的登录与查询也能逐一追踪,共 8,903 条操作记录。
10 月 15 日 13:56,我们收到用户反馈后才启动调查。这时距攻击者首次使用凭证(10 月 14 日 01:36)约 36 小时,10 月 14 日的攻击活动也持续了 16 个多小时。
这段时间没有任何告警:
启动调查后约 4 小时,我们移除了攻击者的内网节点。10 月 15 日至 16 日的处置如下:
| 时间(10 月 15 日) | 处置 |
|---|---|
| 14:43–15:56 | 共享集群的管理接口只允许 Zeabur 系统连接 |
| 15:32 | 撤销遭使用的集群管理令牌,21:47 再轮换一次 |
| 17:17、17:31 | 停用攻击者使用的两把 GCP 密钥 |
| 17:58 | 移除攻击者的内网节点,并撤销创建该节点的凭证 |
| 18:51 | 删除集群备份的访问密钥 |
| 18:54 | 轮换 GitHub App 私钥、支付服务密钥与 GitHub OAuth 密钥 |
| 18:55 | 移除 GCP 服务器初始化配置中的 root 密码 |
| 20:05–21:22 | 停用 24 组已泄露或无法排除泄露的 AWS 密钥,换上权限更小的新密钥 |
| 20:25 | 轮换登录签名密钥,所有用户退出登录 |
| 20:34–20:36 | 移除 GCP 服务器默认服务账号的权限,封禁 GCP 服务器的公网 SSH |
| 20:47 | 撤销全部 566 个 zSend API 密钥 |
| 21:46 | Zeabur 管理的专用集群只允许 Zeabur 系统连接 |
| 10/16 01:09 | 撤销泄露的 Hetzner 与 DigitalOcean 令牌 |
应急响应当天换上的凭证,有一部分后来仍遭攻击者使用,问题出在集群的每日备份上。每日备份覆盖集群内的所有资源,机密也包括在内,而攻击者在 10 月 15 日 15:04 读取了备份的访问密钥:
新密钥被备份收录、之后遭到使用,这两点已确认;攻击者下载了这份备份,则是研判。20:30 用到的密钥,也可能来自攻击者在 18:51 之前就已拿到的备份。
攻击者一开始就持有 Zeabur 的集群管理令牌与多组云密钥。这些凭证保存在 Zeabur 的私有配置仓库中,沿用以往的做法以明文保存。最可能的情况是这个配置仓库泄露了,但泄露途径无法确认,推测见尚未证实的推测。
这是 Zeabur 不到两个月内的第二起安全事件。许多用户在八月后按我们的指引做了调整,也想知道:既然已经做了这些,为什么还会发生,两起事件之间又有没有关联。
八月后做了什么。我们轮换了当时确认泄露的内部密钥,并停用了 Legacy API Key。产品上,专用服务器的项目可以把环境变量与配置文件迁移到自己的服务器,也可以删除 Zeabur 保存的 SSH 凭证,并查看 SSH 登录记录。八月事件的通知与公告也建议用户轮换凭证,删除存放在 Zeabur 的环境变量与配置文件,并迁移到自己的服务器。
为什么还是发生。八月的轮换没有覆盖配置仓库中以明文保存的集群管理令牌与 AWS 密钥,GCP 服务器初始化配置中的 root 密码也还没修复,而这次攻击者用的正是这些凭证。八月事件报告中写的“已停用或轮换所有内部管理密钥”并不完整,我们在此更正。
Zeabur 将在 2026 年 12 月 31 日停止运营,以下只列出已落实的改进。
| 项目 | 状态 |
|---|---|
| 撤销遭使用的集群管理令牌,管理接口只允许 Zeabur 系统连接 | 已完成 |
| 移除 GCP 服务器初始化配置中的 root 密码,封禁公网 SSH | 已完成 |
| AWS 密钥换成权限更小的新密钥 | 已完成 |
| 只允许指定的服务连接平台数据库 | 已完成 |
| 集群备份不再保存明文机密,备份密钥与其他机密分开存放 | 已完成 |
| 新增告警:管理权限的异常使用、在容器内执行命令、大量读取机密或数据库、内网加入新节点、云密钥从陌生来源调用 | 初步完成 |
以下事项受现有记录所限,到本文定稿时仍无法查明。无法排除遭访问的数据与凭证,我们都按已泄露处理。
31.57.201.201 是否为同一攻击者,也没有结论。以下是我们认为最可能的解释。它们有间接证据支持,但缺少直接记录,不能作为事实引用。到本文定稿时,这些推测既没有得到证实,也没有被推翻。
103.237.102.191:10 月 10 日 18:27 未登录浏览 Zeabur,10 月 14 日用管理令牌访问共享集群。23.106.46.239:10 月 12 日 12:52 起未登录大量尝试 Zeabur API,10 月 13 日尝试 SSH 登录专用服务器,10 月 14 日 01:36 首次使用泄露的 AWS 密钥。| 时间(UTC) | 事件 |
|---|---|
| 2024 年 1 月 10 日 | 创建共享集群的管理令牌,永不过期 |
| 2026 年 1 月 20 日 | 管理令牌以明文写入配置仓库 |
| 8 月 27 日 | 八月事件中,GitHub App 私钥遭读取,与本事件的关联为推测 |
| 8 月 30 日、9 月 2 日 | 配置仓库以员工的 GitHub 授权被下载为压缩包,下载者无法确认 |
| 8 月 31 日 | 更换 GitHub App 私钥,配置仓库中的明文凭证没有轮换 |
| 9 月 1–5 日 | 不明来源用 root 密码登录约 98 台 GCP 专用服务器 |
| 9 月 3 日 | 发现 GCP 服务器的初始化配置保存了 root 密码,事发前未修复 |
| 10 月 10 日 18:27 | 后来用于滥用凭证的 IP 首次出现在 Zeabur API 访问记录中(未登录) |
| 10 月 13 日 21:27 | 攻击者 IP 尝试 SSH 登录 3 台专用服务器,至 23:04,全部失败 |
| 10 月 14 日 01:36 | 攻击者首次使用 Zeabur 的 AWS 密钥 |
| 10 月 14 日 01:40 | 攻击者首次用管理令牌访问共享集群 |
| 10 月 14 日 12:39 | 攻击者读取共享集群所有服务的配置与机密 |
| 10 月 14 日 13:40 | 攻击者开始在数据库容器内读取数据,同时开始登录 GCP 专用服务器 |
| 10 月 14 日 17:04 | 数据库容器内的最后一条命令 |
| 10 月 15 日 13:56 | 收到用户反馈后,启动调查 |
| 10 月 15 日 14:43 | 开始限制共享集群管理接口的连接来源 |
| 10 月 15 日 14:52 | 攻击者开始读取约 53 条生产环境机密,至 16:51 |
| 10 月 15 日 15:02 | 已停用服务的部署密钥读取配置仓库(推测为攻击者) |
| 10 月 15 日 15:30 | 攻击者让一个节点加入 Zeabur 内部网络 |
| 10 月 15 日 15:42 | 攻击者下载 Zeabur 对象存储中的用户数据库备份 |
| 10 月 15 日 16:06 | 攻击者在获取的数据中搜索 API 密钥,至 18:13 |
| 10 月 15 日 16:10 | 攻击者开始读取平台数据库,至 16:47 |
| 10 月 15 日 16:12 | 攻击者开始冒用账号调用 API,至 17:19 |
| 10 月 15 日 17:58 | 移除攻击者的内网节点 |
| 10 月 15 日 19:50 | 攻击者第二波登录 GCP 专用服务器,至 20:36 |
| 10 月 15 日 20:25 | 轮换登录签名密钥,所有用户退出登录 |
| 10 月 15 日 20:36 | 封禁 GCP 专用服务器的公网 SSH,攻击者的登录停止 |
| 10 月 15 日 20:48 | 状态页更新,说明平台数据库与专用服务器也受到影响 |
| 10 月 15 日 21:01 | 攻击者尝试访问共享集群节点,遭拒绝 |
| 10 月 15 日 21:05 | 目前观察到的攻击者最后活动(AWS) |
| 10 月 16 日 01:09 | 撤销 Hetzner 与 DigitalOcean 令牌 |
如果在你的系统或服务商的记录中发现下列指标,请把相关凭证按已泄露处理,并联系我们。攻击者大量使用轮换的代理服务器,下表只列出有代表性的地址。置信度采用 STIX 的 0 到 100 分值:已确认为 85,研判为 60,无法确认为 30。机器可读的版本见 STIX 2.1 文件,其中 IP 指标的有效期至 2027 年 1 月 13 日。
| 类型 | 指标 | 出现位置 | 置信度 |
|---|---|---|---|
| IP | 23.106.46.239 | 集群访问、云 API、SSH 登录 | 85 |
| IP | 102.244.78.57 | 云 API、GCP 配置修改 | 85 |
| IP | 103.237.102.191 | 集群访问、云 API | 85 |
| IP | 103.112.139.162 | 首次使用集群管理令牌 | 85 |
| IP | 45.146.232.28 | 验证 AWS 密钥 | 85 |
| IP | 216.98.11.198、45.58.38.175 | 专用服务器 SSH 登录 | 85 |
| IP | 52.220.72.188 | 被植入程序的 PostgreSQL 回连地址 | 85 |
| IP | 31.57.201.201 | 9 月初用 root 密码登录 GCP 专用服务器,与本事件的关联无法确认 | 30 |
| SSH 密钥 | 注释 *@zeabur-pentest,指纹 SHA256:EdBc0uephoOMemIRKK0SRV2TRR45n52tJm1yErVU1iM | 攻击者加入专用服务器的密钥 | 85 |
| User-Agent | 同时包含 Boto3/1.43.111 与 os/linux#6.12.86+deb13-amd64 | 攻击者使用 AWS 密钥的客户端。单独匹配容易误报,请结合来源 IP 与密钥判断 | 60 |
按 MITRE ATT&CK 的战术排列。
| 战术 | 技术 | 本文对应位置 |
|---|---|---|
| 初始访问 | T1078.004 有效账号:云账号 | 路径 A 第 1 步 |
| 初始访问 | T1133 外部远程服务 | 两条路径会合第 1 步 |
| 执行 | T1609 容器管理命令 | 路径 A 第 3 步 |
| 持久化 | T1098.004 账号操纵:SSH 授权密钥 | 路径 B 第 2、3 步 |
| 防御规避 | T1578.002 修改云计算基础设施:创建云实例 | GCP 专用服务器 |
| 防御规避 | T1578.001 修改云计算基础设施:创建快照 | GCP 专用服务器 |
| 凭证访问 | T1552.001 不安全的凭证:文件中的凭证 | 路径 A 第 1 步 |
| 凭证访问 | T1552.007 不安全的凭证:容器 API | 路径 A 第 2 步 |
| 凭证访问 | T1552 不安全的凭证 | 路径 B 第 1 步 |
| 凭证访问 | T1555.006 密码存储中的凭证:云机密管理存储 | 路径 A 第 5 步 |
| 凭证访问 | T1606 伪造 Web 凭证 | 冒用账号 |
| 凭证访问 | T1110 暴力破解(推测) | 10 月 14 日之前的 SSH 尝试 |
| 发现 | T1580 云基础设施发现 | Zeabur 内部系统 |
| 横向移动 | T1021.004 远程服务:SSH | 路径 B 第 1 步 |
| 收集 | T1530 云存储中的数据 | 路径 A 第 4 步 |
| 收集 | T1213.006 信息存储库中的数据:数据库 | 两条路径会合第 2 步 |
| 影响 | T1496.004 资源劫持:云服务劫持(未成功) | Zeabur 内部系统 |
如需帮助,或发现异常访问与不明费用,请通过 Zeabur Support 联系我们。联系前请先撤销相关凭证,只提供脱敏后的信息,不要在工单或公开渠道贴出仍然有效的密钥或密码。
泄露的凭证遭盗用时,你可能需要承担额外的费用,对此我们深表歉意。以目前的财务状况,Zeabur 无法承担本事件引起的第三方服务费用。多数云服务与 API 服务商都设有申诉或减免渠道,你可以把这份报告附给服务商作为说明。服务商要求其他证明时,请通过工单告诉我们,我们会尽力提供。账户余额退款不受本事件影响,详见10 月安全事件后续处理说明。
Zeabur 已宣布将于 2026 年 12 月 31 日停止运营,这是运营上的决定。在此之前,我们会继续处理本事件的支持申请。
攻击者开始使用凭证约 36 小时后,我们才通过用户的反馈得知这起事件。保护你存放在 Zeabur 的凭证是我们的责任,我们没有做到。我们向所有受影响的用户致歉。
Zeabur 团队