Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1071374
  • 博文数量: 242
  • 博客积分: 10209
  • 博客等级: 上将
  • 技术积分: 3028
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-12 09:27
文章分类

全部博文(242)

文章存档

2014年(1)

2013年(1)

2010年(51)

2009年(65)

2008年(124)

我的朋友

分类: LINUX

2008-03-14 10:30:44

一、 SUID/SGID概述(收集整理

  有时,没有被授权的用户需要完成某项任务。一个例子是passwd程序,它允许用户改变口令,这就要求改变/etc/passwd文件的口令域。然而系统管理员决不允许普通用户拥有直接改变这个文件的权利,因为这绝对不是一个好主意。85iLinux联盟
  为了解决这个问题,SUID/SGID便应运而生。UNIX允许程序被授权,当程序被执行的时候,拥有超级用户的权限,完成时又回到普通用户的权限。这个主意很好,所以AT&T对它申请了专利。

二、 UNIX下的一些名词简介

  1.文件权限。确定用户读取、修改或执行文件的权力。85iLinux联盟
    r -- 读访问85iLinux联盟
    w -- 写访问85iLinux联盟
    x -- 执行许可85iLinux联盟
    s -- SUID/SGID85iLinux联盟
    t -- sticky位85iLinux联盟
  2.进程。进程是程序运行一次的过程,以完成预定的任务,它不同于程序。每个进程都有一个唯一的进程ID。此外,每个进程还有一些其他标识符:实际用户ID、实际组ID、有效用户ID、有效组ID。超级用户进程的实际用户ID和有效用户ID为0。85iLinux联盟
  3.超级用户root。超级用户拥有系统的完全控制权。

三、 SUID/SGID的思路

  SUID的程序在运行时,将有效用户ID改变为该程序的所有者ID,使得进程在很大程度上拥有了该程序的所有者的特权。如果被设置为SUID root,那么这个进程将拥有超级用户的特权(当然,一些较新版本的UNIX系统加强了这一方面的安全检测,一定程度上降低了安全隐患)。当进程结束时,又恢复为原来的状态。

注:SUID/SGID程序在执行时的Real Uid可以通过函数setuid()改变

四、一个SUID程序

  下面的程序是用来演示UNIX文件的SUID,取名为parent.c

  #include 〈stdio.h〉85iLinux联盟
  #include 〈stdlib.h〉85iLinux联盟
  #include 〈unistd.h〉85iLinux联盟
  #include 〈sys/types.h〉85iLinux联盟
  int85iLinux联盟
  main(int argc,char **argv)85iLinux联盟
  {85iLinux联盟
    int i;85iLinux联盟
    char **argu;85iLinux联盟
    uid_t uid;85iLinux联盟
    uid=geteuid(); //获取调用进程的有效用户ID85iLinux联盟
    if(argc<2){85iLinux联盟
      fprintf(stderr,"usage: %s \n",argv[0]);85iLinux联盟
      exit(0);85iLinux联盟
    }85iLinux联盟
    if(setuid(uid)<0){85iLinux联盟
      fputs("setuid error.\n",stderr);85iLinux联盟
      exit(1);85iLinux联盟
    } //将调用进程的实际用户ID设置为有效用户ID85iLinux联盟
    if((argu=(char**)malloc(argc*sizeof(char*)))==NULL){85iLinux联盟
       fputs("malloc error.\n",stderr);85iLinux联盟
       exit(1);85iLinux联盟
    } //为execvp的参数指针数组分配内存空间85iLinux联盟
    for(i=0;i     argu[argc-1]=(char *)0; //参数指针数组以空指针结尾85iLinux联盟
    if(execvp(argv[1],argu)<0){85iLinux联盟
      fputs("exec error.\n",stderr);85iLinux联盟
      exit(1);85iLinux联盟
    } //用execvp调用命令行参数指定的程序85iLinux联盟
    exit(0);85iLinux联盟
  }

85iLinux联盟
  该程序将一个SUID的进程转变为一个超级用户进程。将此程序编译成可执行目标文件parent ,用另一个简单的程序进行检验

  int main(void){85iLinux联盟
    printf("real uid=%d, effective uid=%d\n",getuid(),geteuid());85iLinux联盟
    exit(0);85iLinux联盟
  }

  编译为printuids。运行程序得到下列结果:

  $ ./parent printuids //正常执行,无特权85iLinux联盟
  real uid=506, effective uid=50685iLinux联盟
  $ su root85iLinux联盟
  Password:85iLinux联盟
  # chown root parent //更改所有者85iLinux联盟
  # chmod u+s parent //添加SUID85iLinux联盟
  # exit85iLinux联盟
  $ ./parent printuidsv   real uid=0, effective uid=0 //该进程转变为超级用户进程

  某一进程一旦转变为超级用户进程,将拥有系统的完全控制权。比如,我们可以这样执行演示程序:   $ ./parent useradd hacker85iLinux联盟
  $ ./parent passwd hacker85iLinux联盟
  故而,SUID的程序往往伴随着一定的安全问题。在早期的UNIX环境中,SUID/SGID的程序调用system()函数就存在着安全性漏洞。

五、 再谈SUID/SGID程序的安全问题

  有时,一个SUID程序与一个系统程序(或库函数)之间的交互作用会产生连程序的编制者也不知道的安全漏洞。一个典型的例子是 /usr/lib/preserve程序。它被vi和ex编辑器使用,当用户在写出对文件的改变前被意外与系统中断时,它可以自动制作一个正被编辑的文件的拷贝。这个保存的(preserve)程序将改变写到在一个专门的目录内的一个临时文件上,然后利用/bin/mail程序发送给用户一个"文件已经被存"的通知。85iLinux联盟
  由于人们可能正在编辑一个私人的或一个机密的文件,被preserve程序(旧版)使用的那个目录不能被一般用户访问。为了使preserve程序可以写入那个目录,以及使 recover程序可以从那里读,这些程序被设置为SUID root。 这个preserve程序有三个特点值得注意:85iLinux联盟
  1. 这个程序被设置为SUID root。85iLinux联盟
  2. 该程序以root用户的身份运行/bin/mail程序。85iLinux联盟
  3. 该程序调用system()函数调用mail程序。85iLinux联盟
  由于system()函数调用shell对命令字符串进行语法分析,而shell则使用IFS变量作为其输入字段的分割符。早期的shell版本在被调用是时不将此变量恢复为普通字符集。如果先将IFS设置为"/",然后调用vi程序,继而调用preserve程序,就有可能使 usr/lib/preserve程序执行一个在当前目录下的bin程序(/bin/mail被解析为带有参数mail的bin程序)。85iLinux联盟
  如果我们利用前面的演示程序编写一个简单的shell script文件命名为bin,它就有可能通过上面的安全漏洞被执行:

  # shell script to make an SUID-root 85iLinux联盟
shell85iLinux联盟
  #85iLinux联盟
  chown root parent85iLinux联盟
  chmod 4755 parent

  那么它的后果将是……

  参考文献:85iLinux联盟
W.Richard Stevens: Advanced Programming in the UNIX Environment85iLinux联盟
Simson Garfinkel, Gene Spafford: Pracitical UNIX & Internet Security85iLinux联盟
 

 

 

==========================================================

1. 4000---调整用户号 85iLinux联盟
   2000---调整组号 85iLinux联盟
   1000---粘着置位 

2. suid/guid程序 85iLinux联盟
   当一个程序的用户或组被置位的时候,即4000或2000时,可实现某些特殊的功能一般来说, 85iLinux联盟
   一个运行中的程序为运行这个程序的用户所拥有,但如果该程序是suid/guid程序,则运行 85iLinux联盟
   的程序则为文件所有者拥有,运行中的程序在程序运行期间拥有文件所有者的全部权限 85iLinux联盟
   如果一个普通用户运行了一个属于根用户的带s标志的程序,则该程序不考虑用户权限, 85iLinux联盟
   自动拥有在系统中读/写任何文件及目录的特权,对于guid程序也是一样的。 85iLinux联盟
   最典型的要数/usr/bin/passwd程序了,-r-s--x--x ,可帮助普通用户更改在系统中的密码, 85iLinux联盟
   利用的就是suid的作用。 但也要严格设置这种权限,避免破坏性,

因为如果你的suid程序是/bin/bash的话,则会导致严重后果,一个普通用户若在某个短时间 85iLinux联盟
取得过root权限,他就能设置一个suid程序/binb/bash来取得根特权。 85iLinux联盟
(若拿它来破坏别人的系统,后果自负)

# cp /bin/bash /home/jephe/.backdoor

# chmod 4755 /home/jephe/.backdoor

这样当攻击者执行了/home/jephe/.backdoor后就得到了根特权,可用id命令显示suid=0

因此一个管理员应定期运行检查程序检查系统内有无异常的suid/guid程序:象下面这样的命令

#find / -type f \( -perm -04000 -o -perm -02000 \) \-exec ls -lg {} \; >suid-sguid-results

把上面的命令放入cron job并邮递文件suid-guid-resuilts给管理员邮箱帐号.

3. 程序的t属性 85iLinux联盟
粘着位 告诉系统在程序完成后在内存中保存一份运行程序的备份,如该程序常用,可为系统 85iLinux联盟
节省点时间,不用每次从磁盘加载到内存

85iLinux联盟
4.目录的s属性 

目录的S属性使得在该目录下创建的任何文件及目录属于该目录所拥有的组。 85iLinux联盟
例如在apache中为个人设置WEB目录的时候,如果给apache分配的组名为httpd. 85iLinux联盟
则:

#chown -R jephe.httpd ~jephe/public_html 85iLinux联盟
#chmod -R 2770 ~jephe/public_html

确保在public_html中创建新的文件或子目录时,新创建的文件设置了组ID。

另外如有两个用户a和b都属于组c,则希望在某目录下a创建的文件也能被b修改,则 85iLinux联盟
可设置该目录chmod +s属性,同时设置a和b的默认umask为770。

5. 目录的T属性 85iLinux联盟
设置了目录的T属性后1000,由只有该目录的所有者及root才能删除该目录,如 85iLinux联盟
/tmp目录就是drwxrwxrwt

6.  文件及目录的三种时间位  85iLinux联盟
每个Linux文件有三种保存着的时间日期标志。

文件建立时间 (实际上是文件I节点建立时间)  85iLinux联盟
文件最后访问时间 85iLinux联盟
文件最后修改时间

85iLinux联盟
默认ls -l时显示的是文件最后修改时间,也可用ls -l --time=atime(文件最后访问时间) 85iLinux联盟
ls -l --time=ctime(文件建立时间)

可用touch命令改变时间日期标志,从而可隐蔽攻击者对文件放置特洛伊木马后对文件时间 85iLinux联盟
的修改

7。可用chattr改变文件及目录的属性。

有时你会发现对某个文件即使是root用户也不能修改或添加新内容,那很可能是该文件被 85iLinux联盟
用chattr命令设置成不可更改或附加新内容了。你必须先用chattr去掉这些属性再更改内容。 85iLinux联盟
 

85iLinux联盟
 

==============================================================

 

每一个文件都有一个所有者, 表示该文件是谁创建的. 同时, 该文件还有一个组编号, 表示该文件所属的组, 一般为文件所有者所属的组. 如果是一个可执行文件, 那么在执行时, 一般该文件只拥有调用该文件的用户具有的权限. 而setuid, setgid 可以来改变这种设置. 85iLinux联盟
   setuid: 设置使文件在执行阶段具有文件所有者的权限. 典型的文件是 /usr/bin/passwd. 如果一般用户执行该文件, 则在执行过程中, 该文件可以获得root权限, 从而可以更改用户的密码. 85iLinux联盟
   管理员可以用下面这条命令来检查系统内有无异常的suid/guid程序:85iLinux联盟
#find / -type f \( -perm -04000 -o -perm -02000 \) \-exec ls -lg {} \; 85iLinux联盟
   setgid: 该权限只对目录有效. 目录被设置该位后, 任何用户在此目录下创建的文件都具有和该目录所属的组相同的组. 85iLinux联盟
   sticky bit: 该位可以理解为防删除位. 一个文件是否可以被某用户删除, 主要取决于该用户是否有该文件所在目录的写权限. 如果没有写权限, 则这个目录下的所有文件都不能被删除, 同时也不能添加新的文件. 如果希望用户能够添加文件但同时不能删除文件, 则可以对文件夹使用sticky bit位. 设置该位后, 就算用户对目录具有写权限, 也不能删除不属于他的文件(root除外).

如何操作这些标志: 85iLinux联盟
操作这些标志与操作文件权限的命令是一样的, 都是 chmod. 有两种方法来操作, 85iLinux联盟
1) chmod u+s temp -- 为temp文件加上setuid标志. (setuid 只对文件有效) 85iLinux联盟
chmod g+s tempdir -- 为tempdir目录加上setgid标志 (setgid 只对目录有效) 85iLinux联盟
chmod o+t temp -- 为temp加上sticky标志

2) 采用八进制方式. 对一般文件通过三组八进制数字来置标志, 如 666, 777, 644等. 如果设置这些特殊标志, 则在这组数字之外外加一组八进制数字. 如 4666, 2777等. 这一组八进制数字三位的意义如下, 85iLinux联盟
abc 85iLinux联盟
a - setuid位, 如果该位为1, 则表示设置setuid 85iLinux联盟
b - setgid位, 如果该位为1, 则表示设置setgid 85iLinux联盟
c - sticky位, 如果该位为1, 则表示设置sticky

设置完这些标志后, 可以用 ls -l 来查看. 如果有这些标志, 则会在原来的执行标志位置上显示. 如 85iLinux联盟
rwsrw-r-- 表示有setuid标志 85iLinux联盟
rwxrwsrw- 表示有setgid标志 85iLinux联盟
rwxrw-rwt 表示有sticky标志 85iLinux联盟
如果本来在该位上有x, 则这些特殊标志显示为小写字母 (s, s, t). 否则, 显示为大写字母 (S, S, T)

 

 

=======================================================

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

    SUID 是 Set User ID, SGID 是 Set Group ID的意思。

    Linux下可以用ls -l 命令来看到文件的权限。用ls命令所得到的表示法的格式是类似这样的:-rwxr-xr-x 。下面解析一下格式所表示的意思。 85iLinux联盟
    这种表示方法一共有十位: 85iLinux联盟
    9 8 7 6 5 4 3 2 1 0 85iLinux联盟
    - r w x r - x r - x 85iLinux联盟
    第9位表示文件类型,可以为p、d、l、s、c、b和-: 85iLinux联盟
        p表示命名管道文件 85iLinux联盟
        d表示目录文件 85iLinux联盟
        l表示符号连接文件 85iLinux联盟
        -表示普通文件 85iLinux联盟
        s表示socket文件 85iLinux联盟
        c表示字符设备文件 85iLinux联盟
        b表示块设备文件 85iLinux联盟
    第8-6位、5-3位、2-0位分别表示文件所有者的权限,同组用户的权限,其

    他用户的权限,其形式为rwx: 85iLinux联盟
        r表示可读,可以读出文件的内容 85iLinux联盟
        w表示可写,可以修改文件的内容 85iLinux联盟
        x表示可执行,可运行这个程序 85iLinux联盟
        没有权限的位置用-表示 85iLinux联盟
    例子: 85iLinux联盟
        ls -l myfile显示为: 85iLinux联盟
        -rwxr-x---   1 foo   staff  7734 Apr 05 17:07 myfile 85iLinux联盟
    表示文件myfile是普通文件,文件的所有者是foo用户,而foo用户属于staff 85iLinux联盟
    组,文件只有1个硬连接,长度是7734个字节,最后修改时间4月5日17:07。

    所有者foo对文件有读写执行权限,staff组的成员对文件有读和执行权限,其他的用户对这个文件没有权限。 如果一个文件被设置了SUID或SGID位,会分别表现在所有者或同组用户的权限的可执行位上。例如: 85iLinux联盟
        1、-rwsr-xr-x 表示SUID和所有者权限中可执行位被设置 85iLinux联盟
        2、-rwSr--r-- 表示SUID被设置,但所有者权限中可执行位没有被设置

        3、-rwxr-sr-x 表示SGID和同组用户权限中可执行位被设置 85iLinux联盟
        4、-rw-r-Sr-- 表示SGID被设置,但同组用户权限中可执行位没有被社

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

    1,表示有相应的权限: 85iLinux联盟
    11 10 9 8 7 6 5 4 3 2 1 0 85iLinux联盟
     S  G T r w x r w x r w x 85iLinux联盟
    第11位为SUID位,第10位为SGID位,第9位为sticky位,第8-0位对应于上面

    的三组rwx位。 85iLinux联盟
                            11 10 9 8 7 6 5 4 3 2 1 0 85iLinux联盟
    上面的-rwsr-xr-x的值为: 1  0 0 1 1 1 1 0 1 1 0 1 85iLinux联盟
          -rw-r-Sr--的值为: 0  1 0 1 1 0 1 0 0 1 0 0 

    给文件加SUID和SUID的命令如下: 85iLinux联盟
    chmod u+s filename   设置SUID位 85iLinux联盟
    chmod u-s filename   去掉SUID设置 85iLinux联盟
    chmod g+s filename   设置SGID位 85iLinux联盟
    chmod g-s filename   去掉SGID设置 85iLinux联盟
    另外一种方法是chmod命令用八进制表示方法的设置。如果明白了前面的12位85iLinux联盟
权限表示法也很简单。

二、SUID和SGID的详细解析

    由于SUID和SGID是在执行程序(程序的可执行位被设置)时起作用,而可执行位只对普通文件和目录文件有意义,所以设置其他种类文件的SUID和SGID位是没有多大意义的。 85iLinux联盟
    首先讲普通文件的SUID和SGID的作用。例子: 85iLinux联盟
    如果普通文件myfile是属于foo用户的,是可执行的,现在没设SUID位,ls命令显示如下: 85iLinux联盟
    -rwxr-xr-x   1 foo   staff  7734 Apr 05 17:07 myfile 85iLinux联盟
    任何用户都可以执行这个程序。UNIX的内核是根据什么来确定一个进程对资源的访问权限的呢?是这个进程的运行用户的(有效)ID,包括user id和group id。用户可以用id命令来查到自己的或其他用户的user id和group id。 85iLinux联盟
    除了一般的user id 和group id外,还有两个称之为effective 的id,就是有效id,上面的四个id表示为:uid,gid,euid,egid。内核主要是根据euid和egid来确定进程对资源的访问权限。 85iLinux联盟
    一个进程如果没有SUID或SGID位,则euid=uid egid=gid,分别是运行这个程序的用户的uid和gid。例如kevin用户的uid和gid分别为204和202,foo用户的uid 和gid为200,201,kevin运行myfile程序形成的进程的euid=uid=204,egid=gid= 202,内核根据这些值来判断进程对资源访问的限制,其实就是kevin用户对资源访问的权限,和foo没关系。 85iLinux联盟
    如果一个程序设置了SUID,则euid和egid变成被运行的程序的所有者的uid和gid,例如kevin用户运行myfile,euid=200,egid=201,uid=204,gid=202,则这个进程具有它的属主foo的资源访问权限。 85iLinux联盟
    SUID的作用就是这样:让本来没有相应权限的用户运行这个程序时,可以访问他没有权限访问的资源。passwd就是一个很鲜明的例子。 85iLinux联盟
    SUID的优先级比SGID高,当一个可执行程序设置了SUID,则SGID会自动变成相应的egid。 85iLinux联盟
    下面讨论一个例子: 85iLinux联盟
    Linux系统有一个/dev/kmem的设备文件,是一个字符设备文件,里面存储了核心程序要访问的数据,包括用户的口令。所以这个文件不能给一般的用户读写,权限设为:cr--r-----   1 root     system     2,  1 May 25 1998  kmem 85iLinux联盟
但ps等程序要读这个文件,而ps的权限设置如下: 85iLinux联盟
-r-xr-sr-x   1 bin      system     59346 Apr 05 1998  ps 85iLinux联盟
这是一个设置了SGID的程序,而ps的用户是bin,不是root,所以不能设置SUID来访问kmem,但大家注意了,bin和root都属于 system组,而且ps设置了SGID,一般用户执行ps,就会获得system组用户的权限,而文件kmem的同组用户的权限是可读,所以一般用户执行ps就没问题了。但有些人说,为什么不把ps程序设置为root用户的程序,然后设置SUID位,不也行吗?这的确可以解决问题,但实际中为什么不这样做呢?因为SGID的风险比SUID小得多,所以出于系统安全的考虑,应该尽量用SGID代替SUID的程序,如果可能的话。 85iLinux联盟
    下面来说明一下SGID对目录的影响。SUID对目录没有影响。 85iLinux联盟
    如果一个目录设置了SGID位,那么如果任何一个用户对这个目录有写权限的话,他在这个目录所建立的文件的组都会自动转为这个目录的属主所在的组,而文件所有者不变,还是属于建立这个文件的用户。85iLinux联盟

收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站讨论
阅读(1608) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~