chmod +s 可以给文件/目录 设置 suid和sgid

要了解 suid/sgid, 必需先了解 process 及 permission.
我們需知道: 每個 process 都有其 effective uid/gid , 以決定其在傳統 unix filesystem 中獲得的實際 permission .
再, process 是由 binary 產生的, 而 binary 是從 shell / shell script 載入執行.
在正常的情況下, process 的 effective uid/gid 是從 parent 繼承, 或簡單說是與 shell 的 uid/gid 一樣.
shell 的 uid/gid 則是跟據 /etc/passwd 的第 3 與 第 4 欄位決定.

當我們有了以上的概念之後, 再來看 suid 對 effective uid/gid 的影響:
若 binary file 帶有 suid/sgid 的時候,
其 effective id 就不是從 parent 那邊繼承, 而是以 binary file 本身的 user/group 為準.

舉例而言, 若一個 prog1 的 user/group 都是 root , 但沒設 suid/sgid ,
那當一個 uid(500)/gid(500) 的 parent process 執行這個 prog1 的話,
那 effective uid/gid 就是 500 …
但若 prog1 設了 suid/sgid 後, 那其 effective uid/gid 就是 root !

一旦這個 process effective 是 root 的話, 那它對 file system 的 permission 就如脫繮野馬般任意奔騰而不受限制了.
因此我才在前面提到木馬程式與病毒的例子…
試想一下: 若病毒的 user/group 被設為 root, 然後被一般 user 執行時,
suid/sgid 的有與無將導致甚麼不同結果?

好了, 由於 suid/sgid 在系統上有其存在的必要性(舉 /usr/bin/passwd 與 /etc/shadow 為例),
但同時又有極大的殺傷力, 在應用上要異常小心!
因此, bash shell script 在先天上不支援 suid/sgid .
perl 亦如此, 除非額外再安裝 suid-perl ….


根据现在的Unix机里,脚本是无法设置suid的,因为真正运行的进程是脚本的解释程序而不是脚本本身
当然,理论上可以让脚本的解释程序获得脚本的suid状态并且动态的改变自己的suid属性,然后在脚本运行完毕后再改回去。不过这样的整个系统架构的修改可以说不算小,而且也不符合POSIX规范(POSIX规范中没有允许一个正在运行的进程动态修改自身的suid属性)

由于SUID和SGID是在执行程序(程序的可执行位被设置)时起作用,而可执行位只对普通文件和目录文件有意义,所以设置其他种类文件的 SUID和SGID位是 没有多大意义的。
首先讲普通文件的SUID和SGID的作用。

例子: 如果普通文件myfile是属于foo用户的,是可执行 的,现在没设SUID位,ls命 令显示如下:

-rwxr-xr-x 1 foo staff 7734 Apr 05 17:07 myfile

任何用户都可以执行这个程序。UNIX的内核是根据什么来确定一个进程对资 源的访问权限的呢?是这个进程的运行用户的(有效)ID,包括user id和 group id。用户可以用id命令来查到自己的或其他用户的user id和group id。 除了一般的user id 和group id外,还有两个称之为effective 的id,就是 有效id,上面的四个id表示为:uid,gid,euid,egid。

内核主要是根据euid和 egid来确定进程对资源的访问权限。 一个进程如果没有SUID或SGID位,则euid=uid egid=gid,分别是运行这个程 序的用户的 uid和gid。例如
kevin用户的uid和gid分别为204和202
foo用户的ui d和gid为200,201
kevin运行myfile 程序形成的进程的euid=uid=204,egid=gid =202,内核根据这些值来判断进程对资源访问的限制,其实就是kevin用户对资源 访 问的权限,和foo没关系。

如果一个程序设置了SUID,则euid和egid变成被运行的程序的所有者的uid 和 gid,例如kevin用户运行 myfile,euid=200,egid=201,uid=204,gid=202,则 这个进程具有它的属主foo的资源访问权限。 SUID的作用就是这样:让本来没有相应权限的用户运行这个程序时,可以访 问他没有权限访问的资源。passwd就是一个很鲜明的例子。 SUID的优先级比SGID 高,当一个可执行程序设置了SUID,则SGID会自动变成 相应的egid。

下面讨论一个例子: UNIX系统有一个/dev/kmem的设备文件, 是一个字符设备文件,里面存储了核 心程序要访问的数据,包括用户的口令。所以这个文件不能给一般的用户读写, 权限设为:

crr—- 1 root system 2, 1 May 25 1998 kmem

但ps等程序要读这个文件,而ps的权限设置如下:

-r-xr-sr- x 1 bin system 59346 Apr 05 1998

ps 这是一个设置了SGID的程序,而ps的用户是bin,不是root,所以不能设置SUID来 访问kmem,但大家注意了,bin和root都属于system组,而且ps设置了SGID,一般 用户执行ps,就会获得 system组用户的权限,而文件kmem的同组用户的权限是可 读,所以一般用户执行ps就没问题了。
但有些人说,为什么不把ps程序设置为 root 用户的程序,然后设置SUID位,不也行吗?这的确可以解决问题,但实际中 为什么不这样做呢?因为SGID的风险比SUID小得多,所以出于系统安全的考虑, 应该尽量用SGID代替SUID的程序,如果可能的话。 下面来说明一下SGID对目录的影响。SUID对目录没有影响。 如果一个目录设置了 SGID位,那么如果任何一个用户对这个目录有写权限的 话,他在这个目录所建立的文件的组都会自动转为这个目录的属主所在的组,而 文件所有者不变,还是属于建立这个文件的用户


返回:

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License