程序员伤不起的 30 岁
点击上方“程序员大咖”,选择“置顶公众号”
以下是对用户和组信息的举例。 /etc/shadow 中的口令信息为加密存储,不举例。
$cat /etc/passwd |head -n 5
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
$cat /etc/group |head -n 5
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:miracle
输出中, 第1个字符表示文件类型,其中,普通文件(-)、目录文件 (d)、套接字文件(s),管道文件(p),字符文件(c),块文件(b),链接文件(l); 第2个字符开始的 -rwxr-xr-x 部分表示文件的权限位,共有9位。
对于文件 /usr/bin/qemu-i386 , 这个权限控制的含义是:
第2~4位的 rwx 表示该文件可被它的 owner (属主)以 r 或 w 或 x 的权限访问。
第5~7位的 r-x 表示该文件可被与该文件同一属组的用户以 r 或 x 的权限访问
第8~10位的 r-x 表示该文件可被其它未知用户以 r 或 x 的权限访问。
对于 test/, test2/, test3/ 设定的权限:
r,w,x 权限对每一权限控制组的权限用一位8进制来表示; 例如: 755 表示 rwxr-xr-x。
s,t 权限会替代 x 位置显示;设定 s,t 权限则需在对应的、用于控制 r,w,x 的8进制权限控制组前追加数字; s 权限用于属主属组控制, t 用于其它控制。
设定属主 s 需追加 4, 设定属组 s 追加 2, 设定其它者 t 权限追加 1 ; 例如前面对 test/ 设定 t, 则用 1775, 表示 rwxrwxr-t 。
进程权限控制信息
进程权限
对于进程,有如下属性与文件访问权限相关:
effective user id : 进程访问文件权限相关的 UID (简写为 euid )。
effective group id : 进程访问文件权限相关的 GID (简写为 egid )。
real user id : 创建该进程的用户登录系统时的 UID (简写为 ruid )。
real group id : 创建该进程的用户登录系统时的 GID (简写为 rgid )。
saved set user id : 拷贝自 euid 。
saved set group id : 拷贝自 egid 。
举例
我们可以使用 ps 和 top 选择查看具有 euid 和 ruid 的进程。或者通过 top 来查看进程的 euid 和 ruid
通过 top 来查看的例子:
首先输入 top 得到类似如下
其中, PID 是对应进程, USER 是对应的 effective user, RUSER 是对应的 real user 。
进程访问文件的权限控制策略
规则
进程访问文件大致权限控制策略
对于进程访问文件而言,最重要的是 euid, 所以其权限属性均以 euid 为 “中心”。
进程的 euid 一般默认即为 其 ruid 值
若可执行文件的可执行权限位为 s ,进程对其调用 exec 后,其 euid 被设置为该可执行文件的 user id
进程的 saved set user id 拷贝自 euid.
当进程的 euid 与文件的 user id 匹配时,进程才具有文件 user 权限位所设定的权限
组权限 egid 的控制规则类似。
通过 exec 执行文件修改权限属性
通过 exec 调用可执行文件之时:
进程 ruid 值始终不变;
saved set-user ID 始终来自 euid ;
euid 值取决于文件的 set-user-ID 位是否被设置。
如下:
举例
再举几个比较特别的例子:
- 设置了 set-user-id
$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 71288 2月 28 2013 /usr/bin/sudo
如前所述,这个输出的含义是,对于 /usr/bin/sudo 文件,
第1~3位的 rws 表示该文件可被它的owner(属主)以 r 或 w 或 s 的权限访问
第4~6位的 r-x 表示该文件可被与该文件同一属组的用户以 r 或 x 的权限访问。
第7~9位的 r-x 表示该文件可被其它未知用户以 r 或 x 的权限访问。
这样设置之后,对于owner,具有读、写、执行权限,这一点没有什么不同。但是对于不属于 root 组的普通用户进程来说,却大不相同。
普通用户进程执行 sudo 命令时通过其 others 中的 x 获得执行权限,再通过 user 中的 s使得普通用户进程临时具有了 sudo 可执行文件属主( root )的权限,即超级权限。
这也是为什么通过 sudo 命令就可以让普通用户执行许多管理员权限的命令的原因。
- 设置了 stick-bit
$ ls -l / |grep tmp
drwxrwxrwt 25 root root 12288 7月 20 09:09 tmp
这样设置之后,对于 /tmp 目录,任何人都具有读、写、执行权限,这一点没有什么不同。但是对于 others 部分设置了粘滞位 t, 其功能却大不相同。
若目录没设置粘滞位,任何对目录有写权限者都则可删除其中任何文件和子目录,即使他不是相应文件的所有者,也没有读或写许可; 设置粘滞位后,用户就只能写或删除属于他的文件和子目录。
这也是为什么任何人都能向 /tmp 目录写文件、目录,却只能写和删除自己拥有的文件或目录的原因。
举一个 man 程序的应用片断,描述 set-user-id 和 saved set-user-id 的使用
man 程序可以用来显示在线帮助手册, man 程序可以被安装指定 set-user-ID 或者 set-group-ID 为一个指定的用户或者组。
man 程序可以读取或者覆盖某些位置的文件,这一般由一个配置文件(通常是 /etc/man.config 或者 /etc/manpath.config )或者命令行选项来进行配置。
man 程序可能会执行一些其它的命令来处理包含显示的 man 手册页的文件。
为防止处理出错, man 会从两个特权之间进行切换:运行 man 命令的用户特权,以及 man程序的拥有者的特权。
需要抓住的主线:当只执行 man 之时,进程特权就是 man 用户的特权, 当通过 man 执行子进程(如通过 !bash 引出shell命令)时,用户切换为当前用户,执行完又切换回去。
过程如下:
假设 man 程序文件被用户 man 所拥有,并且已经被设置了它的 set-user-ID 位,当我们 exec 它的时候,我们有如下情况:
real user ID = 我们的用户UID
effective user ID = man用户UID
saved set-user-ID = man用户UID
man 程序会访问需要的配置文件和 man 手册页。这些文件由 man 用户所拥有,但是由于 effective user ID 是 man,文件的访问就被允许了。
在 man 为我们运行任何命令的时候,它会调用 setuid(getuid())) (getuid() 返回的是 real user id).因为我们不是 superuser 进程,这个变化只能改变 effective user ID. 我们会有如下情况:
现在 man 进程运行的时候把我们得UID作为它的 effective user ID.这也就是说,我们只能访问我们拥有自己权限的文件。也就是说,它能够代表我们安全地执行任何 filter.
real user ID = 我们的用户UID(不会被改变)
effective user ID = 我们的用户UID
saved set-user-ID = man 的用户UID(不会被改变)
当 filter 做完了的时候, man 会调用 setuid(euid).这里, euid 是 man 用户的UID.(这个ID是通过 man 调用 geteuid 来保存的)这个调用是可以的,因为 setuid 的参数和 saved set-user-ID 是相等的。(这也就是为什么我们需要 saved set-user-ID).这时候我们会有如下情况:
real user ID = 我们的用户UID(不会被改变)
effective user ID = man的UID
saved set-user-ID = man 的用户UID(不会被改变)
由于 effective user ID 是 man,现在 man 程序可以操作它自己的文件了。通过这样使用 saved set-user-ID,我们可以在进程开始和结束的时候通过程序文件的 set-user-ID 来使用额外的权限。然而,期间我们却是以我们自己的权限运行的。如果我们无法在最后切换回 saved set-user-ID,我们就可能会在我们运行的时候保留额外的权限。
下面我们来看看如果 man 启动一个 shell 的时候会发生什么:
这里的 shell 是 man 使用 fork 和 exec 来启动的。
因为这时 real user ID 和 effective user ID 都是我们的普通用户UID(参见step3), 所以 shell 没有其它额外的权限.
启动的 shell 无法访问 man 的 saved set-user-ID(man) ,因为 shell 的 saved set-user-ID 是由 exec 从 effective user ID 拷贝过来的。
在执行 exec 的子进程( shell )中,所有的 user ID 都是我们的普通用户ID.
实际上,我们描述 man 使用 setuid 函数的方法不是特别正确,因为程序可能会 set-user-ID 为 root .这时候, setuid 会把所有三种uid都变成你设置的id,但是我们只需要设置 effective user ID。
来源:Linux爱好者
https://mp.weixin.qq.com/s/NOmUGsozkWF1IExo8OKC0g
程序员大咖整理发布,转载请联系作者获得授权