第六章:shell退出、编辑器和sudoers政策

类Unix操作系统及其软件像俄勒冈州海岸的苔藓一样生长出新的功能。他们无处不在。许多较旧但流行的程序,如pagers的 moreless 和编辑器 vi ,允许用户从其中运行shell命令。自己试试——查看包含更多内容的文件。当您仍在查看文件时,输入一个感叹号,然后输入一个shell命令,如 lsifconfig 。命令将运行。您将看到输出,然后更多返回到最初显示的文本。

在哑终端或SLIP连接上工作的系统管理员迫切需要逃到shell的能力。您不想留下一个文件来验证您计算机上的IP地址是否与文件中的内容匹配。现在我们可以在一台机器上打开无数个SSH会话,shell转义就不用那么多了。

除非你使用sudo。然后,炮弹逃逸以一种糟糕的方式变得非常可怕。考虑以下sudoers政策:

我可以使用更多来查看任何系统上的文件。太酷了。我可以查看 /var/log/auth.log ,了解用户的SSH连接失败的原因。但我更像根一样奔跑。这意味着我可以运行的任何命令都将以root权限运行。我在一个文件上运行sudo more,然后输入:

我在visudo里面,sudoers的编辑者!我可以编辑策略以添加一条规则,允许我在所有计算机上运行所有命令、保存和退出。然后我退出更多,检查我的特权。

如果高级系统管理员发现了这一点,她会把我的头放在盘子里。再一次。

如果用户可以访问有限的特权命令子集,则必须确保他无法引导自己获得更大的访问权限。通过限制命令或禁止命令运行其他命令来实现这一点。

命令限制

消除shell转义的一种方法是验证没有允许的程序包含shell转义。这很难——许多程序都有shell转义,而不仅仅是pagers和文本编辑器。您可以通过只允许用户特权访问 cat(1) 来消除翻页器问题,要求他们将输出转储到pagers。

然而,这只消除了pagers的shell转义。要遵循此方法,您必须仔细检查每个允许的shell转义命令的文档。并非所有文件都是完整的。

禁止执行命令

Shell逃逸并不是破解程序的唯一方法。许多程序运行其他程序。我们已经看过visualdo,它为您运行一个文本编辑器。在现代类Unix操作系统上,sudo可以阻止程序执行其他程序。Sudo使用LD_LIBRARY_PRELOAD环境变量来禁用程序执行。每个现代的BSD、Linux和类Unix操作系统都支持这个变量,但如果你不确定,请查看系统的文档。

EXEC和NOEXEC标签控制命令是否可以执行其他命令。EXEC是不成文的默认值,允许其他命令执行命令。NOEXEC禁止执行死刑。在sudoers规则中,将标签放在命令之前。

这有什么作用?使用sudo more检查文件,并尝试在visualdo中进行shell转义。more没有进入visual编辑器,只是打印了一条消息,比如“done”或“exec failed”。为什么会这样做?它试图运行该命令,但失败了。

NOEXEC标签甚至禁止通过sudo运行visudo。

visudo命令尝试运行文本编辑器。Visudo无法运行其他命令,因此失败。

不过,全球NOEXEC标签有点苛刻。一些命令合法地生成其他进程来为它们执行任务。例如,newaliases命令合法地运行sendmail。我建议使用全局块,然后将特定命令列入白名单。

newaliases命令被允许生成新进程。一个非常精明的入侵者可能会让newaliases生成一个特权外壳,但这种攻击大大提高了渗透你的系统所需的技能。

允许命令的白名单是命令别名的完美应用程序。

用户可以运行 sudo /bin/sh ,但新shell将无法执行除shell内置命令之外的任何命令。用户仍然可能损坏系统,但这样做需要更多的专业知识。许多第三方sudo教程建议明确禁止特定程序执行其他程序,就像他们建议从允许列表中排除命令一样。这两种解决方案都有同样的问题。通过sudo获得真正安全性的唯一方法是显式枚举用户可能使用的命令。

编辑文件

许多编辑都提供shell转义功能。但是,您需要访问编辑器才能更改某些关键文件。你可以试试这样的sudoers政策:

这是否可以在没有shell转义的情况下更改文件?对。但它有更普遍的问题。首先,我不使用老式的vi进行日常工作。我更喜欢Emacs或ed(如果我必须使用原始编辑器,我想要一个能证明我是阿尔法极客的编辑器)。在编辑文件时,我可能需要一个无特权的shell转义。

这就是sudoedit发挥作用的地方。sudoedit允许用户编辑特权文件,而无需以root身份运行编辑器。当您在文件上运行sudoedit时,sudo会将目标文件复制到临时文件,设置临时文件的权限以便您可以对其进行编辑,并在其上运行编辑器。您可以使用普通的无权限文本编辑器编辑文件。退出编辑器时,sudoedit会检查临时文件。如果文件已更改,它会将临时文件复制到目标文件。

配置Sudoedit

要配置编辑权限,请使用sudoedit关键字和目标文件的完整路径。

wheel组中的用户可以通过sudo编辑SSH服务器配置文件。

使用 sudoedit

要编辑文件,请使用sudoedit命令和文件名:

文本编辑器打开。用户可以进行更改、保存和退出。sudoedit将他们编辑过的文件放在原来的位置。

用户会得到什么编辑器?这取决于用户的环境。如果编辑器有一个$SUDO_EDITOR环境变量,则使用它。否则,sudoedit会查找$VISUAL或$EDITOR变量。如果这些不存在,sudoedit会在sudoers中寻找编辑器选项。Sudoedit使用vi作为最后的手段。我建议你用sudoers设置一个编辑器,因为vi有点无聊。

提供默认编辑器的完整路径。如果用户不能使用你的编辑器,也不能设置自己的编辑器,他就不应该编辑sudoers策略。

制定Sudoers政策

现在,您已经拥有了组成sudo策略的所有部分。其他一切都建立在你已经学到的基础上。让我们讨论一下如何使用这些工具来构建sudoers策略。

在第4章中,我演示了如何从ALL中排除命令,让人们以root身份运行任意命令。在本章中,我演示了shell转义如何为人们提供root访问权限。虽然默认情况下sudo会记录所有命令,但它不会自动记录所有发生的事情。像sudoreplay这样的程序会提供更详细的日志,但需要特殊的配置(第12章)。自然的问题是:如果用户可以如此轻松地避免限制,sudo工具有什么好处?

如果你的用户可以以root身份运行任意命令,这不是工具的错。问题是你写的肥皂泡政策很糟糕。不要太尴尬——大多数人写的政策都很糟糕。许多操作系统都附带了sudoers策略,允许管理组中的所有用户无限制访问。此策略意味着您的管理员可以在不记录的情况下执行任何操作。恶意入侵者或管理员可以在shell逃逸后隐藏大量损坏。

那么,该怎么办?

编写安全sudoers策略的唯一方法是默认拒绝命令。在命令中使用ALL关键字为人们提供了太多获得无限制特权访问的简单方法。用户会拼命地绕过他们认为阻碍他们的限制。不要给他们留下一个可以钻进去的洞。

将你的sudoers策略视为防火墙。早在10baseT时代,人们就运行防火墙,允许所有访问,然后阻止易受攻击的服务的流量。在今天的互联网上,这是无能的表现。以同样的方式对待你的sudoers政策。默认许可证sudoers规则让我宣布“90年代的人打电话来了,他们希望他们的安全政策回来。”

仅仅在sudoers规则的命令部分出现ALL一词就意味着用户可以获得不受限制的root访问权限,而不管你认为你对他施加了什么限制。你实际上无法列举sudoers策略中的不良之处,就像在防火墙中一样;唯一安全的做法是允许已知的必要活动。

您可以安全地将ALL用于用户、运行方式和服务器列表。非特权用户不能更改他们的用户名或服务器的主机名,但他们可以毫不费力地更改命令的完整路径。

从这一点开始,我在命令描述中从不使用ALL,除了一些糟糕的实践的具体例子。否则,就会招致辱骂和侵扰。刚开始的时候不要为错误感到尴尬是一回事,但现在你知道得更好了。