2003 年 11 月 20 日晚,Debian 的 master 服务器接连发生 Linux 内核故障,起初看起来只是单台机器出了问题。随后,管理员发现 murphy 也反复产生同类 oops,也就是内核进入无效内部状态时给出的报告。两套运行已久的系统出现相同故障,硬件原因便很难成立。文件系统监控同时报告,/sbin/init 已被替换。到 22:00 UTC,管理员确认 Debian 基础设施已落入攻击者控制。[2][4]
最终确认受影响的主机共有四台:klecker、master、murphy 和 gluck。它们共同运行缺陷跟踪、邮件列表、Web 与 CVS 服务、开发者页面、质量保证系统和安全相关服务。攻击者在每台机器上都取得 root 权限,并安装了 SucKIT rootkit。Debian 的软件包归档没有遭到改动。[1][2]
把这起事件称作一次“失败”的攻击,会漏掉真正发生的损失。开发工作停摆,凭据可信度遭到破坏,机器需要重装,安装器项目也失去了部分构建的访问权限。事件中有三道彼此独立的界线,分别失守或守住:
- 一名贡献者被盗的身份凭据打开了第一道门。
- 一处本地内核漏洞把普通账户提升为 root。
- 关键证据留存在失陷主机之外,因此软件包完整性仍可核验。
上方的 DebConf3 合影摄于四个月前,当时 Lars Wirzenius 在奥斯陆把 Debian 贡献者聚到同一幅画面里。[8] 这张照片让事件中的“账户”回到真实背景:每份凭据都对应分布式社群中的一个人,共享基础设施又把一段段个人信任关系连接起来。
因此,事后复盘所要追问的,不能只停留在 攻击者如何在四台服务器上取得 root 权限? 更要追问 入侵为何扩散到这一范围,运维人员如何发现异常,事后又凭什么对归档作出经得起核验的判断?
一份凭据串起了项目内的入侵路线
Debian 重建的时间线始于 11 月 19 日约 17:00 UTC。有人使用此前嗅探到的一名无特权开发者账户密码登录 klecker。几分钟内,攻击者经由 HTTP 下载本地漏洞利用程序的源代码,取得 root 权限并安装 SucKIT。调查人员后来在取证过程中找到了一个经 Burneye 混淆的漏洞利用二进制程序。同一套开发者凭据也能登录 master,入侵过程随即重演。[2]
murphy 的访问限制更严,那名开发者没有直接登录权限。然而,master 上的 root 权限暴露了一个用于备份的管理员账户,这条服务通道由此通向 murphy。11 月 20 日,在 master 上截获的密码又打开了 gluck。攻击路线由逐台取得的权限拼接而成:每控制一台主机,攻击者便得到进入下一台所需的凭据或权限。[2][4]
这条链值得细看,因为“开发者访问”“root 权限”和“服务间访问”代表着不同能力,组合起来却产生了严重后果。被盗密码让攻击者进入系统,内核漏洞带来更高权限,备份通道与密码嗅探则支持横向移动。即使其余两环依然存在,只要抽走其中任何一环,受影响范围都会改变。
最初凭据究竟经由哪条路线被盗,公开调查始终没有定论,攻击者身份也未查明。Debian 的报告把陈述严格限定在证据覆盖之处:嗅探所得的密码、观察到的登录、找回的漏洞利用程序,以及发现的 rootkit。这条界线让复盘立足于取证材料,避免事后拼凑一套完整的攻击者经历。[2][4]
Rootkit 制造的噪声超出了攻击者预期
SucKIT 直接修改运行中的 Linux 内核,不借助可加载内核模块。它能够隐藏文件和进程,也能截获密码;Debian 的调查人员认为,它与 /sbin/init 被替换以及最早引起注意的内核 oops 有关。部署在数台主机上的文件完整性监控工具 AIDE 也发现了二进制文件的变化,以及 /usr/lib/locale/en_US 下可疑的时间戳。[2]
起决定作用的是信号之间的关联。老旧服务器偶发一次 oops,可以合理归因于硬件、驱动程序或一次性的内核缺陷。同一管理范围内的两套系统出现陌生的相同行为,先验概率随之改变。当这些故障之间显出关联,Debian 管理员便从日常维护转入事件响应。
监控给出了信号,判断仍由人完成。在后来 LWN 的讨论中,一名参与发现入侵的管理员澄清,AIDE 确实报告了变化,但团队起初以为那是另一名管理员的正常操作。工具检测到了一项事实,团队仍需要一名明确的负责人完成核查。[7] 这正是 告警送达 与 告警处理完成 的运维差别。完整性警告即使准确,只要缺少明确的确认流程,仍会失去控制作用。
这起事件也提醒人们谨慎看待偶然发现。一个存在缺陷的 rootkit 让多台机器的内核失去稳定,从而暴露了攻击;更隐蔽的植入程序完全可以保留同一批凭据与权限,同时避开 oops。真正能够迁移到其他系统的控制原则,是跨主机比较低频异常,并要求高权限文件的每一项变更都由人核查完成。
内核漏洞已经修复,却尚未被识别为安全边界
取证工作把提权漏洞利用程序与随后安装的 rootkit 区分开来。该程序利用内核处理 brk 时的一处整数溢出漏洞,改变内存保护并取得对内核内存的控制。这个漏洞最初编号为 CAN-2003-0961,现写作 CVE-2003-0961。Debian 的 DSA-403 公告为其支持的 Linux 2.4 软件包发布了修正后的内核。[2][5]
时间线令人不安。相关代码修正已在 9 月下旬进入 Linux 2.6 的预发布版本,并于 10 月初进入 2.4 分支,当时其安全影响尚未得到理解。也没有厂商公告提醒运维人员:本地账户可以借此取得 root 权限。11 月 28 日发布的 Linux 2.4.23 已包含修复;Debian 随后于 12 月 1 日发布 DSA-403。[2][5]
只用“未打补丁”概括这些失陷主机,会抹去问题最重要的一层。上游已有代码修正,距离漏洞得到识别、修复被回移植成软件包、运维人员收到通知以及全部机器完成部署,仍隔着一整条传递链。2003 年 11 月,这条链尚未赶在漏洞被利用前走完。整起事件发生在代码维护与漏洞响应之间的空档里。
这段空档对今天仍提供 shell 访问的项目依旧重要。本地权限隔离的强度,取决于底层最老旧且仍可被利用的内核;补丁的紧迫程度,又取决于项目能否知道哪些普通修正实际属于安全修复。因此,共享开发主机同时面对两项艰难要求:及时维护内核,并把任何贡献者账户最终遭窃视作设计前提。
“归档未受影响”来自核验结果,不能预先假定
Debian 在 11 月 21 日发布第一份公开通知,列出受影响机器,并立即把它们与软件包归档区分开来。项目没有直接恢复服务。安全归档保持暂停以接受核验,已经同步到镜像的 Debian 3.0r2 点版本也经过检查,随后才发布一度延后的公告。[1]
最终调查报告说明了这项结论的依据。响应人员把归档状态与几类不完全受失陷机器控制的记录相互比对:
- 在其他系统上持续积累的 MD5 校验和列表;
- 保存在外部邮件列表归档中的数字签名
.changes文件; - 归档服务器上的签名
.changes文件;以及 - 存放在受影响主机之外的镜像日志。[2]
任何一项记录单独看,都称不上万能封印。如今,MD5 已不适合作为抗碰撞的完整性哈希。签名的可信度取决于密钥保管。若镜像在入侵后收到恶意内容,它也会原样保存。证据的力量来自 来源彼此独立且内容相符:攻击者若想让修改过的软件包看起来与事发前的归档一致,就需要在多个地点重写多类证据。
这与恢复备份回答的是两类问题。备份回答:“能否找回某个更早时点的字节?”归档证据回答:“正在核查的字节,是否与事件发生前、事件范围外生成的记录一致?”恢复工作需要同时回答这两个问题。缺少来源记录的干净副本,会有把攻击者状态一并恢复的风险;只有来源记录却没有可恢复副本,只能证明损失,无法修复。
归档通过核验的结论只覆盖归档完整性:四台主机仍不能视为可信,部分服务仍未复原,每份开发者凭据是否保密也要另行查明。Debian 安装器团队在 12 月 12 日报告,尽管其他地方已经出现已知完好的快照,受影响机器上的 beta 1 镜像和部分每日构建仍无法访问。[6] 软件包归档的完整性保住了,业务连续性则已中断。
恢复时先撤销关系图中的凭据,再重建各个节点
响应人员为失陷磁盘制作镜像,以供分析。master、murphy 和 gluck 随后重装,服务再逐项恢复。为让安全归档尽早重新运行,klecker 起初采用远程清理和加固,完整重装安排在之后。时间线显示,安全服务于 11 月 22 日早些时候恢复,邮件列表则于 11 月 25 日恢复。[2][4]
主机恢复只占工作的一半。Debian 停用了 LDAP 中的开发者账户,从重要机器移除已授权的 SSH 密钥,让相关服务上的密码失效,并更换 SSH 主机密钥。运维通知要求开发者在另行通知前停止使用 Debian 凭据,同时更换在其他地方重复使用的密码。[2][3]
这些动作承认了磁盘镜像解决不了的一项事实:密码嗅探程序一旦以 root 权限运行,整张凭据关系图都会受到污染。恢复范围必须超出服务器本身,涵盖暴露期间经过服务器的每个身份、密钥、口令、备份账户和向外发起的登录。
扩大响应范围带来了实际代价。上传和 CVS 访问全部停止,因为支持分布式贡献的同一套身份系统,也把贡献者连接到共享的生产服务。项目选择承受停机,没有把使用便利当作凭据依然安全的证据。[3][4]
面向当今共享 OSS 基础设施的设计测试
2003 年尚无今天常见的托管 forge、硬件保护凭据、短期工作负载 token 和日常使用的不可变基础设施。这起事件揭示的控制逻辑依然适用。
小型项目采用托管 forge 时,应从控制原则入手,照搬 Debian 的服务器规模没有意义。日常维护者会话不应持有发布权限。给 CI 配置权限范围狭窄、有效期短的发布身份;把签名发布清单或 tag 指纹保存在 forge 账户无法改写的地方;同时保留经过恢复演练的问题单、仓库 ref 和软件包元数据导出。运维能力构成这里的限制条件:无人能在压力下恢复的控制,只具装饰作用。
对于必须运行共享系统的发行版或基金会,需要检验四项分离:
- 贡献者身份与主机权限分离。 一份被盗的贡献者凭据遇上一处本地内核漏洞时,不应直接换来 root 权限。
- 相邻服务彼此分离。 备份账户的权限应限于备份;一台主机截获的 secret 也不应在各处通用。
- 检测记录与受检测系统分离。 文件完整性结果和审计事件应发送到外部,由明确的负责人处理,并设置解释期限。
- 发布状态与发布证据分离。 至少一项核验记录——签名的晋级元数据、透明度日志条目、独立镜像或已知完好的清单——必须保存在有权改动软件包的管理域之外。
反证测试十分直接。若一份被盗的维护者密码加上一次主机提权,仍足以改动发行制品、抹去唯一审计轨迹、取得全部恢复 secret,并重写唯一用于判定归档未受改动的记录,那么这个项目只是用更新的工具复刻了 2003 年的密码链。
Debian 入侵之所以浮出水面,是因为两台机器以同一种反常方式发生故障。它最重要的完整性主张得以成立,原因恰与此相反:各类记录 并未 一起失效。彼此关联的异常暴露了共同入侵;刻意分散、互不关联的证据则限定了入侵所及范围。
这正是复盘留下的长期结论。事件中服务已经中断,四台主机均被取得 root 权限。韧性来自留存的独立证据:这些证据足以阻止四台失陷服务器把软件包归档变成一团无法查明的状态。
来源
- Debian Project,《部分 Debian Project 机器遭到入侵》,2003 年 11 月 21 日——第一份公开通知,列出四台主机、受影响服务、归档范围以及 Debian 3.0r2 的核验情况。
- Debian Project,《Debian 服务器入侵事件调查报告》,2003 年 12 月 2 日——关于时间线、攻击过程重建、归档检查、漏洞分析、恢复与凭据后果的权威报告。
- Debian Project,《入侵事件后的 Debian 开发者账户与服务状态》,2003 年 11 月 21 日——关于账户锁定、服务可用性、密码复用与凭据重置的一手运维指引。
- James Troup,《Debian 机器入侵事件详报》,2003 年 11 月 28 日——涵盖发现过程、横向移动、磁盘镜像、主机清理与证据限制的一手初步报告。
- Debian Security Team,“DSA-403-1:Linux 内核——权限提升”,2003 年 12 月 1 日——CAN-2003-0961 及 Debian 内核修正软件包的官方公告。
- Debian Installer Team,《Debian 近期入侵事件后的状态》,2003 年 12 月 12 日——beta 镜像、每日构建、已知完好快照与安装器恢复的服务后续情况。
- Robert Bernier,LWN.net,《Debian 入侵事件的教训》,2003 年 12 月 10 日——关于检测、凭据访问、主机多样性与恢复工作的独立同期分析及社群讨论。
- Lars Wirzenius,《Debcamp/DebConf3 结束了》,2003 年 7 月 21 日——摄影者的同期记录,也是本文所用 DebConf3 档案集体照的来源页面。