什么是 SUID, SGID 和 Sticky bit

在可执行文件中有三种权限,如下:

1. SUID 权限 (Set-user Identification)

2. SGID 权限(Set-group identification)

3. Sticky bit

下面逐个对这三个东西来解释一下

这个最开始用在  共享文件夹

一、UNIX下关于文件权限的表示方法解析

用ls -l可以查看当前目录底下文件的属性,格式一般如下:

drwxr-xr-x@ 20 bob  staff    680  6 21  2017 3.日记

上一行中,我们看到了drwxr-xr-x。下面解析一下这一格式所表示的意思: 
这种表示方法一共有十位: 
    9 8 7 6 5 4 3 2 1 0 
    d  r w x r  - x r - x 
第9位表示文件类型,可以为p、d、l、s、c、b和-: 
        p表示命名管道文件 
        d表示目录文件 ,文件夹
        l表示符号连接文件 
        -表示普通文件 
        s表示socket文件 
        c表示字符设备文件 ,里面为一次性读取装置
        b表示块设备文件 , 里面可以供存储周边设备

第8-6 位   是指拥有者对这个文件所能执行的权限  
类似于windows中的所有者权限比如 administrator 对文件具有 修改、读取和执行权限
 
第5-3位  是指所属于这个组的成员对于这个文件具有的权限      
类似于windows中的组权限比如administrators组,属于这个组的成员对于文件的都有 哪些 权限
 
第2-0位  -- 是指其他人对于这个文件的权限

类似于windows中的 anyone 一样就是说所有人对着个文件都会有一个怎样的权限.

0-8是权限位,里面的字母的含义如下:

1.r(Read,读取):对文件而言,具有读取文件内容的权限;对目录来说,
  具有浏览目 录的权限。 

2.w(Write,写入):对文件而言,具有新增、修改文件内容的权限;对目
  录来说,具有删除、移动目录内文件的权限。

3.x(eXecute,执行):对文件而言,具有执行文件的权限;对目录了来说
  该用户具有进入目录的权限。
4.- 表示没有相应的权限
 
比如: ls -l myfile显示为:

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

  表示文件myfile是普通文件文件的所有者是bob用户而bob用户属于staff组文件只有1个硬连接长度是7734个字节最后修改时间4月5日17:07。 

 

  如果一个文件被设置了SUIDSGID会分别表现在所有者或同组用户的权限的可执行位上。例如:

  1、-rwsr-xr-x 表示SUID所有者权限中可执行位被设置

  2、-rwSr--r-- 表示SUID被设置但所有者权限中可执行位没有被设置

  3、-rwxr-sr-x 表示SGID同组用户权限中可执行位被设置

  4、-rw-r-Sr-- 表示SGID被设置但同组用户权限中可执行位没有被社

  其实在UNIX的实现中文件权限用12个二进制位表示如果该位置上的值是

  1表示有相应的权限:

  11 10 9 8 7 6 5 4 3 2 1 0

  S G T r w x r w x r w x

  第11位为SUID第10位为SGID第9位为sticky第8-0位对应于上面的三组rwx位。

  11 10 9 8 7 6 5 4 3 2 1 0

  上面的-rwsr-xr-x的值为: 1 0 0 1 1 1 1 0 1 1 0 1

  -rw-r-Sr--的值为: 0 1 0 1 1 0 1 0 0 1 0 0

  给文件加SUIDSUID的命令如下:

  chmod u+s filename 设置SUID

  chmod u-s filename 去掉SUID设置

  chmod g+s filename 设置SGID

  chmod g-s filename 去掉SGID设置

  另外一种方法是chmod命令用八进制表示方法的设置。如果明白了前面的12位权限表示法也很简单。

  比如chmod 7777  ,有时候 会只写三位  chmod 777   就是说任何人都对 这个文件有读写和执行的权限

  改变文件的权限的属性

    命令:chmod

    语法

           chmod[OPTION]...MODE[,MODE]...FILE...
           chmod[OPTION]...OCTAL-MODE FILE...
           chmod[OPTION]...--reference=RFILE
         功能:
          更改文件的访问权限。Linux下文件访问分为读、写、执行三种;另外还规定了拥有者、所属组和所有人三个对象范围。
        路径:/bin/chmod
        参数:
        --help 表示使用帮助
        --reference=RFILE 将指定文件的访问权限设置为RFILE模式
        -c,--change 仅仅显示做出更改的部分
        -f,--silent,--quiet 禁止多数错误信息
        -R,--recursive 连同目录下面的文件和文件夹一起处理(慎重使用)
        -v,--verbose 显示命令执行的详细信息
        MODE由三个部分组成:一个或以上字母“ugoa”,一个或一个以上符号"+-=",然后是一个或一个以上的字母“rwxXstugo”。u表示文件的拥有者;g表示文件所属组;o表示除了文件拥有者和所属组外其它用户;a表示所有用户。rwx前面说过就不解释了;“X”只有目标文件对某些用户是可执行的或该目标文件是目录时才追加X属性;"s"同时设定用户和组ID;“t”位元(保存程序的文本到交换的设备上);"u"目标文件属主;"g"目标文件所在的群组;"o"其它用户。以上是字符形式的用法。
        数字形式用法:
        chmod[选项][0000-7777]文件名称
        chmod[选项][000-777]文件名称
        完整的数字权限是4位數。但在一般情況下,都只带入三位,其代表的就是“后三位”的权限设定。
        第一位
        代表文件或文件夹的特殊性。4代表“suid;2代表“sgid”;1代表“沾滞元位-save text image”
        后三位
        依序代表“user-拥有者”,"group-群组","other-其它",每一位,代表三种权限的叠加,4-读(r),2-写(w),1-执行(x),被禁止的权限以0表示。
        例1:用字符方法,对myfile文件拥有者和群组赋予执行的权限。
        [root@localhost/]#chmod -c ug+x myfile
        'myfile'的权限模式已更改为0754(rwxr-xr--)
        例2:用数值赋值的方法,将myfile文件变更为文件拥有者具有读、写、执行权限,其它用户只有读取的权限。
分析:
[root@localhost/]#chmod -c 744 myfile
'myfile'的权限模式已更改为0744(rwxr--r--) 
 

  二、SUIDSGID的详细解析

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

  首先讲普通文件的SUIDSGID的作用。例子:

  如果普通文件myfile是属于foo用户的是可执行的现在没设SUIDls命令显示如下:

   -rwxr-xr-x 1 foo staff 7734 Apr 05 17:07 myfile任何用户都可以执行这个程序。UNIX的内核是根据什么来确定一个进程对资源的访问权限的呢?是这个进程的运行用户的(有效)ID包括 user idgroup id。用户可以用id命令来查到自己的或其他用户的user idgroup id。

  除了一般的user id group id外还有两个称之为effective 的id就是有效id上面的四个id表示为:uidgideuidegid。内核主要是根据euidegid来确定进程对资源的访问权限。

   一个进程如果没有SUIDSGID则euid=uid egid=gid分别是运行这个程序的用户的uidgid。例如kevin用户的uidgid分别为204202foo用户的uidgid为 200201kevin运行myfile程序形成的进程的euid=uid=204egid=gid=202内核根据这些值来判断进程对资源访问 的限制其实就是kevin用户对资源访问的权限foo没关系。

  如果一个程序设置了SUID则euidegid变成被运行的程序的所有者的uidgid例如kevin用户运行myfileeuid=200egid=201uid=204gid=202则这个进程具有它的属主foo的资源访问权限。

  SUID的作用就是这样:让本来没有相应权限的用户运行这个程序时可以访问他没有权限访问的资源。passwd就是一个很鲜明的例子。

  SUID的优先级比SGID当一个可执行程序设置了SUIDSGID会自动变成相应的egid。

  下面讨论一个例子:

   UNIX系统有一个/dev/kmem的设备文件是一个字符设备文件里面存储了核心程序要访问的数据包括用户的口令。所以这个文件不能给一般的 用户读写权限设为:cr--r----- 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但大家注意了binroot都属于 system组而且ps设置了SGID一般用户执行ps就会获得system组用户的权限而文件kmem的同组用户的权限是可读所以一般用户执 行ps就没问题了。但有些人说为什么不把ps程序设置为root用户的程序然后设置SUID不也行吗?这的确可以解决问题但实际中为什么不这样 做呢?因为SGID的风险比SUID小得多所以出于系统安全的考虑应该尽量用SGID代替SUID的程序如果可能的话。下面来说明一下SGID对目 录的影响。SUID对目录没有影响。如果一个目录设置了SGID那么如果任何一个用户对这个目录有写权限的话他在这个目录所建立的文件的组都会自动 转为这个目录的属主所在的组而文件所有者不变还是属于建立这个文件的用户。

  三、关于SUIDSGID的编程

  SUIDSGID编程比较密切相关的有以下的头文件函数:

  #include

  #include

  uid_t getuid(void);

  uid_t geteuid(void);

  gid_t getgid (void);

  gid_t getegid (void);

  int setuid (uid_t UID);

  int setruid (uid_t RUID);

  int seteuid (uid_t EUID);

  int setreuid (uid_t RUID,uid_t EUID);

  int setgid (gid_t GID);

  int setrgid (gid_t RGID);

  int setegid (git_t EGID);

  int setregid (gid_t RGID, gid_t EGID);

  具体这些函数的说明在这里就不详细列出来了,要用到的可以用man查。

  SUID/SGID :

  假如你有文件a.txt

  #ls -l a.txt

  -rwxrwxrwx

  #chmod 4777 a.txt

  -rwsrwxrwx ======>注意s位置

  #chmod 2777 a.txt

  -rwxrwsrwx ======>注意s位置

  #chmod 7777 a.txt

  -rwsrwxswt ======>出现了t,t的作用在内存中尽量保存a.txt,节省系统再加载的时间.

  现在再看前面设置 SUID/SGID作用:

  #cd /sbin

  #./lsusb

  ...

  #su aaa(普通用户)

  $./lsusb

  ...

  是不是现在显示出错?

  $su

  #chmod 4755 lsusb

  #su aaa

  $./lsusb

  ... 现在明白了吗?本来是只有root用户才能执行的命令加了SUID,普通用户就可以像root一样的用权限提升了。上面是对于文件来说的对于目录也差不多!

   目录的S属性使得在该目录下创建的任何文件及子目录属于该目录所拥有的组目录的T属性使得该目录的所有者及root才能删除该目录。还有对于s与 S设置SUID/SGID需要有运行权限否则用ls -l后就会看到S,证明你所设置的SUID/SGID没有起作用。

  Why we need suid,how do we use suid?

  r -- 读访问

  w -- 写访问

  x -- 执行许可

  s -- SUID/SGID

  t -- sticky

  那么 suid/sgid是做什么的? 为什么会有suid位呢?

  要想明白这个先让我们看个问题:如果让每个用户更改自己的密码?

  用户修改密码是通过运行命令passwd来实现的。最终必须要修改/etc/passwd文件而passwd的文件的属性是:

  #ls -l /etc/passwd

  -rw-r--r-- 1 root root 2520 Jul 12 18:25 passwd

  我们可以看到passwd文件只有对于root用户是可写的而对于所有的他用户来说都是没有写权限的。 那么一个普通的用户如何能够通过运行passwd命令修改这个passwd文件呢?

  为了解决这个问题SUID/SGID便应运而生。而且AT&T对它申请了专利。 呵呵。

  SUIDSGID是如何解决这个问题呢?

  首先我们要知道一点:进程在运行的时候有一些属性其中包括 实际用户ID,实际组ID,有效用户ID,有效组ID等。 实际用户ID实际组ID标识我们是谁谁在运行这个程序,一般这2个字段在登陆时决定在一个登陆会话期间 这些值基本上不改变。

  而有效用户ID有效组ID则决定了进程在运行时的权限。内核在决定进程是否有文件存取权限时是采用了进程的有效用户ID来进行判断的。

  知道了这点我们来看看SUID的解决途径:

  当一个程序设置了为SUID位时内核就知道了运行这个程序的时候应该认为是文件的所有者在运行这个程序。即该程序运行的时候有效用户ID是该程序的所有者。举个例子:

  [root@sgrid5 bin]# ls -l passwd

  -r-s--s--x 1 root root 16336 Feb 14 2003 passwd

   虽然你以test登陆系统但是当你输入passwd命令来更改密码的时候由于passwd设置了SUID因此虽然进程的实际用户ID是 test对应的ID但是进程的有效用户ID则是passwd文件的所有者root的ID,因此可以修改/etc/passwd文件。

  让我们看另外一个例子。

  ping命令应用广泛可以测试网络是否连接正常。ping在运行中是采用了ICMP协议需要发送ICMP报文。但是只有root用户才能建立ICMP报文如何解决这个问题呢?同样也是通过SUID位来解决。

  [root@sgrid5 bin]# ls -l /bin/ping

  -rwsr-sr-x 1 root root 28628 Jan 25 2003 /bin/ping

  我们可以测试一下如果去掉ping的SUID再用普通用户去运行命令看会怎么样。

  [root@sgrid5 bin]#chmod u-s /bin/ping

  [root@sgrid5 bin]# ls -l ping

  -rwxr-xr-x 1 root root 28628 Jan 25 2003 ping

  [root@sgrid5 bin]#su test

  [test@sgrid5 bin]$ ping byhh.net

  ping: icmp open socket: Operation not permitted

  SUID虽然很好了解决了一些问题但是同时也会带来一些安全隐患。

  因为设置了 SUID 位的程序如果被攻击(通过缓冲区溢出等方面),那么hacker就可以拿到root权限。

  因此在安全方面特别要注意那些设置了SUID的程序。

  通过以下的命令可以找到系统上所有的设置了suid的文件:

  [root@sgrid5 /]# find / -perm -04000 -type f -ls

  对于这里为什么是4000大家可以看一下前面的st_mode的各bit的意义就明白了。

  在这些设置了suid的程序里如果用不上的就最好取消该程序的suid位。

Sticky Bit

这 个Sticky Bit当前只针对目录有效对文件没有效果。SBit对目录的作用是:“在具有SBit的目录下用户若在该目录下具有w及x权限则当用户在该目录下建 立文件或目录时只有文件拥有者与root才有权力删除”。换句话说:当甲用户在A目录下拥有group或other的项目且拥有w权限这表示甲用户 对该目录内任何人建立的目录或文件均可进行“删除/重命名/移动”等操作。不过如果将A目录加上了Sticky bit的权限则甲只能够针对自己建立的文件或目录进行删除/重命名/移动等操作。

举例来说/tmp本身的权限是“drwxrwxrwt”在这样的权限内容下任何人都可以在 /tmp内新增、修改文件但仅有该文件/目录的建立者与root能够删除自己的目录或文件。这个特性也很重要。可以这样做个简单测试:

1. 以root登入系统并且进入 /tmp中。

2. touch test并且更改test权限成为777。

3. 以一般用户登入并进入 /tmp。

4. 尝试删除test文件。

参考链接:

http://blog.csdn.net/xuhuojun/article/details/2028118

http://blog.chinaunix.net/uid-25314474-id-3313109.html

上一篇:文件的特殊权限(SUID,SGID,SBIT)


下一篇:Linux PHP增加JSON支持及如何使用JSON