关于setuid命令

一 预备知识

1 ubuntu下如何查看所有用户信息

 cat /etc/passwd
 或者
 less /etc/passwd
 more /etc/passwd

会出现下列的信息
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
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
leeleell:x:1000:1000:ubuntu13-64,,,:/home/leeleell:/bin/bash

比如 root bin games man  leeleell 这些都是linux下的用户了

2 切换用户

由于笔者的ubuntu是直接修改成以root方式登录的,直接打开shell就是
root用户,但是在这个实验中又的确需要非root用户,原来建立了一个
leeleell用户,所以这里使用

su leeleell 或者 su root 这个命令切换即可

3 查看实验的命令的位置 以及权限

我们这个实验,以vi来做实验,所以需要使用 which vi 这个命令来查看
vi这个命令的具体位置,
然后再使用 ll vi 看这个命令具体的权限,同时目标文件也是这样

4 setuid命令的获取

 apt-get install super
 即可下载获取 setuid 这个命令了

Use: setuid uid|username command [args...]
Purpose: changes uid, then executes command.
Unlike su(1):
   * won't ever ask for password
   * args are given to execvp(), not to a shell

比su赶脚用的更简单了,特别是第二项,比较有用

用法
setuid root /usr/bin/vim.tiny  /etc/shadow

但是在非root用户下使用该命令报错
setuid: setuid(user=root) failed: Operation not permitted
这点不如 sudo,连个输入密码的机会都不给


二 实验目的

 通过给vi 命令设置 setuid的权限,让vi命令在非root的用户shell下,打开
 本来无法打开的 /etc/shadow文件。

leeleell@ubuntu:/usr/bin$ ll /etc/passwd
-rw-r--r-- 1 root root 1776 Jan 21 16:03 /etc/passwd
leeleell@ubuntu:/usr/bin$ ll /usr/bin/vim.tiny
-rwxr-xr-x 1 root root 781384 Apr  2  2013 /usr/bin/vim.tiny*

 这两个文件的权限如上


三 命令行实验
  其实本身linux 下权限是有四个数字的,我们常用的 chmod 777 xxx
  其实默认是 chmod 0777 xxx

  而第一位的 0 也有 4 2 1 三种组合,分别代表

  suid的二进制串为:100,换算十进制为:4
  guid的二进制串为:010,换算十进制:2
  stick bit 二进制串:001,换算十进制:1
  更多详见
  http://sunzeduo.blog.51cto.com/2758509/1316327
  这个链接

  所以首先先要修改 vi为 4755权限,这个需要在root下面执行
  root@ubuntu:/usr/bin# chmod 4755  /usr/bin//vim.tiny
  root@ubuntu:/usr/bin# ll /usr/bin//vim.tiny
  -rwsr-xr-x 1 root root 781384 Apr  2  2013 /usr/bin//vim.tiny*

  这个时候 vi已经从原来的 rwx 修改成 rws了
  再在leeleell 非root的shell中执行 刚才的命令


  leeleell@ubuntu:/usr/bin$ vi /etc/shadow
  发现已经能够打开



四 程序实现

  本身unix 系统给我们留有 setuid这个接口,我们就编一个最简单的程序来尝试修改自身的uid吧

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>

void p_state()
{
   printf("--current states--\n");
   printf("real uid = %d\n",getuid());
   printf("effective uid = %d\n",geteuid());
   printf("-------------------\n");
}

void test_read_file(char *name)
{
   FILE *fp = fopen(name,"r");

   if(fp)
   {
       printf("read ok\n");
       fclose(fp);
       return;
   }

   printf("read failed\n");
}



void test_setuid()
{
   int i = 0;
   int uids[3] = {0,1000,0};

   for(i = 0;i < sizeof(uids) /sizeof(int);i ++)
   {
       printf("--------TEST %d begin-----------\n",i);
       p_state();

       printf("setuid %d\n",uids[i]);
       if(setuid(uids[i]) == -1)
       {
           printf("setuid error\n");
       }
       else
       {
           printf("setuid ok\n");
       }

       test_read_file("root_read_only.txt");
       printf("--------TEST %d end-----------\n\n",i);
   }


}

int main(void) {

   test_setuid();
   return EXIT_SUCCESS;
}


其中 setuid 中的参数来源

root:x:0:0:root:/root:/bin/bash
leeleell:x:1000:1000:ubuntu13-64,,,:/home/leeleell:/bin/bash

root 的uid是 0 groupid 也是 0
leeleell 的uid 是 1000 groupid 也是 1000

root_read_only.txt的权限如下
-rw------- 1 root root     0 Feb 23 12:40 root_read_only.txt

在root下的运行该程序,结果如下

--------TEST 0 begin-----------
--current states--
real uid = 0
effective uid = 0
-------------------
setuid 0
setuid ok
read ok
--------TEST 0 end-----------

--------TEST 1 begin-----------
--current states--
real uid = 0
effective uid = 0
-------------------
setuid 1000
setuid ok
read failed
--------TEST 1 end-----------

--------TEST 2 begin-----------
--current states--
real uid = 1000
effective uid = 1000
-------------------
setuid 0
setuid error
read failed
--------TEST 2 end-----------

发现从root用户修改成 leeleell用户 setuid执行没有问题,但是同一个程序,将leeleell用户再修改回来
root用户 setuid 执行出错。

五 setuid的缺点:

1 、为系统的安全性带来了隐患,如果Root用户为指定的程序文件配置过大的SetUID权限,那么就会为***或者非法用户打开了侵入系统的大门。
2、如果vi编辑器被设置了u+s,就更危险了,普通用户可以使用vi编辑/etc/shadow文件,因为具备root身份,可以进行任意读写操作(比如可以把任何一个用户密码位清空,则用户登录不需要输入密码)。但是使用more、cat等命令仍然无法查看文件/etc/shadow的内容,只有被授予了SetUID的vi可以查看和修改。同样,vi如果具有了SetUID权限,普通用户可以vi编辑/etc/passwd文件把自己的UID改为0 ,则他的权限就和root一样;可以vi编辑/etc/inittab文件把缺省运行级别改成6 ,则Linux会开机后不停的重启…,更可恶的是可以vi编辑/etc/inittab文件把缺省运行级别改成1,这时不太懂得人会以为机子坏了。
如果kill被授予setid权限,当普通用户执行kill时,因为kill被授予了SetUID权限,在执行的一瞬间具有了root权限,只要用户不爽想关闭任何服务都可以!