Answers:
您可能知道UNIX中文件的正常读取,写入和执行权限。
但是,在许多应用程序中,这种类型的权限结构(例如,给定用户授予读取给定文件的完全权限,或者完全不授予读取文件的权限)太粗糙了。因此,Unix包含另一个权限位,即该权限set-user-ID
位。如果为可执行文件设置了该位,那么只要所有者以外的用户执行该文件,该用户就可以访问所有者的其他任何文件,从而获得所有者的所有文件读/写/执行特权!
要设置文件的设置用户标识位,请键入
chmod u+s filename
确保您还设置了组其他执行权限;最好还有其他组的读取权限。所有这些都可以通过一个语句来完成
chmod 4755 filename
也称为已保存的UID。启动具有Set-UID位的文件时,保存的UID将是文件所有者的UID。否则,保存的UID将是真实UID。
此UID用于评估执行特定操作的进程的特权。可以将EUID更改为Real UID,如果EUID!= 0,则可以将其更改为超级用户UID。如果EUID = 0,则可以将其更改为任何值。
此类程序的一个示例是passwd
。如果将其完整列出,您将看到它具有Set-UID位,并且所有者是“ root”。当普通用户运行“ mtk”时passwd
,它将以:
Real-UID = mtk
Effective-UID = mtk
Saved-UID = root
man credentials
在这种情况下是一个很好的信息来源。另请参阅关于SO的此问题。有关历史的解释,请参见此存档的帖子。
与其将“设置UID”和“有效UID”称为一种机制,不如将其称为UID的整个概念。存在各种UID的基本原理是特权分离带来的种种麻烦。甚至普通(非特权)用户有时也需要做只有特权用户才能做的事情(访问资源)。为了轻松实现此目的,程序可以更改其UID。其中有3种类型:
真正的UID-拥有进程的UID
有效UID-进程当前运行的UID-这确定了在任何特定时刻该进程的实际功能。这也是ps
在USER字段中向您显示的内容。
保存的集合UID-占位符,用于在真实和有效UID之间来回切换
需要最后一个源于这样的事实,即普通用户可以仅这三个之间切换闲来无事和setuid程序通常需要以某种方式知道,谁是谁装好了(再加上真实的UID不应该因为改变用户这会造成更大的混乱)。
mtk的解释很不错。
该passwd
示例是特权升级之一-passwd始终以root用户身份运行,因为它必须更改仅允许root用户更改的文件。这使得passwd可执行文件不易于出现缓冲区溢出等问题非常重要,这样聪明的普通用户就可以将其用于非预期的用途。
另一个理由是,以与您su
以root用户身份登录时使用的方式相同的方式保护用户-以便减少或限制对特定任务的特权,而不是升级它们。例如,如果我有权启动不需要访问我的东西并且拥有自己的东西(例如记录器)的守护程序服务,则以suid的身份运行它将意味着它只能访问该东西而不是我的或其他任何人。
请注意,即使未在可执行文件上设置suid位,也可以通过编程方式设置uid,但是,这对于升级不起作用。即,如果您是普通用户,并且编写了自己在某个时候设置了uid的程序,则该程序将无法切换到root用户。我相信,Apache以这种方式工作。它通常由root启动,并具有一个进程,然后分叉将uid切换到非特权用户(例如“ httpd”)的子代。这些子进程是实际的Web服务器的工作。