黑客和 / - 来自 DEF CON 的一些黑客技巧
我认为,在编辑日历上,黑客专题的截止日期与 Black Hat 和 DEF CON 大会同时到来,再合适不过了。虽然我长期以来对安全很感兴趣,但通常是从系统管理员的防御姿态或黑客攻击后的取证角度来看待的。今年,我很幸运地旁观了 neg9 团队的一群才华横溢的黑客参加开放式 CTF 锦标赛。本质上,锦标赛让多个团队相互对抗,他们都试图解决针对锁定服务器的各种谜题和安全挑战。我认为在本专栏中,我将列出一些针对防御性系统管理员的提示,这些提示是我从攻击性角度看待计算机安全时想到的,尤其是在像黑客竞赛这样的受限环境中。
首先,在我收到太多愤怒的信件之前,我非常清楚关于“黑客”这个词及其多种含义的长期争议。在本文中,我出于几个原因,将巧妙的技巧和安全漏洞都称为黑客行为,并将他们的实施者称为黑客。
英语中有许多词可以根据语境改变含义,我认为阅读本文的每个人都足够聪明,可以做出适当的区分。
我们的社区已经能够区分“黑客”是指恶作剧、优雅的解决方案、权宜之计,甚至是根据语境指作家或政治家,所以我认为我们可以处理一个额外的语境定义。
“cracker(破解者)”这个词只是让我想起 20 世纪 70 年代对白人的俚语,无论在哪个语境中听到这个词,我都很难保持严肃。
现在这个问题解决了,我发现从进攻的角度来看安全,首先有趣的是学习基本的经典命令行工具(如 vi、nc 和其他工具)是多么重要。在这个竞赛和适当的锁定系统中,您不仅要运行最少量的服务,还要尝试限制您在机器上安装的程序集,以便它们不会被潜在的攻击者利用。如果您想攻击一个系统,但只知道如何在 Emacs 中编辑文本文件、使用 Nmap 进行端口扫描或编写 Ruby 脚本,当这些工具没有安装时,您该怎么办?即使在受限的环境中,您也可以指望某些工具会被安装,例如 vi、nc、dd、sh 和所有其他很棒的两个字母命令。从进攻的角度来看,如果您知道如何使用这些命令,那么如果您碰巧遇到一个最小化的系统,您就不会束手无策。从防御的角度来看,如果您确实将系统上安装的程序限制为必要的程序,那么您将减慢那些期望系统上存在更新、更高级工具的黑客的速度。
我认为,如果您要掌握这两个字母的命令来进行黑客攻击,除了 vi 之外,nc 是最佳选择。如果您不熟悉 nc(或 netcat),它是一个非常通用的工具,允许您打开或侦听 TCP 和 UDP 连接。它是最初的网络瑞士军刀,无论您是系统管理员还是黑客,它都是您武器库中一个有价值的工具。在黑客攻击和故障排除的情况下,它都很有用,因为您可以像 telnet 一样使用它来连接到远程服务器和端口,并启动交互式会话。
$ nc mail.example.org 25 220 mail.example.net ESMTP Postfix . . . QUIT
您还可以打开一个 nc 会话,使其在端口上处于侦听模式,并在远程主机上启动第二个 nc 会话以连接到该端口,并像基本的聊天程序一样来回发送文本。在侦听主机上,运行
$ nc -l 31337
在远程主机上,输入
$ nc hostname 31337
您也可以在这两个示例中用主机名替换 IP。一旦建立连接,在一端输入的任何内容都会显示在另一端,您可以按 Ctrl-D 关闭任一会话中的连接。
许多系统管理员长期以来一直使用此功能作为快速而肮脏的文件传输协议。启动第一个 nc 会话,使其处于侦听模式,并将其输出重定向到一个文件
$ nc -l 31337 > output_file
在您要从中发送文件的远程计算机上,您需要键入
$ nc hostname 31337 < input_file
一旦文件传输完成,连接将自动关闭。
nc 的另一个非常有用的功能是,当没有更复杂的工具时,它可以充当端口扫描器。只需使用 -z 选项让 nc 仅测试端口是否打开,而不是连接到端口,添加 -v 以获得详细输出,并提供端口范围作为参数。因此,要扫描主机上 20 到 25 之间的开放端口(非常适合测试开放的 FTP、telnet、SSH 和 SMTP 服务),您需要键入
$ nc -zv host.example.org 20-25 nc: connect to host.example.org port 20 (tcp) failed: ↪Connection refused Connection to host.example.org 21 port [tcp/ftp] succeeded! Connection to host.example.org 22 port [tcp/ssh] succeeded! nc: connect to host.example.org port 23 (tcp) failed: ↪Connection refused nc: connect to host.example.org port 24 (tcp) failed: ↪Connection refused Connection to host.example.org 25 port [tcp/smtp] succeeded!
比赛中的另一个有趣的要点涉及一个系统,您可以在其中登录,但是,包括主目录在内的许多目录都通过 NFS 以只读方式挂载。这带来了一系列有趣的限制。例如,由于机器正受到多个团队的攻击,每个团队都可以作为同一用户登录,所以每个人都在将其他人踢出机器。这意味着每次您想要登录时,都必须手动输入密码,但由于主目录是只读的,您无法使用 SSH 密钥自动执行该过程。这也意味着您需要创造性地考虑将脚本存储在哪里,因为您无法写入您的用户通常有权访问的主目录。
对于防御者来说,您可以看到为什么将安全目录以只读方式通过 NFS 挂载会给攻击者带来问题——攻击者无法以用户身份写入目录,而且即使他们成为 root 用户,他们也可能必须利用 NFS 服务器以读写模式重新挂载文件系统。作为攻击者,这只是意味着您需要更有创意地考虑将文件存储在哪里。
大多数命令行用户都知道 Linux 系统上 /tmp 目录的存在。这是一个所有用户都可以写入的目录,并且该目录上设置了特殊权限,因此虽然任何人都可以写入文件,但一旦创建文件,其他用户就无法访问它。在黑客攻击这个特定的受限系统时,您很可能会将脚本存储在 /tmp 中,但那是其他团队首先会注意到您的文件的地方,并且很可能会删除它们(坏事)或修改它们以执行您不希望的操作(更糟)。幸运的是,Linux 系统上至少还有两个不太为人所知的目录是所有人都可以写入的:/var/tmp 和 /dev/shm。
/var/tmp 目录的功能与 /tmp 目录大致相同,即所有用户和程序都可以写入它;但是,与 /tmp 目录不同,许多用户不知道它的存在或忘记在那里查找。同样与 /tmp 目录不同的是,/tmp 目录会在系统重启时被擦除,而您放在 /var/tmp 中的任何文件都会在重启之间保留。
/dev/shm 目录也是黑客的最爱,这是有充分理由的——管理员甚至更不了解它是世界可写的。攻击者使用此目录的另一个更好的理由是,它的内容实际上仅存储在 RAM 中,而不是磁盘上,因此一旦系统重启,文件就会消失,甚至取证技术也无法恢复它们。
在比赛的某个时刻,neg9 团队的一些聪明黑客在一个作为 root 用户在其中一个比赛系统上运行的自定义服务中发现了一个故障。他们能够将这个缺陷转化为 root 漏洞,使他们能够以 root 用户身份在他们想要的文件系统上的任何位置写入 33 个字节。棘手的部分是,如果他们选择一个现有文件,它将被截断为这 33 个字节。
这提出了一个有趣的问题。如果您的唯一 root 访问权限是向文件写入 33 个字节的能力,您将如何将其转换为完全 root 访问权限?例如,您可以将一个新文件写入 /etc/cron.d/,该文件每分钟执行一个漏洞利用脚本。但是,如果这不起作用,您会怎么做呢?当您将自己置于像这样的受限环境中的进攻心态时,您最终会发现接近系统的创造性方法。
有几种方法可以利用此选项来获得完全 root 访问权限。例如,您可以查看 /etc/inittab 以查看哪个 getty 进程设置为自动重新生成,然后用您自定义的 33 字节 shell 代码替换现有的 getty(例如,/sbin/agetty)。然后,当 getty 重新生成时(您可能会强制执行),它将以 root 用户身份重新生成,并且您的自定义代码将以 root 权限运行。
该团队利用该漏洞的方式是编写一个新的简短的 init 脚本,该脚本使 vim SUID root。然后,他们写入 /proc 中的一个文件,强制系统重启,以便在重启时,他们的 init 脚本将运行。通过将 vim 设置为 SUID root,他们可以编辑 root 拥有的文件,并执行诸如更改 root 密码和启用使用 SSH 进行 root 登录之类的操作,并最终撤消 vim 上的 SUID 权限。从防御者的角度来看,这种攻击很难防范,本质上归结为基本的安全实践,例如保持软件包更新以及在可能的情况下将服务放在沙箱中。
总而言之,我不得不说,我非常喜欢这种不同的安全视角。无论您是站在防御端的系统管理员,还是站在进攻端思考的黑客,我认为双方都可以从不时地戴上对方的帽子中受益。
Kyle Rankin 是旧金山湾区的系统架构师,也是许多书籍的作者,包括 The Official Ubuntu Server Book、Knoppix Hacks 和 Ubuntu Hacks。他目前是 North Bay Linux Users' Group 的总裁。