logo

Zeabur 2026 年十月安全事件

攻击者用泄露的内部凭证入侵了共享集群与 GCP 专用服务器,最终读取了存放在 Zeabur 平台数据库中的环境变量。本文说明事件经过、受影响的数据、我们的处置,以及你需要做的事。

Zeabur TeamZeabur Team

本文亦提供 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 的私有配置仓库泄露,泄露途径无法确认。仓库中的凭证以明文保存、长期有效,集群管理接口也对公网开放,见根本原因
本文用语
用语含义
已确认有日志直接记录
研判时间与内容吻合,但缺少直接记录
无法确认没有记录可查,我们一律按已泄露处理
推测只有间接证据支持的可能解释,集中列在尚未证实的推测

你需要做什么

请现在就处理,不必等通知邮件。已泄露的数据仍可能被利用,八月事件后换过的凭证也要再换一次。

所有用户

  1. 更换环境变量中的所有凭证。包括 API 密钥、云密钥、数据库密码、签名密钥与加密密钥。先到服务商处撤销旧的,再创建新的并重新部署。八月后已把环境变量迁移到自己专用服务器的项目,这些变量不在这次平台数据库的读取范围内,但如果主机本身遭到入侵,主机上保存的凭证仍要更换。
  2. 重新登录并重新创建 Access Token。旧的平台访问令牌已全部撤销。到 Access Token 管理页面创建新的令牌,并检查有没有不明请求。
  3. zSend 用户:重新创建 zSend API 密钥。
  4. GitHub 用户:在 GitHub 审计日志中,检查 10 月 15 日 15:05 至 18:54 来自 Zeabur GitHub App 的操作,留意以下几项:
    • 非预期的 clone 或推送
    • 新增的 deploy key
    • 被修改的 webhook
  5. 核对账单。检查各服务自 2026 年 10 月 14 日起的用量与账单,GCP 专用服务器用户请回溯到 9 月 1 日。10 月 14 日是我们所知攻击者最早使用凭证的时间,凭证可能更早就已泄露,如有更早的记录,也请一并检查。

共享集群用户

  1. 在数据库内更换密码。只改 Zeabur 上的环境变量,不会改到数据库内的密码。更换密码也不会让已泄露的数据失效。如果数据库里存有你的用户的密码哈希、登录会话或令牌,请一并撤销并重新生成。
  2. n8n:更换 n8n 加密密钥,并重新创建 n8n 内的所有第三方凭证。
  3. new-api/one-api:撤销上游 AI 服务密钥,并重新生成访问令牌。
  4. PostgreSQL:检查有没有你不认识的角色、函数、触发器、定时任务或扩展。如有疑虑,新建一个数据库,只导入数据。
  5. 台北(tpe1)与香港(hkg1)区域:把数据库备份中的数据按已泄露处理。

GCP 专用服务器用户

把服务器视为已遭入侵:

  1. 备份数据后重建服务器。这是清除后门最可靠的方法。
  2. 如果暂时无法重建,至少做到:
    • 移除 /root/.ssh/authorized_keys 中注释为 @zeabur-pentest 或你不认识的密钥。
    • 检查 google-sudoers 用户组、系统账号、crontab、systemd 服务与 k3s 工作负载。
    • 更换 root 密码,并关闭 SSH 的密码登录。
  3. 更换服务器上的所有凭证,包括你自己的云凭证,并检查对应的账单。
  4. 对照入侵指标检查登录记录,回溯到 2026 年 9 月 1 日。

Hetzner 与 DigitalOcean 专用服务器用户

在控制台检查 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 的 n8n736第三方凭证、用户、项目、变量与 workflow
PostgreSQL(逐表读取)211每张表最多 50,000 条,台北(tpe1)区域没有
new-api/one-api10AI 服务密钥、访问令牌与用户
Redis1名称含 token、secret 等字样的键
MongoDB、MariaDB各 1台北(tpe0)没有命令内容,按全部泄露处理

使用 PostgreSQL 的 n8n 中,我们检查了 607 个,其中 602 个把加密密钥写在环境变量里,因此 n8n 内的第三方凭证相当于以明文泄露。这些读取发生在容器内部,八月事件后轮换的数据库密码挡不住这类读取。

另外,东京(hnd1)区域至少有 2 个 PostgreSQL 自 10 月 14 日 01:51 起被植入了会回连外部的程序,其中一个到 10 月 15 日 16:24 仍在回连。入口是否为八月泄露的密码,无法确认。我们发现时已通知受影响的用户更换凭证。

GCP 专用服务器

攻击者曾以 root 权限登录 101 台服务器,最后一次登录是 10 月 15 日 20:36。攻击者在其中 50 台上加入了自己控制的 SSH 公钥,为之后再次登录留了通道,还在 Zeabur 的 GCP 项目内创建了 5 台虚拟机,挂载了 16 份客户服务器的磁盘拷贝。

这 101 台服务器,我们都按数据可能已泄露、也可能留有后门处理。我们已发邮件通知受影响的用户,并重置了这些服务器的 root 密码。

Hetzner、DigitalOcean、Linode 与腾讯云

用来管理 Hetzner 与 DigitalOcean 客户服务器的令牌写在内部代码与环境变量中,随平台数据库一起泄露。持有令牌就能重置密码、重装系统或复制磁盘。我们在 10 月 16 日 01:09 撤销了全部令牌。两家都没有提供操作审计 API,令牌是否遭使用无法确认。我们只排除了一件事:10 月 15 日 Hetzner 上的重置密码与创建镜像操作,是客户本人和系统定时任务所为。DigitalOcean 没有比对结果。

Linode 的 890 台服务器中,有记录的 847 台没有攻击者登录。腾讯云的管理凭证没有遭使用的记录。

GitHub App

10 月 15 日 15:05,攻击者读取了 Zeabur GitHub App 的私钥。持有这把私钥,就能访问用户授权 Zeabur 访问的仓库。我们在 18:54 轮换了私钥。私钥是否遭使用无法确认:我们没有拿到 GitHub 组织的完整审计日志,向 GitHub Support 申请的记录也始终没有回复。

Zeabur 内部系统

攻击者使用了多组 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 技术,见附录。

事件路径
两条路径在内部网络会合。箭头旁标注的是攻击者在每一步利用的凭证或缺口。
路径 A 共享集群与 AWS
起点
已持有 AWS 密钥与集群管理令牌
获取方式无法确认
管理令牌永不过期,管理接口对公网开放
9 个区域的共享集群
所有服务的环境变量、865 个数据库容器
研判:用权限过大的密钥读取旧集群备份
AWS
机密管理服务的密钥
已确认:读取生产环境机密
Zeabur 机密管理服务
约 53 条生产环境机密
包括内网管理凭证与数据库账号
路径 B GCP 专用服务器
起点
一把旧的 GCP 服务账号密钥
泄露来源无法确认
研判:读取初始化配置中的 root 密码
GCP 专用服务器
101 台服务器的 root 权限
在遭入侵的服务器上,用内网管理凭证加入节点
Zeabur 内部网络
一个带有生产环境权限的节点
内网规则放行连接,再以内部只读账号登录
Zeabur 平台数据库
存放在 Zeabur 的环境变量、账号与项目数据
图 1:攻击者在路径 B 入侵的服务器上,用路径 A 取得的内网凭证加入节点。其实不必先入侵客户服务器,也能加入内网。

路径 A:从共享集群到机密管理服务

  1. 获取凭证。10 月 14 日 01:36,攻击者开始使用 Zeabur 内部的 AWS 密钥,01:40 开始使用共享集群的管理令牌。这两组凭证以明文保存在 Zeabur 的私有配置仓库中,和各集群的连接地址写在同一份配置里。攻击者如何获取,无法确认,推测见尚未证实的推测。
  2. 进入共享集群。管理令牌永不过期,集群的管理接口当时又对公网开放,攻击者因此能从外部进入 9 个区域的共享集群。01:51 起读取部分系统机密,12:39 起范围扩大到所有服务的配置与机密,包括环境变量。有完整读取记录的区域已确认读到内容,其余区域我们一律按已泄露处理。
  3. 读取用户数据库。13:40 起,攻击者进入用户数据库的容器执行读取命令:先是少数 new-api/one-api,15:41 起大量读取 n8n,16:50 起逐表读取部分 PostgreSQL,最后一条命令在 17:04。前后共涉及 865 个数据库服务,并非每条命令都成功。
  4. 从备份获取机密管理服务的密钥。攻击者用集群里另一组权限过大的密钥,读取了一份旧集群的备份(研判),备份里有一组能读取 Zeabur 机密管理服务的密钥。
  5. 读取生产环境机密。10 月 15 日 14:52 至 16:51,攻击者读取了约 53 条生产环境机密(已确认),包括内部网络的管理凭证、平台数据库的账号与 GitHub App 私钥。

路径 B:GCP 专用服务器的 root 权限

  1. 登录服务器。10 月 14 日 13:40 起,攻击者以 root 身份登录 Zeabur 托管在 GCP 上的专用服务器,共 101 台。这些服务器创建时,root 密码以明文写在初始化配置里,配置完成后没有清除。平台自身也要用这个密码登录服务器,所以保存的是明文,而非哈希值。攻击者持有的旧 GCP 密钥能读取这些配置,我们研判密码就是这样泄露的。
  2. 加入 SSH 密钥。10 月 15 日 14:26 起,攻击者用旧 GCP 密钥修改服务器配置,加入自己的 SSH 密钥。15:05,攻击者又从机密管理服务取得一把生产环境的 GCP 密钥。
  3. 换一把密钥再试。我们在 17:17 停用旧密钥,11 分钟后,攻击者改用新取得的密钥再次加入 SSH 密钥。17:31,我们也停用了这一把。

这批登录发生在 10 月 14 日,比路径 A 已知最早的生产环境机密读取(10 月 15 日 14:52)早了一天多,所以路径 B 的起点无法用路径 A 读到的机密来解释。同一批服务器在 9 月 1 日至 5 日也曾有不明来源用 root 密码登录,9 月 5 日当天约 98 台。是否为同一攻击者,无法确认。

两条路径会合

  1. 加入内部网络。10 月 15 日 15:30,攻击者在一台遭入侵的 GCP 服务器上,用路径 A 取得的内网管理凭证,让一个节点加入了 Zeabur 内部网络。
  2. 读取平台数据库。内部网络的规则允许这类节点连接平台数据库。16:10 至 16:47,攻击者以内部只读账号读取了平台数据库(已确认)。
  3. 移除节点。17:58,我们移除了这个节点。

平台数据库遭读取的结论,来自内部网络两端的连接记录与数据库日志:这段时间的 29 个数据库连接都能对应到这个节点,连接中的登录与查询也能逐一追踪,共 8,903 条操作记录。

检测

10 月 15 日 13:56,我们收到用户反馈后才启动调查。这时距攻击者首次使用凭证(10 月 14 日 01:36)约 36 小时,10 月 14 日的攻击活动也持续了 16 个多小时。

这段时间没有任何告警:

  • 攻击者用的是有效凭证,走的是 Zeabur 正式的访问渠道,在记录中和正常的管理操作没有区别。
  • 当时没有针对这类行为的告警,例如管理权限的异常使用、在容器内执行命令、大量读取机密、内网加入新节点,或云密钥从陌生来源调用。

处置

遏制

启动调查后约 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:46Zeabur 管理的专用集群只允许 Zeabur 系统连接
10/16 01:09撤销泄露的 Hetzner 与 DigitalOcean 令牌

事件期间换上的密钥仍遭使用

应急响应当天换上的凭证,有一部分后来仍遭攻击者使用,问题出在集群的每日备份上。每日备份覆盖集群内的所有资源,机密也包括在内,而攻击者在 10 月 15 日 15:04 读取了备份的访问密钥:

  1. 15:40,我们换上新密钥。
  2. 16:00,每日备份收录了这把新密钥。
  3. 18:51,我们删除备份的访问密钥。
  4. 20:30,攻击者使用了这把新密钥。
  5. 21:47,我们再次轮换受影响的凭证。

新密钥被备份收录、之后遭到使用,这两点已确认;攻击者下载了这份备份,则是研判。20:30 用到的密钥,也可能来自攻击者在 18:51 之前就已拿到的备份。

根除与恢复

  • 从 GCP 专用服务器移除攻击者的 SSH 密钥,重置 root 密码,并发邮件通知受影响的用户。
  • 删除攻击者留下的磁盘拷贝、快照与测试资源。
  • 撤销所有用户的平台访问令牌。
  • 停用硬编码在代码中的腾讯云、阿里云与 Linode 凭证。
  • 轮换其余遭读取的生产环境机密,包括平台数据库的账号密码,并撤销其他泄露的凭证。
  • 保全各系统的审计日志。
  • 受影响的功能均已恢复,各功能的影响时段见对服务的影响。

根本原因

攻击者一开始就持有 Zeabur 的集群管理令牌与多组云密钥。这些凭证保存在 Zeabur 的私有配置仓库中,沿用以往的做法以明文保存。最可能的情况是这个配置仓库泄露了,但泄露途径无法确认,推测见尚未证实的推测。

让攻击者进入平台数据库的缺口

  • 管理令牌永不过期。管理接口也对公网开放。令牌在 2024 年 1 月创建后从未轮换,八月事件后的轮换也没有覆盖它。
  • 机密以明文保存。配置仓库、代码、共享集群的服务配置与构建任务中,都有明文保存的密钥。GCP 服务器的初始化配置保存了 root 密码,这个问题我们 9 月 3 日就已发现,事发前还没修复。10 月 3 日开始的机密迁移,事发时也还没合并到主分支。
  • 备份含有全部机密。备份密钥又和其他机密存放在一起,攻击者因此能从备份获取更多凭证,事件期间换上的部分凭证也被后续备份收录。
  • 权限超出实际用途:
    • 只需读取单个存储桶的密钥,实际上能读取整个 AWS 账号内的存储桶。
    • GCP 服务器的默认服务账号拥有项目级的修改权限。
    • 内网规则允许带特定标签的节点连接平台数据库,而内网管理凭证能让新节点直接带上这个标签。
    • 内部只读数据库账号能读取所有数据。
    • 已停用服务的部署密钥,在服务停用四个月后仍然有效。
  • 内部服务与用户服务部署在同一个集群。攻击者读取用户配置时,也一并拿到了内部服务的凭证。
  • 检测与日志不足。攻击持续约 36 小时都没有触发告警,见检测。对象存储、GCP 与 GitHub 的访问记录不完整,部分访问与影响范围无法查明。

与八月事件的关系

这是 Zeabur 不到两个月内的第二起安全事件。许多用户在八月后按我们的指引做了调整,也想知道:既然已经做了这些,为什么还会发生,两起事件之间又有没有关联。

八月后做了什么。我们轮换了当时确认泄露的内部密钥,并停用了 Legacy API Key。产品上,专用服务器的项目可以把环境变量与配置文件迁移到自己的服务器,也可以删除 Zeabur 保存的 SSH 凭证,并查看 SSH 登录记录。八月事件的通知与公告也建议用户轮换凭证,删除存放在 Zeabur 的环境变量与配置文件,并迁移到自己的服务器。

为什么还是发生。八月的轮换没有覆盖配置仓库中以明文保存的集群管理令牌与 AWS 密钥,GCP 服务器初始化配置中的 root 密码也还没修复,而这次攻击者用的正是这些凭证。八月事件报告中写的“已停用或轮换所有内部管理密钥”并不完整,我们在此更正。

复盘

做得好的地方

  • 按八月指引完成迁移的项目,环境变量与配置文件只存放在用户自己的服务器上,不在这次平台数据库遭读取的数据中。
  • 启动调查后约 4 小时,我们移除了攻击者的内网节点,当天也封禁了集群管理接口与 GCP 专用服务器的公网连接。
  • 内部网络两端的连接记录与数据库日志完整,平台数据库的读取范围可以逐条确认。

做得不好的地方

  • 八月事件后的轮换没有覆盖这次被使用的凭证,八月事件报告的说法也不完整,见与八月事件的关系。
  • 9 月 3 日已发现 GCP 服务器的初始化配置保存了 root 密码,事发前没有修复。
  • 应急响应当天换上的密钥被每日备份收录,部分后来仍遭使用,见事件期间换上的密钥仍遭使用。
  • 攻击持续约 36 小时,最后是靠用户反馈才发现,见检测。

改进措施

Zeabur 将在 2026 年 12 月 31 日停止运营,以下只列出已落实的改进。

项目状态
撤销遭使用的集群管理令牌,管理接口只允许 Zeabur 系统连接已完成
移除 GCP 服务器初始化配置中的 root 密码,封禁公网 SSH已完成
AWS 密钥换成权限更小的新密钥已完成
只允许指定的服务连接平台数据库已完成
集群备份不再保存明文机密,备份密钥与其他机密分开存放已完成
新增告警:管理权限的异常使用、在容器内执行命令、大量读取机密或数据库、内网加入新节点、云密钥从陌生来源调用初步完成

尚未查明的事项

调查限制

以下事项受现有记录所限,到本文定稿时仍无法查明。无法排除遭访问的数据与凭证,我们都按已泄露处理。

  • 最初的凭证从哪里来。GitHub 审计日志只记录压缩包下载,没有 clone 操作。记录显示,8 月 30 日与 9 月 2 日有人用员工的 GitHub 授权下载了配置仓库,但无法确认是谁。我们向 GitHub Support 申请了完整记录,最终没有得到回复。
  • 旧 GCP 密钥从哪里泄露。我们查过 git 历史、机密管理服务与旧集群备份,都没有找到泄露点。9 月初用 root 密码登录 GCP 专用服务器的 31.57.201.201 是否为同一攻击者,也没有结论。
  • 共享集群数据库实际被读走多少。审计日志保留了命令,没有记录输出,我们只知道攻击者执行过哪些命令。
  • 备份与存储对象的下载范围。遭入侵主机上的证据确认,攻击者在 10 月 15 日 15:42 通过预签名下载链接获取了客户数据库备份。这与含有内部凭证的集群备份是两回事。台北(tpe1)与香港(hkg1)的数据库备份,以及源代码上传的存储桶,只确认对象列表被列出过。当时没有开启对象访问日志,是否遭下载无法确认。旧集群备份是否遭读取,同样没有直接证据,仍维持研判。
  • GCP 资源的读取范围。GCP 项目当时没有开启数据访问审计日志,只有写入操作的记录,事后也无法通过其他方式补查。
  • Hetzner 与 DigitalOcean 令牌是否遭使用。两家都没有提供操作审计 API。除了 10 月 15 日 Hetzner 上已确认是客户本人和系统定时任务所为的操作,其余无法确认。
  • GitHub App 私钥是否遭使用。我们没有拿到 GitHub 组织的完整审计日志,GitHub Support 也没有回复。
  • 平台数据库的查询返回了什么。我们已确认攻击者执行的查询、其中 7 个主要查询返回的条数,以及有 14 个集合返回了数据,主要查询都读到了最后一条。数据库日志没有记录返回内容,我们也无从得知攻击者之后如何保存或使用这些数据。
  • 部分集群的活动范围。台北(tpe0)集群,以及攻击者曾创建资源的专用集群,审计日志不完整,之后也没有再调查。
  • 10 月 14 日之前发生了什么。共享集群与 AWS 的记录中,10 月 14 日 01:36 之前没有使用有效凭证的活动。后来滥用凭证的部分 IP,10 月 10 日起已出现在未登录的 Zeabur API 访问记录中,但这些 IP 可能是多人共用的代理服务器,仅凭 IP 相同无法确认是同一人。10 月 13 日另有针对专用服务器的 SSH 登录尝试,均未成功。这段时间是否有数据泄露,无法确认。

尚未证实的推测

以下是我们认为最可能的解释。它们有间接证据支持,但缺少直接记录,不能作为事实引用。到本文定稿时,这些推测既没有得到证实,也没有被推翻。

推测 1:最初的凭证来自八月事件

  • 推测:攻击者利用八月事件泄露的 GitHub App 私钥,获取了 Zeabur 私有配置仓库的内容,包括 10 月 14 日使用的 AWS 密钥与集群管理令牌。没有任何证据直接证明这条路径,以下只是时间与能力上吻合的间接线索。
  • 换了与没换的凭证:
    • GitHub App 私钥已更换。八月事件中,这把私钥在 8 月 27 日遭读取。根据 GitHub 审计日志与机密管理服务的版本时间,私钥在 8 月 31 日更换,可被利用的时间窗口约 4 天。这个 App 安装在 Zeabur 的 GitHub 组织上,持有私钥就能读取组织内的所有仓库。
    • 配置仓库中的明文凭证没有更换。10 月 14 日攻击者最先使用的 AWS 密钥与集群管理令牌,8 月 27 日时已经以明文存在于配置仓库中。八月事件后我们只更换了私钥,没有更换这些凭证,到 10 月 15 日应急响应时才停用。所以即使私钥已经更换,只要有人在 8 月 27 日至 31 日间拿到了仓库内容,里面的凭证到 10 月都还有效。
  • 其他支持的线索:
    • 攻击者尝试读取的部分内部机密名称,只出现在另一个内部仓库中。攻击者可能同时持有两个仓库的内容,这与 App 私钥的组织级权限相符。
    • 10 月 14 日 01:36 之前,共享集群与 AWS 没有有效凭证的使用记录,后来滥用凭证的 IP 在 Zeabur API 上也都没有登录。这符合“只持有仓库中的凭证”的情况。
  • 不支持的线索:八月事件与这次事件的攻击者 IP 没有重叠。
  • 为什么无法证实:我们向 GitHub Support 申请了 8 月 27 日至 31 日间这个 App 签发的访问令牌、配置仓库的 clone 与下载记录,以及 8 月 30 日与 9 月 2 日用员工授权下载配置仓库的来源,GitHub Support 最终没有回复。员工授权的下载,也不能排除是另一条获取渠道。

推测 2:10 月 14 日前的探测是同一攻击者的侦察

  • 推测:10 月 10 日至 13 日的匿名探测与 SSH 尝试,是同一攻击者在使用凭证前的侦察。
  • 支持的线索:
    • 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 密钥。
  • 为什么无法证实:攻击者大量使用代理服务器,同一个 IP 可能由不同的人共用,仅凭 IP 相同无法确认是同一人。

推测 3:10 月 15 日的部署密钥访问是攻击者所为

  • 推测:10 月 15 日 15:02,一把已停用服务的部署密钥读取了配置仓库,研判为攻击者所为。
  • 支持的线索:这次访问发生在攻击者读取生产环境机密期间(14:52 至 16:51),而密钥所属的服务已停用四个月,不应有正常访问。
  • 为什么无法证实:没有记录能把这次访问直接关联到攻击者。

附录

时间线

攻击者活动与我们的响应
10 月 14 日至 15 日,各系统上的攻击者活动与我们的处置,按 UTC 时间绘制
攻击者的操作
攻击者有访问权限、没有连续记录
我们的处置
图 2:每个系统上方是攻击者的活动,下方是我们的处置。从首次已知的凭证使用(10/14 01:36)到启动调查约 36 小时,这段时间的访问没有触发告警。启动调查后约 4 小时,攻击者的内网节点已被移除。
时间(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 日。

类型指标出现位置置信度
IP23.106.46.239集群访问、云 API、SSH 登录85
IP102.244.78.57云 API、GCP 配置修改85
IP103.237.102.191集群访问、云 API85
IP103.112.139.162首次使用集群管理令牌85
IP45.146.232.28验证 AWS 密钥85
IP216.98.11.198、45.58.38.175专用服务器 SSH 登录85
IP52.220.72.188被植入程序的 PostgreSQL 回连地址85
IP31.57.201.2019 月初用 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 对照

按 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 内部系统

术语说明

  • 共享集群(Shared Cluster):多位用户的服务一起运行的 Kubernetes 集群。我们已在 2026 年 2 月公告下线,受影响的服务都是在公告前部署的。
  • 专用服务器(Dedicated Server):由 Zeabur 托管、只运行单个用户服务的服务器。
  • 管理令牌:能管理整个集群的凭证,持有者可以读取所有服务的配置,并在任何容器内执行命令。
  • 机密管理服务:Zeabur 用来集中保存生产环境机密的 AWS 服务。
  • 内部网络:连接 Zeabur 生产环境服务的私有网络(Tailscale),平台数据库只接受来自这个网络的连接。
  • 平台数据库:保存所有账号、项目、服务与环境变量的 Zeabur 生产数据库。

支持与费用

如需帮助,或发现异常访问与不明费用,请通过 Zeabur Support 联系我们。联系前请先撤销相关凭证,只提供脱敏后的信息,不要在工单或公开渠道贴出仍然有效的密钥或密码。

泄露的凭证遭盗用时,你可能需要承担额外的费用,对此我们深表歉意。以目前的财务状况,Zeabur 无法承担本事件引起的第三方服务费用。多数云服务与 API 服务商都设有申诉或减免渠道,你可以把这份报告附给服务商作为说明。服务商要求其他证明时,请通过工单告诉我们,我们会尽力提供。账户余额退款不受本事件影响,详见10 月安全事件后续处理说明。

Zeabur 已宣布将于 2026 年 12 月 31 日停止运营,这是运营上的决定。在此之前,我们会继续处理本事件的支持申请。

攻击者开始使用凭证约 36 小时后,我们才通过用户的反馈得知这起事件。保护你存放在 Zeabur 的凭证是我们的责任,我们没有做到。我们向所有受影响的用户致歉。

Zeabur 团队