Linux系统中每个普通用户都可以更改自己的密码,这是合理的设置。

问题是:用户的信息保存在文件/etc/passwd中,用户的密码保存在文件/etc/shadow中,也就是说用户更改自己密码时是修改了/etc/shadow文件中的加密密码,但是,

-rw-r--r-- 1 root root 1787 Oct 27  2009 /etc/passwd

-r-------- 1 root root 1187 Oct 27  2009 /etc/shadow

/etc/passwd文件每个用户都有读权限但是只有root有写权限,/etc/shadow文件只有超级用户root有读写权限,也就是说普通用户对这两个文件都没有写权限无法写入新密码,为什么普通用户可以更改密码呢?

PS:在linux中设置或更改用户密码,是先写入到/etc/passwd文件然后通过pwconv命令转换到/etc/shadow文件,执行pwunconv命令可观察到转换前效果,会观察到/etc/shadow文件神奇的消失掉了,而/etc/passwd文件中原来打x的地方变成了真正的加密密码。

其实,用户能更改密码真正的秘密不在于文件的权限,而在于更改密码的命令passwd 。

-rwsr-xr-x 1 root root 22960 Jul 17  2006 /usr/bin/passwd

passwd命令有一个特殊的权限标记s ,存在于文件所有者的权限位上。这是一类特殊的权限SetUID ,可以这样来理解它:当一个具有执行权限的文件设置SetUID权限后,用户执行这个文件时将以文件所有者的身份执行。passwd命令具有SetUID权限,所有者为root(Linux中的命令默认所有者都是root),也就是说当普通用户使用passwd更改自己密码的时候,那一瞬间突然灵魂附体了,实际在以passwd命令所有者root的身份在执行,root当然可以将密码写入/etc/shadow文件(不要忘记root这个家伙是superuser什么事都可以干),命令执行完成后该身份也随之消失。

可以试验用root身份修改passwd命令权限去掉SetUID :

chmod u-s /usr/bin/passwd

再尝试以普通用户身份登录后修改密码,就会发现提示:

passwd

Changing password for user samlee.

Changing password for samlee

(current) UNIX password:

passwd: Authentication token manipulation error

普通用户无法修改密码,所以只要能够想明白为什么普通用户可以更改密码就可以大概了解SetUID权限的作用。

接下来我们用两个SetUID的按理来进一步诠释下它的概念——

案例一:SetUID授权示例

为便于深入理解SetUID ,笔者以touch命令为例做一演示。

普通用户samlee用touch创建文件newfile01 :

touch newfile01

ls -l newfile01

-rw-rw-r-- 1 samlee samlee 0 05-21 01:20 newfile01

文件的创建者默认就是所有者,所以文件newfile01的所有者为samlee 。

管理员root给touch命令添加SetUID权限:

chmod u+s /bin/touch   # 或 chmod 4755 /bin/touch

ls -l /bin/touch

-rwsr-xr-x 1 root root 42284 Jul 13  2009 /bin/touch

再用普通用户samlee创建文件newfile02,看到如下结果:

touch newfile02

ls -l newfile02

-rw-rw-r-- 1 root samlee 0 05-21 01:48 newfile02

通过这个例子,我们可以再诠释下SetUID的定义,当一个可执行文件(命令touch)设置SetUID权限后,当普通用户samlee执行touch创建新文件时,实际上是以touch命令所有者root的身份在执行此操作,既然是以root身份执行,当然新建文件的所有者为root ,这就是SetUID的作用。

再看一下与SetUID类似的SetGID权限,看一个例子,给touch命令再授予SetGID :

chmod g+s /bin/touch   # 或 chmod 6755 /bin/touch

ls -l /bin/touch

-rwsr-sr-x 1 root root 42284 Jul 13  2009 /bin/touch

此时,再使用touch创建新文件newfile03,会看到如下现象:

touch newfile03

ls -l newfile03

-rw-rw-r-- 1 root root 0 05-21 01:48 newfile02

新建文件的所属组为touch命令的所属组,而不是执行touch命令的普通用户samlee的所属组,这就是SetGID的作用,与SetUID类似,用户在执行具有SetGID的命令时会调用命令所属组的身份。

案例二:危险的SetUID

对于SetUID的使用,可以做一个的比喻:一个绝密机关,要让一些人进来做一些事情,但是不能让他们看见机关内部的情况,于是授权一些特殊的“车辆”(没有窗户,车门紧闭,看不到外面,只有一个小洞允许乘坐的人伸出手臂做事),带着所乘坐的人开到要去的地方,允许它办完事情马上带他出来。这样是不是很安全?不一定。如果“车辆”没有经过精挑细选,可能有很多“门窗”,那可就危险了,这种类似的场景相信大家在一些警匪电影中已经见过多次了。

普通用户使用vi编辑/etc/shadow文件会提示“PermissionDenied”,这是合理的设置,但是如果赋予vi以SetUID权限:

chmod u+s /bin/vi

ls -l /bin/vi

-rwsr-xr-x 1 root root 594740 Jun 12  2009 /bin/vi

此时,普通用户使用vi即可以编辑/etc/shadow文件,因为具备root身份,可以进行任意读写操作(比如可以把任何一个用户密码位清空,则用户登录不需要输入密码)。但是使用more、cat等命令仍然无法查看文件/etc/shadow的内容,只有被授予了SetUID的vi可以查看和修改。同样,vi如果具有了SetUID权限,普通用户可以vi编辑/etc/passwd文件把自己的UID改为0 ,则他的权限就和root一样;可以vi编辑/etc/inittab文件把缺省运行级别改成6 ,则Linux会开机后不停的重启……

再来看一个令人不安的情况,用普通用户尝试关闭Apache服务: 
     ps -le | grephttpd

140 S     0  8916     1  0  76   0    -  3697 -      ?        00:00:00 httpd

kill 8916

-bash: kill: (8916) - Operation not permitted

可以看到,普通用户不可以关闭root启动的进程,但是如果做下面一个动作:

chmod 6555 /bin/kill

现在当普通用户执行kill时,因为kill被授予了SetUID权限,在执行的一瞬间具有了root权限,只要用户不爽想关闭任何服务都可以!

所以,SetUID权限不能随便设置,同时要防止黑客的恶意修改,怎样避免SetUID的不安全影响,有几点建议: 
    1. 关键目录应严格控制写权限。比如“/”、“/usr”等; 
    2. 用户的密码设置要足够强壮,8位以上,大小写字母、数字、符号的组合,如:Am@ri31n,且定期更换;
    3. 对系统中应该具有SetUID权限的文件作一列表,定时检查有没有这之外的文件被设置了SetUID权限。

可以对系统中应该具有SetUID权限的文件作一列表,定时检查有没有非列表中的命令被设置了SetUID权限。 
    在Linux安装部署完成后,执行下面命令生成SetUID列表文件:

mkdir /script   # 创建目录/script

find / -perm -4000 -o -perm -2000 >/script/setuid.list

命令find选项“-perm”为指定文件权限,SetUID权限位对应数字标识为4 ,SetGID权限位对应数字标识为2 ,后面写为“000”标识对所有者所属组其他人三类用户的权限不限制;“-o”表示or,就是文件具有SetUID或者具有SetGID都在搜索之列,生成的搜索结果存放在文件/script/setuid.list中。

在需要对系统做检查时,执行以下shell程序。也可以放在计划任务中定时检查。

/usr/bin/find / -perm -4000 -o -perm -2000 >/tmp/setuid.check

for file in `/bin/cat /tmp/setuid.check`

do

/bin/grep $file /script/setuid.list > /dev/null

if [ "$?" != "0" ]

then

echo "$file isn't in list! it's danger!!"

fi

done

/bin/rm /tmp/setuid.check
假设命令kill被设置了SetUID ,则会检测提示:

/bin/kill isn't in list! it's danger!!

另外,如果在一些数据存放的分区想禁用SetUID功能,还可以做如下设置,编辑配置文件/etc/fstab ,找到要设置的分区(如/home)所对应的设置行:

vi /etc/fstab

LABEL=/home       /home     ext3        defaults          1     2

在设置“defaults”后,添加“nosuid”选项,并重新挂载/home分区:

vi /etc/fstab

LABEL=/home       /home     ext3        defaults,nosuid              1     2

mount -o remount /home

设置后,分区/home上任何可执行文件即使被设置了SetUID权限也无法执行(读者可自行拷贝一个SetUID命令至/home目录下执行试验),在一些存放数据、用来备份等功能的分区上做此设置,可以保护系统安全。

友情提示:请您作完本文中的实验后,别忘把文件的权限恢复原状,以免带来不必要的麻烦。

至此相信读者已经对SetUID的作用有所了解,最后,还有一个大家要注意的问题,SetUID只针对具有可执行权限的文件有效,不具有x权限的文件被授予了SetUID会显示标记为S(一下子由小s变成姐姐了),仔细想一下,如果没有可执行权限的话设置SetUID无任何意义。

(转) Linux下Setuid命令!的更多相关文章

  1. Linux下Setuid命令! 转载

    Linux下Setuid命令! 转载  在Linux系统中每个普通用户都可以更改自己的密码,这是合理的设置. 问题是:用户的信息保存在文件/etc/passwd中,用户的密码保存在文件/etc/sha ...

  2. Linux下ps命令详解 Linux下ps命令的详细使用方法

    http://www.jb51.net/LINUXjishu/56578.html Linux下的ps命令比较常用 Linux下ps命令详解Linux上进程有5种状态:1. 运行(正在运行或在运行队列 ...

  3. 例解 Linux 下 Make 命令

    Linux 下 make 命令是系统管理员和程序员用的最频繁的命令之一.管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题.本文我们将用一些实例来讨论 make ...

  4. Linux下who命令之C语言实现

    Linux下who命令之C语言实现 Step1:前期准备 首先要有一个清楚的认识:linux中一切皆文件 实现who命令,who命令也是Linux中的一个文件,那我们怎么找到它呢?我们可以" ...

  5. linux下history命令显示历史指令记录的使用方法

    Linux系统当你在shell(控制台)中输入并执行命令时,shell会自动把你的命令记录到历史列表中,一般保存在用户目录下的.bash_history文件中.默认保存1000条,你也可以更改这个值 ...

  6. linux下svn命令使用大全

    最近经常使用svn进行代码管理,这些命令老是记不住,得经常上网查,终于找了一个linux下svn命令使用大全:1.将文件checkout到本地目录 svn checkout path(path是服务器 ...

  7. Linux下rz命令使用的实例详解

    Linux中rz命令和sz命令都可用于文件传输,而rz命令主要用于文件的上传,下面将通过几个实例来给大家详细介绍下Linux下rz命令的用法,一起来学习下吧. rz命令可以批量上传文件,当然也可上传单 ...

  8. Linux下rar命令详解

    Linux下rar命令详解 用法: rar <命令> -<选项1> ….-<选项N> < 操作文档> <文件…> <@文件列表…> ...

  9. linux下tar命令详解

     linux下tar命令详解    tar是Linux环境下最常用的备份工具之一.tar(tap archive)原意为操作磁带文件,但基于Linux的文件操作机制,同样也可适用于普通的磁盘文件.ta ...

随机推荐

  1. 推荐sinaapp谷歌搜索引擎,firefox自定义搜索引擎

    满园春色关不住,从此不用再FQ. 一直都在用谷歌,也一直都被和谐. 直到在迅影实习,知道了这个网站:http://goog.sinaapp.com/ 下面说说在firefox里面添加搜索引擎 首先打开 ...

  2. 何时使用padding和margin

    先看看这张图: 重点其实是background-image CSS边距属性定义元素周围的空间.通过使用单独的属性,可以对上.右.下.左的外边距进行设置.也可以使用简写的外边距属性同时改变所有的外边距. ...

  3. Java8中计算日期时间差

    一.简述 在Java8中,我们可以使用以下类来计算日期时间差异: 1.Period 2.Duration 3.ChronoUnit 二.Period类 主要是Period类方法getYears(),g ...

  4. [BZOJ4061][Cerc2012]Farm and factory

    bzoj 鉴于是权限题,放一下题面. Description 向Byteland的国王Bitolomew致敬!国王Bitolomew认为Byteland是一个独一无二的国家.它太小了,它所有的市民(包 ...

  5. spring事务中隔离级别和spring的事务传播机制

    Transaction 也就是所谓的事务了,通俗理解就是一件事情.从小,父母就教育我们,做事情要有始有终,不能半途而废. 事务也是这样,不能做一般就不做了,要么做完,要 么就不做.也就是说,事务必须是 ...

  6. PAT 1006 换个格式输出 C语言

    让我们用字母B来表示“百”.字母S表示“十”,用“12...n”来表示个位数字n(<10),换个格式来输出任一个不超过3位的正整数.例如234应该被输出为BBSSS1234,因为它有2个“百”. ...

  7. Python 函数 -getattr()

    getattr(object, name[, default]) getatt() 函数用于返回一个对象属性值.object 对象.name 字符串,对象属性.object 默认返回值,如果不提供该参 ...

  8. 解决EditPlus的默认编码方式有关问题(转)

    http://blog.csdn.net/hzhsan/article/details/7911660 最近在使用英文版的Editplus写代码的时候,发现中文字符在调试过程中都变成了乱码, 发现是E ...

  9. CentOS 添加常用 yum 源(转)

    CentOS 的官方源去掉了一些与版权有关的软件,因此想要安装这些软件或者手动下载安装,或者使用其他源. 下面我推荐常用的两个源, 这两个源基本可以满足一般服务器的使用需求. 首先, 添加源之前要确定 ...

  10. 常用 Git 命令使用教程

    下面整理一下自己在开发过程中经常使用到的 Git 命令.使用 GUI 工具的同学,也可以对照起来看看. Git 配置 1. 在安装完成 Git 后,开始正式使用前,是需要有一些全局设置的,如用户名.邮 ...