Linux SetUID(SUID)详细说明
Linux当中除了 rwx 权限,还会用到 s 权限
[root@localhost ~]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 22984 Jan 7 2007 /usr/bin/passwd
可以看到,原本表示文件所有者权限中的 x 权限位,却出现了 s 权限,此种权限通常称为 SetUID,简称 SUID 特殊权限。
SUID 特殊权限仅适用于可执行文件,所具有的功能是,只要用户对设有 SUID 的文件有执行权限,那么当用户执行此文件时,会以文件所有者的身份去执行此文件,一旦文件执行结束,身份的切换也随之消失。
举一个例子,我们都知道,Linux 系统中所有用户的密码数据都记录在 /etc/shadow 这个文件中,通过 ll /etc/shadow 命令可以看到,此文件的权限是 0(---------),也就是说,普通用户对此文件没有任何操作权限。这就会产生一个问题,为什么普通用户可以使用 passwd 命令修改自己的密码呢?
本节开头已经显示了 passwd 命令的权限配置,可以看到,此命令拥有 SUID 特殊权限,而且其他人对此文件也有执行权限,这就意味着,任何一个用户都可以用文件所有者,也就是 root 的身份去执行 passwd 命令。
Linux 系统中,绝对多数命令的文件所有者默认都是 root。
换句话说,当普通用户使用 passwd 命令尝试更改自己的密码时,实际上是在以 root 的身份执行passwd命令,正因为 root 可以将密码写入 /etc/shadow 文件,所以普通用户也能做到。只不过,一旦命令执行完成,普通用户所具有的 root身份也随之消失。
如果我们手动将 /usr/bin/passwd 文件的 SUID 权限取消,会发生什么呢?观察如下命令的执行过程:
[root@localhost ~]# chmod u-s /usr/bin/passwd
#属主取消SetUID权限
[root@localhost ~]# ll /usr/bin/passwd
-rwxr-xr-x. 1 root root 30768 Feb 22 2012 /usr/bin/passwd
[root@localhost ~]# su - lamp
[lamp@localhost ~]$ passwd
Changing password for user lamp.
Changing password for user.
(current) UNIX password:
#看起来没有什么问题
New passwor:
Retype new password:
password:Authentication token manipulation error <--鉴定令牌操作错误
#最后密码没有生效
显然,虽然用户有执行 passwd 命令的权限,但无修改 /etc/shadow 文件的权限,因此最终密码修改失败。注意,实验完成后,一定要再把 /usr/bin/passwd 文件的 SetUID 权限加上。
那么,普通用户可以使用 cat 命令查看 /etc/shadow 文件吗?答案的否定的,因为 cat 不具有 SUID 权限,因此普通用户在执行 cat /etc/shadow 命令时,无法以 root 的身份,只能以普通用户的身份,因此无法成功读取。
我们可以使用下面这张图来描述上述过程:
由此,我们可以总结出,SUID 特殊权限具有如下特点:
- 只有可执行文件才能设定 SetUID 权限,对目录设定 SUID,是无效的。
- 用户要对该文件拥有 x(执行)权限。
- 用户在执行该文件时,会以文件所有者的身份执行。
- SetUID 权限只在文件执行过程中有效,一旦执行完毕,身份的切换也随之消失。
授予setuid有两种方法:
(1)使用chmod u+s进行授予
(2)使用数字方式授予,在linux里面默认权限是755,setuid权限位是数字4,这样就可以在缺省的权限前面加上4,即4755
如果要收回s权限,那么就使用chmod u-s 可执行程序。或者使用chmod 755,即不加上第一位4。
注意使用chmod u+s的时候,对象必须是可执行程序,比如一个命令,不能是一个目录。如果一个对象不是可执行程序设置为setuid是没有任何意义的。
轻易设置SetUID(SUID)权限会带来重大安全隐患
如果我们手动给默认无 SetUID 权限的系统命令赋予 SetUID 权限,会出现什么情况呢?比如说,我们尝试给 Vim 赋予 SetUID 权限:
[root@localhost ~]# chmod u+s /usr/bin/vim
[root@localhost ~]# ll /usr/bin/vim
-rwsr-xr-x. 1 root root 1847752 Apr 5 2012 /usr/bin/vim
此时你会发现,即便是普通用户使用 vim 命令,都会暂时获得 root 的身份和权限,例如,很多原本普通用户不能查看和修改的文件,竟然可以查看了,以 /etc/passwd 和 /etc/shadow 文件为例,普通用户也可以将自己的 UID 手动修改为 0,这意味着,此用户升级成为了超级用户。除此之外,普通用户还可以修改例如 /etc/inittab 和 /etc/fstab 这样重要的系统文件,可以轻易地使系统瘫痪。
其实,任何只有管理员可以执行的命令,如果被赋予了 SetUID 权限,那么后果都是灾难性的。普通用户可以随时重启服务器、随时关闭看得不顺眼的服务、随时添加其他普通用户的服务器,可以想象是什么样子。所以,SetUID 权限不能随便设置。
如何防止他人(例如黑客)对 SetUID 权限的恶意篡改呢?这里,给大家提供以下几点建议:
- 关键目录要严格控制写权限,比如 "/"、"/usr" 等。
- 用户的密码设置要严格遵守密码规范。
- 对系统中默认应该有 SetUID 权限的文件制作一张列表,定时检査有没有列表之外的文件被设置了 SetUID 权限。
前面 2 点不再做过多解释,这里就最后一点,给大家提供一个脚本,仅供参考。
首先,在服务器第一次安装完成后,马上查找系统中所有拥有 SetUID 和 SetGID 权限的文件,把它们记录下来,作为扫描的参考模板。如果某次扫描的结果和本次保存下来的模板不一致,就说明有文件被修改了 SetUID 和 SetGID 权限。命令如下:
[root@localhost ~]# find / -perm -4000 -o -perm -2000 > /root/suid.list
#-perm安装权限査找。-4000对应的是SetUID权限,-2000对应的是SetGID权限
#-o是逻辑或"or"的意思。并把命令搜索的结果放在/root/suid.list文件中
接下来,只要定时扫描系统,然后和模板文件比对就可以了。脚本如下:
[root@localhost ~]#vi suidcheck.sh
#!/bin/bash
find / -perm -4000 -o -perm -2000 > /tmp/setuid.check
#搜索系统中所有拥有SetUID和SetGID权限的文件,并保存到临时目录中
for i in $(cat /tmp/setuid.check)
#循环,每次循环都取出临时文件中的文件名
do
grep $i /root/suid.list > /dev/null
#比对这个文件名是否在模板文件中
if ["$?"!="o"]
#检测测上一条命令的返回值,如果不为0,则证明上一条命令报错
then
echo "$i isn't in listfile! " >>/root/suid_log_$(date +%F)
#如果文件名不在模板文件中,则输出错误信息,并把报错写入日志中
fi
done
rm -rf/tmp/setuid.check
#删除临时文件
[root@localhost ~]# chmod u+s /bin/vi
#手工给vi加入SetUID权限
[root@localhost ~]# ./suidcheck.sh
#执行检测脚本
[root@localhost ~]# cat suid_log_2013-01-20
/bin/vi isn't in listfile!
#报错了,vi不在模板文件中。代表vi被修改了SetUID权限
这个脚本成功的关键在于模板文件是否正常。所以一定要安装完系统就马上建立模板文件,并保证模板文件的安全。
注意,除非特殊情况,否则不要手工修改 SetUID 和 SetGID 权限,这样做非常不安全。
目录 返回
首页