0x00 前置-用户ID

Linux系统使用用户ID(英语:user identifier,一般缩写为User ID或UID)来辨别用户。UID在类UNIX系统中是一个无符号整型数值,亦是UNIX文件系统与进程的必要组成部分。

这里主要介绍三种UID(下面这段摘自Wiki)

有效用户ID

有效用户ID(Effective UID,即EUID)与有效用户组ID(Effective Group ID,即EGID)在创建与访问文件的时候发挥作用;具体来说,创建文件时,系统内核将根据创建文件的进程的EUID与EGID设定文件的所有者/组属性,而在访问文件时,内核亦根据访问进程的EUID与EGID决定其能否访问文件。

真实用户ID

真实用户ID(Real UID,即RUID)与真实用户组ID(Real GID,即RGID)用于辨识进程的真正所有者,且会影响到进程发送信号的权限。没有超级用户权限的进程仅在其RUID与目标进程的RUID相匹配时才能向目标进程发送信号,例如在父子进程间,子进程从父进程处继承了认证信息,使得父子进程间可以互相发送信号。

暂存用户ID

暂存用户ID(Saved UID,即SUID)于以提升权限运行的进程暂时需要做一些不需特权的操作时使用,这种情况下进程会暂时将自己的有效用户ID从特权用户(常为root)对应的UID变为某个非特权用户对应的UID,而后将原有的特权用户UID复制为SUID暂存;之后当进程完成不需特权的操作后,进程使用SUID的值重置EUID以重新获得特权。在这里需要说明的是,无特权进程的EUID值只能设为与RUID、SUID与EUID(也即不改变)之一相同的值。


0x10 Linux用户管理

  • 超级用户:
    root 具有操作系统的一切权限 UID 值为 0
  • 普通用户:
    普通用户具有操作系统有限的权限,
    UID值 500 – 6000

  • 伪用户:
    是为了方便系统管理,
    满足相应的系统进程文件属主的要求,
    伪用户不能登录系统,UID值 1 – 499


0x20 用户的权限管理 chmod

当我们使用 ll 或者 ls 命令查看文件时,能看到类似于下面这样的信息在每行的最前面

drwxrwxrwx

其中
第一个字母:代表文件类型
第2~4字符:表示当前用户的权限
第5~7字符:表示当前用户组权限
第8~10字符:表示其他用户的权限

d:目录
r:读权限
w:写权限
x:可执行权限

chmod命令

当我们需要改变权限时,我们需要用到chmod命令
下面是一些参数的含义

a:所有权限/所有用户
u:用户
g:用户组
o:其他用户

+:加上权限
-:减去权限
=:等于权限

eg:给文件file.txt对于所有用户加上可执行权限
chmod a+x file.txt

我们也可以用八进制的数据表示权限

0:无权限
1:x
2:w
3:xw
4:r
5:rx
6:rw
7:rwx

eg: 给文件一个755权限
chmod 755 file.txt

文件/目录的所属用户和所属用户组
修改目录下所有文件、所有子文件、文件夹的权限
chmod -R 755 folder


0x30 特殊的s权限

linux中除了r w x 三个权限外(分别代表r 读,w 写,x 执行),其实还有几个特殊的权限
这里主要讲s权限

当s权限在文件所有者 x 权限上时,例如:-rwsr-xr-x,此时称为Set UID,简称为SUID的特殊权限,即当执行该文件时将具有该文件所有者的权限。这里要注意,此处的SUID与前面讲用户ID时的SUID不同,这里的SUID是文件中的权限,而前面讲的SUID是进程中的ID。

例如:

这里可以看到passwd的拥有者是root,但实际上你使用普通用户也可以使用passwd来修改你的密码,这就是因为s权限可以让你在使用程序时短暂的具有拥有者的权限。
在实际操作中
1、因为/usr/bin/passwd的权限对任何的用户都是可以执行的,所以系统中每个用户都可以执行此命令。
2、/usr/bin/passwd这个文件的权限是属于root的。
3、当某个用户执行/usr/bin/passwd命令的时候,就拥有了root的权限了。
4、于是某个用户就可以借助root用户的权力,来修改了/etc/shadow文件了。
5、密码修改成功。

SUID仅可用在“二进制文件(binary file)”,SUID因为是程序在执行过程中拥有文件拥有者的权限,因此,它仅可用于二进制文件,不能用在批处理文件(shell脚本)上。这是因为shell脚本只是将很多二进制执行文件调进来执行而已。

设置s权限可以直接chmod a+s filename或者在正常权限前面加一个4,比如chmod 4755 filename

SUID虽然很好了解决了一些问题,但是同时也会带来一些安全隐患。
因为设置了s位的程序如果被攻击(通过缓冲区溢出等方面),那么hacker就可以拿到root权限。因此在安全方面特别要注意那些设置了SUID的程序。在shellcode那篇文章中,我会准备一份演示代码。

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


0x40 setreuid

在C语言里面,我们可以用setreuid函数来设置ruid和euid。
其原型是:int setreuid(uid_t ruid, uid_t euid);
头文件:#include <unistd.h>

setresuid()满足一下任一条件即可被执行:

  • 当前进程的euid是root
  • 三个参数,每一个等于原来某个id中的一个


至此,本文简单的描述了Linux用户权限,需要更多的实例请移步隔壁的文章。//隔壁文章转送门