helium.ruby-lang.org 入侵事件分析

正如之前报道的那样,helium.ruby-lang.org,它是提供与 Ruby 开发相关的各种服务的服务器之一,遭到了未经授权的用户的入侵。我们,ruby-lang.org 管理员,正在报告我们对这次入侵的分析以及我们采取的对策。

事件时间线

以下显示了入侵的时间进展。每个时间均为 UTC 时间。

19 May       The public disclosure of a vulnerability of CVS
             (CAN-2004-0396) is announced.  We believe that this
             vulnerability was used in this intrusion.
20 May 02:46 The Debian CVS package of the host helium.ruby-lang.org
             (hereafter called 'helium') is upgraded. However, the
             chrooted CVS package, which provided the actual pserver,
             is overlooked.
23 May 11:15 Oldest (corroborated) time stamp of the trace of intrusion
27 May 19:03 Opening of the back-door installed by the invader
28 May 09:26 A ruby-lang.org administrator discovers a trace of the
             intrusion.
28 May 09:35 Administrator disconnects 'helium' from network.
28 May 11:53 Administrator reboots 'helium' and resumes mailing list
             services.
29 May 07:28 Our first announcement about this intrusion.

当时机器和服务

在入侵发生时,以下两台机器提供了与 Ruby 相关的服务。

helium.ruby-lang.org
以下服务由 ‘helium’ 提供。
  • CVS (cvs.ruby-lang.org)
  • HTTP (www.ruby-lang.org/raa.ruby-lang.org)
  • FTP (ftp.ruby-lang.org)
  • RSYNC (用于镜像站点)
  • ML (<ML 名称>@ruby-lang.org)
hydrogen.ruby-lang.org(以下简称 ‘hydrogen’)
以下服务由 ‘hydrogen’ 提供。
  • HTTP (www.rubyist.net)
  • NFS (将 /home 导出到 ‘helium’)

入侵详情

在 ‘helium’ 上,pserver 服务在 chroot 环境中以 anoncvs 用户权限提供。此 CVS 服务用于 Ruby 的开发,多个提交者拥有自己的帐户。允许通过 ‘anonymous’ 用户帐户进行公共只读 CVS 访问。

如上所述,CVS 的漏洞于 5 月 19 日公布。尽管 ‘helium’ 的 Debian CVS 包在 5 月 20 日进行了升级,但 chroot 环境的 CVS 包并未升级。

在这种情况下,‘helium’ 的管理员在 5 月 28 日 09:26 (UTC) 发现了 anoncvs 的可疑进程。发现入侵者安装了多个可疑的可执行文件,包括一个在 TCP 端口 #54320 上创建后门的程序。在发现入侵时,此后门程序正在运行。“时间线”时间由 ‘ps’ 命令的输出和入侵可执行文件的时间戳确定。我们应该在此指出,Linux 内核的 IP 数据包过滤功能阻止了所有与后门的外部连接。

另一个注意事项:通常,pserver 进程会为每个会话创建一个临时目录 (/tmp/cvs-serv<进程 ID>),并在会话结束时删除它。在入侵时,在 chroot 环境的 /tmp 目录中留下了多个临时目录。这表明 pserver 进程异常终止,可能是由于入侵者的攻击造成的。在这些临时目录的时间戳中,最旧的时间戳是 5 月 23 日 11:15 (UTC)。“时间线”时间由这个时间戳确定。将这些目录的时间戳与 pserver 会话日志进行比较,可以看出,有多个独立的黑客攻击了该漏洞。

此证据表明,入侵者正在利用 CVS 漏洞并获得了 ‘helium’ 上的 anoncvs 用户权限。入侵者可以获取、更改和销毁 chroot 环境中的所有信息。

迄今为止,尚未发现诸如夺取其他帐户、本地权限提升或入侵到 chroot 环境之外的证据。

入侵 chroot 环境之外的可能性

为了让入侵者突破 chroot 保护,需要提升到特权用户。

在入侵时,在 ‘helium’ 上运行的 Linux 内核版本为 2.4.24。已应用了针对漏洞的补丁(从内核版本 2.4.25 反向移植)。但是,尚未应用在内核 2.4.26 中修复的针对 setsockopt(2) 漏洞的补丁。

已展示了利用易受攻击的 setsockopt(2) 进行 DoS 攻击的代码,但认为很难通过此方法成功实现本地权限提升。如果入侵者无法获得目标环境的内核映像,则似乎无法实现权限提升。在 ‘helium’ 上,内核不是来自二进制包,而是从源代码构建并单独应用补丁。因此,入侵者能够实现权限提升的可能性被认为是最小的。

服务恢复

在首次调查中,我们推断入侵可能仅限于 chroot 环境。起初,我们决定恢复 ‘helium’ 上的邮件列表服务,因为从用户的角度来看,暂停邮件服务的影响被认为是最大的。在检查没有更改二进制包,并且配置文件中没有可疑设置后,我们恢复了邮件列表服务。

然后,我们开始确认工作,以恢复 ‘helium’ 上的其他服务,但很快决定彻底重建机器并在检查每个服务后单独恢复服务。做出此决定的原因是检查大量文件有困难。

为了恢复服务,我们需要一台用作 ‘helium’ 替代品的机器。我们决定使用托管 www.rubyist.net 的 ‘hydrogen’。‘Hydrogen’ 不提供 pserver 服务,并且在机器上没有发现入侵的痕迹,但是 ‘hydrogen’ 将 /home 作为 NFS 挂载的文件系统提供给 ‘helium’。为了确保 ‘hydrogen’ 没有被攻破,我们重新安装了 ‘hydrogen’ 的操作系统,并将主机名设置为 ‘lithium’。然后,我们将邮件列表服务从 ‘helium’ 移至 ‘lithium’,以及网站的入侵公告页面。

接下来,我们重新安装了 ‘helium’ 的操作系统,并将主机名设置为 ‘beryllium’。我们计划将来将所有公共服务迁移到 ‘beryllium’。

目前机器和服务

目前,以下两台机器提供与 Ruby 相关的服务。

lithium.ruby-lang.org
以下服务由 lithium.ruby-lang.org 提供。
  • CVS (用于提交者开发,无公共访问)
  • 邮件列表(计划迁移到 ‘beryllium’)
beryllium.ruby-lang.org
以下服务由 beryllium.ruby-lang.org 提供。
  • HTTP (www.ruby-lang.org/raa.ruby-lang.org/www.rubyist.net)
  • FTP (ftp.ruby-lang.org)
  • 匿名 CVS (cvs.ruby-lang.org)

验证每个服务的内容

接下来,我们将解释我们评估入侵者是否对服务进行了任何更改或破坏的结果。

前提条件

我们拥有的最古老的入侵证据来自 5 月 23 日,并且已得到证实;由于此痕迹可能已被具有 anoncvs 用户权限的入侵者删除,因此我们无法断定这是入侵的第一天。由于入侵的证据来自 CVS 漏洞,并且由于没有其他已知可用于入侵 ‘helium’ 的漏洞,因此我们确信入侵者滥用了 CVS 漏洞,从而获得了对 ‘helium’ 的访问权限。

我们对服务中更改或破坏的验证基于以下假设:首次入侵证明发生在 5 月 19 日之后,当时 CVS 漏洞 CAN-2004-0396 公开宣布。

CVS

由于入侵者应该获得了 anoncvs 用户权限,因此我们最怀疑和担心 ‘helium’ 上所有服务中可能对 CVS 造成的损害。

在入侵时,存在以下四个 CVS 存储库。

/src
源代码
/www
WWW 数据
/doc
文档
/admin
CVS 的管理文件

其中,/www 和 /doc 不需要验证,因为它们的内容已经未使用。此外,我们决定暂停使用 /admin,并直接将其删除。

我们接下来解释的是对 Ruby 源代码和 /src 中包含的每个其他模块的验证结果。

Ruby 的源代码

我们将可能的 CVS 存储库更改分为两类

(1) 更改 5 月 19 日之前 CVS 存储库中文件的历史数据

(2) 伪装 5 月 19 日之后定期提交的更改

对于 (1),我们通过 5 月 19 日之后安全保存在 ‘helium’ 外部的 cvsup 日志检查了 CVS 存储库中的文件。我们验证了 CVS 存储库中文件没有被更改的迹象。对于 (2),我们单独检查了所有提交的内容,并确认 5 月 19 日之后不存在任何恶意代码。这意味着不仅没有恶意代码,而且我们还与提交者验证了每个提交。

我们的验证由以下 URL 中的数据支持。

  • cvsup 日志
    https://ruby-lang.com.cn/check-data/cvs/cvsup-log/
  • 从 5 月 19 日到 5 月 28 日的提交内容
    https://ruby-lang.com.cn/check-data/cvs/cvs-diff/

此外,除了上述材料外,我们还做了以下补充工作

  • 我们确认了 ‘helium’ 上 CVS 存储库中的文件与 5 月 21 日外部安全服务器上的文件之间没有不一致之处。
  • 我们确认了从 2003-11-02 到 2004-05-27(每日)的 CVS 快照与从 ‘helium’ 上的 CVS 存储库创建的快照之间没有不一致之处。

我们得出的结论是,CVS 存储库中 ruby 的源代码没有被更改或破坏。

Ruby 源代码以外的模块

除了 Ruby 的源代码外,CVS 存储库的 /src 目录还包含以下模块

  • app
  • lib
  • rough
  • rubicon
  • ruby-parser
  • shim
  • vms
  • pocketruby
  • oniguruma
  • mod_ruby
  • eruby

首先,我们通过比较存储库文件的 ctime 与 CVSup 将文件复制到外部服务器的时间,发现只有以下文件在 5 月 19 日之后被更改

  • lib/csv/lib/csv.rb,v
  • lib/csv/tests/csv_ut.rb,v
  • lib/soap4r/lib/wsdl/xmlSchema/parser.rb,v
  • lib/soap4r/lib/wsdl/xmlSchema/complexContent.rb,v
  • lib/soap4r/lib/wsdl/parser.rb,v
  • mod_ruby/lib/apache/eruby-run.rb,v
  • mod_ruby/lib/apache/erb-run.rb,v
  • mod_ruby/ChangeLog,v

其次,我们将复制的 CVS 存储库与 ‘helium’ 上的 CVS 存储库进行了比较,我们确认它们之间没有不一致之处,除了 ‘pocketruby’ 中的二进制文件。由于我们已经在 ruby 的主分支中合并了 ‘wince’,因此我们没有对 pocketruby 进行进一步检查,并已停止提供其源代码。

下面提到了 5 月 19 日之后更改的每个文件。

lib/csv/lib/csv.rb,v
lib/csv/tests/csv_ut.rb,v
lib/soap4r/lib/wsdl/xmlSchema/parser.rb,v
lib/soap4r/lib/wsdl/xmlSchema/complexContent.rb,v
lib/soap4r/lib/wsdl/parser.rb,v
我们对这些文件不确定。lib/csv 和 lib/soap4r 已经与 ruby 合并,这些模块仅由各自的维护者使用。lib/csv 和 lib/soap4r 已从 CVS 存储库中删除,将在其他地方进行开发。
mod_ruby/lib/apache/eruby-run.rb,v
mod_ruby/lib/apache/erb-run.rb,v
包括分支在内的所有修订版都已检查完毕,没有发现问题。它们都与发布的源代码包进行了比较,并且已确认没有不一致之处。
mod_ruby/ChangeLog,v
ChangeLog 文件的通常更改是添加内容。可以使用以下方法检查 ChangeLog:

(1)我们确认第一个版本没有问题。

(2)我们确认最新版本没有问题。

(3)我们确认了所有包含更改的版本,不仅仅是添加的内容。

此外,我们将其与发布的源代码包进行了比较,并验证了不存在不一致之处。

另外,mod_ruby 和 eruby 的开发已转移到 Subversion,因此这些 CVS 模块名称已更改为 mod_ruby-old 和 eruby-old。

HTTP (www.ruby-lang.org)

https://ruby-lang.com.cn/{ja, en}/ 由 tDiary 生成。为了检查执行 tDiary CGI 程序是否存在问题,我们执行了以下操作:

  • 确认 CGI 程序中不存在可疑代码
  • 验证嵌入在内容中的 <script> 元素中的代码
  • 确认配置文件中不存在可疑数据

此外,我们检查了内容和链接的 URL,但没有发现问题。如果发现任何问题,请联系 webmaster@ruby-lang.org。

在线参考手册

在线参考手册位于 RWiki 上。我们首先恢复了 2 月 29 日的内容,然后应用了 2 月 29 日发送到外部电子邮件帐户的补丁。然后,我们将其与“helium”上的内容进行了比较。

差异可以从以下位置获得

https://ruby-lang.com.cn/check-data/ruby-man/man-rd-ja.diff

Base64.rd 的差异来自于接收邮件时插入的新行。trap%3A%3ANilClass.rd.rej 被拒绝,因为相同的补丁应用了两次。diff 脚本比较的是 61 分钟前的文件,因此相同的补丁发送了两次。

我们确认它们都没有受到入侵的影响。

RAA

我们进行了以下数据验证。

  • 我们对 RAA 数据进行了每日差异比较,从 1) 3 月 27 日备份的干净的 RAA 数据副本,2) 4 月 4 日至 5 月 28 日的每日备份,以及 3) 5 月 28 日的最新 RAA 数据。

    2) 和 3) 位于机器上受 chroot 保护的区域中。 1) 是干净的,因为它保存在开发环境中。

    • RAA 数据更新
      http://raa.ruby-lang.org/announce/soapbox-diff-all-passphrasemask.txt
    • RAA 新条目
      http://raa.ruby-lang.org/announce/soapbox-new-passphrasemask.txt
  • 我们确认上述差异中不存在可疑数据。

可以得出结论,5 月 28 日的 RAA 数据(与我们用于 RAA 服务重启的数据相同)不包含任何可疑数据。因此,我们决定按 5 月 28 日的状态重启 RAA 服务。我们无法保证入侵者不会进行看起来正常的更改。例如,5 月 18 日的 sampleproject 的更改如下:

== sampleproject
- updated: Sun May 09 12:35:19 GMT+9:00 2004
+ updated: Mon May 17 13:00:38 GMT+9:00 2004
- version: 0.0.8
+ version: 0.1.1

这些数据均无可疑之处,但有可能是入侵者所做的更改。因此,我们要求每个 RAA 项目所有者检查他们的 RAA 条目并进行更新以进行确认。为此,请执行以下步骤:

(1)打开项目页面

(2)检查项目信息

(3)转到“更新”页面

(4)按“提交”按钮(即使不需要更新也请这样做,此步骤用于确认)

如果您在 RAA 中发现任何可疑数据,或者有任何疑问,请联系 raa-admin@ruby-lang.org。感谢您的合作。

FTP

我们将 FTP 上的文件的 md5sum 值与保存在外部安全服务器中的文件进行了比较,没有发现差异。

但是,我们无法检查以下目录。因此,它们目前不提供。

/pub/ruby/contrib/
/pub/ruby/doc/
/pub/ruby/snapshots/
/pub/ruby/ML/
/pub/ruby/shim/

如果您需要这些目录中的文件,请联系 ftpadmin@ruby-lang.org。

邮件列表

我们调查了每个邮件列表的配置文件,没有发现问题。但是,成员列表和邮件存档尚未经过彻底检查。

如果您有任何问题,请联系 <ML name>-admin@ruby-lang.org。

Shugo Maeda <shugo@ruby-lang.org>
ruby-lang.org 管理员小组