权限与用户

Linux 是一个多用户操作系统。为了保证数据安全,系统通过权限系统来精细控制哪些用户可以读取、写入或执行特定的文件和目录。理解权限标志与用户切换,是进行安全审计和防范提权风险的关键支柱。

文件权限位的解读

当我们在终端运行带有详细信息参数的列表命令(如 ls -lls -lh)时,输出中会呈现关于文件的权限详情:

crow@opsbox:~$ ls -lh
-rwxr-x--- 1 crow crow 120 Jul 15 22:00 todo.txt

每一行最左侧都会展示一列由 10 个字符组成的权限字符串,例如 -rwxr-x---。这 10 个字符的含义非常固定,我们可以通过下面的示意图进行拆解:

权限位 -rwxr-x--- 拆解与八进制换算示意图

  1. 类型标志位(第 1 位)
    • -:代表常规普通文件。
    • d:代表目录。
    • l:代表符号链接。
  2. 权限主体位(第 2 至 10 位,共 9 位): 这 9 位被均匀划分为三组,每组 3 个字符,按顺序分别适用于不同的操作者主体:
    • 属主权限(第 2-4 位):代表文件创建者或当前拥有者的权限。
    • 属组权限(第 5-7 位):代表与该文件关联的用户组内成员的权限。
    • 其他用户权限(第 8-10 位):代表系统内所有其他不符合属主或属组成员身份的普通用户的权限。

而在每组的 3 位中,其所使用的字母代表了具体允许的操作类型:

  • r(值 = 4):读取权限。对于文件,允许查看内容;对于目录,允许列出目录内的项。
  • w(值 = 2):写入权限。对于文件,允许修改其内容;对于目录,允许在其中创建、删除或重命名文件与子目录。
  • x(值 = 1):执行权限。对于可执行文件,允许将其调入内存运行;对于目录,则是进入和遍历(cd 进入)该目录所必不可少的基本权限。
  • -:代表该主体没有对应的读取、写入或执行权限。

我们可以把“文件”比作纸质合同,而“目录”则是装合同的抽屉,来区分这三者的实际效果:

  • 对文件(纸质合同)的权限
    • r(读):你可以翻阅合同内容。
    • w(写):你可以修改合同文本。
    • x(执行):你可以按照合同条款去执行任务。
  • 对目录(抽屉)的权限
    • r(读):你可以拉开抽屉,看看里面有哪些档案袋。
    • w(写):你可以在抽屉里放入新的档案袋,或者把里面的某个档案袋扔掉、重命名(注意:即便你无权阅读某份合同,只要你有抽屉的写权限,你就可以直接撕毁并扔掉它!)。
    • x(执行):你可以把手伸进抽屉里去拿取特定的档案袋。如果没有 x 权限,哪怕你通过 r 权限看到了抽屉里的档案名称,也摸不到它,更无法进入。

符号权限与八进制数字权限的换算

为了操作简便,Linux 权限系统采用 3 位八进制数字来代替 9 位字母。 换算的方法非常简单:只需将每一组权限位所代表的数值(r=4, w=2, x=1)进行求和累加。

二进制与八进制转换机制

我们可以通过以下对照结构来观察转换的过程:

二进制表示法:                4 2 1  |  4 2 1  |  4 2 1
----------------------------------------------------------
二进制状态位:                1 1 1  |  1 0 1  |  1 0 0
----------------------------------------------------------
对应的八进制值:                7    |    5    |    4
----------------------------------------------------------
符号权限表示:                r w x  |  r - x  |  r - -

根据该转换:

  • 第一组(属主):rwx → 4 + 2 + 1 = 7
  • 第二组(属组):r-x → 4 + 0 + 1 = 5
  • 第三组(其他):--- → 0 + 0 + 0 = 0
  • 对应的数字权限即为:750。这意味着文件所有者拥有全部读、写、执行权限;同组的成员拥有读取与执行权限;而其他任何人均无法访问该文件。

常用权限表

字母权限位八进制数字实际访问权限
rwxr-xr-x755所有者完全控制,组内成员与其他用户仅能读取与执行
rw-r--r--644所有者有读写权,组内成员与其他用户仅能读取文件
rwx------700仅所有者拥有全部访问权限,其他任何人皆无权限
rw-r-----640所有者有读写权,同组成员仅可读,其他用户无权

权限与所有者的修改

修改权限:chmod

chmod 命令用于更改文件或目录的访问权限。它支持两种主流的操作语法:

  • 数字语法(最直接推荐):直接使用三位八进制数字。
    crow@opsbox:~$ chmod 750 system_overview.txt
    
  • 符号语法:使用代表主体的字母(u = 属主, g = 组, o = 其他用户, a = 所有用户)配合操作符(+ = 增加权限, - = 去除权限)进行调整。
    • 给所有用户增加读取权限:
      crow@opsbox:~$ chmod a+r shell
      
    • 从同组用户中减去执行权限:
      crow@opsbox:~$ chmod g-x shell
      

更改文件属主与属组:chown

chown 命令允许系统管理员更改文件所有者以及关联的群组。其命令语法结构为:

chown user:group filename

注意

在 Linux 中,修改文件的属主和属组属于特权操作。非特权用户无法随意把自己的文件赠予他人。因此,通常需要配合 sudo 命令以 root 权限执行:

crow@opsbox:~$ sudo chown root:root shell

用户身份切换与登录环境变量:su

在 Linux 中,你可以使用 su 命令在不退出当前连接的情况下快速切换到其他用户的身份。要切换成功,你通常需要知道目标用户的登录密码。

susu - 的关键区别与机制

  • 不带短横线的切换 su username:仅切换身份(UID 变更),但不加载目标用户的个性化环境变量,并且你的当前工作目录(PWD)和原来的 PATH(查找命令的路径)保持不变。
    crow@opsbox:~$ pwd
    /home/crow
    crow@opsbox:~$ su user2
    Password: 
    user2@opsbox:/home/crow$ pwd
    /home/crow
    
  • 带短横线的切换 su - username(推荐,等同于 su -l:以登录 Shell 的形式切换用户。目标 Shell 会读取相应的登录初始化文件(例如 Bash 常见的 .bash_profile.profile),加载目标用户专属的 PATH,并将当前工作目录切换到目标用户的主目录(/home/user2)。
    crow@opsbox:~$ pwd
    /home/crow
    crow@opsbox:~$ su - user2
    Password: 
    user2@opsbox:~$ pwd
    /home/user2
    

身份数据存储结构

用户与密码的安全数据存放于以下两个特殊文件中,它们位于 /etc 配置目录下:

  • /etc/passwd:系统的用户属性表。我们分析其典型的一行配置:
    crow:x:1000:1000:crow_user:/home/crow:/bin/bash
    
    它包含了用户名、密码占位符(x 代表实际哈希存储于 shadow 中)、用户标识符、组标识符、用户主目录以及默认使用的 Shell 解释器路径。此文件对系统中的所有普通用户均是可读的。
  • /etc/shadow:存储用户经 SHA-512 等单向哈希算法加密后的密码密文。基于系统安全性,此文件仅有管理员 root 或拥有特定权限的账户可以读取。

下面,我们通过一个权限判读测验来巩固你对权限位的认知。

判读文件权限位

练习

已知某个文件的权限位为 -rwxr-x---,请计算并提交其对应的 3 位八进制数字权限值(例如 755)。

提交答案

题解 Hint

练习二:通过提取凭据切换用户身份

下面,我们将通过真实的实验场景演示用户权限受阻,以及如何通过信息搜集定位凭据并完成用户切换。

我们的任务目标是读取当前服务器中 deploy 用户特有目录下的一个保密令牌。

我们仍以普通用户 crow 的身份,在之前的网页终端中继续操作。

  1. 我们尝试读取该文件:
    crow@opsbox:~$ cat /home/deploy/secret/deploy.token
    cat: /home/deploy/secret/deploy.token: Permission denied
    
    终端会返回权限不足报错。
  2. 我们检查其详情,确认其权限属性:
    crow@opsbox:~$ ls -l /home/deploy/secret/deploy.token
    -rw-r----- 1 deploy deploy 32 Jul  1 12:00 /home/deploy/secret/deploy.token
    
    其数字权限对应为 640,所有者是 deploy,组也是 deploy。这说明,除了 deploy 用户本身和同组账号以外,包括 crow 在内的其他任何普通用户均被阻拦,无法读取该文件。
  3. 既然无法直接读取,我们尝试进行本地信息收集。在一些维护场景下,开发人员可能会将敏感密码以注释的形式硬编码进脚本中。我们尝试在运维目录 /srv/ops 下递归搜索包含 pw 关键字的项:
    crow@opsbox:~$ grep -R -n -i pw /srv/ops
    /srv/ops/deploy.sh:12:# deploy user default setup password: <刚发现的明文密码>
    
    我们发现运维人员将 deploy 用户的明文密码写死在了部署脚本的注释中。
  4. 获取该明文密码后,我们执行 su - deploy 切换到目标用户身份:
    crow@opsbox:~$ su - deploy
    Password: 
    deploy@opsbox:~$ whoami
    deploy
    
    终端提示你输入 Password:。输入刚刚找到的明文密码并回车。
  5. 此时我们已经具备了属主权限,直接读取该令牌文件:
    deploy@opsbox:~$ cat ~/secret/deploy.token
    tok_<...>
    
    屏幕上会成功打印出包含令牌内容的回显。找到并提交该令牌以完成挑战。

切到 deploy 读出受限令牌

Lab

opsbox 上 deploy 用户的私密目录里有一枚部署令牌,权限只允许 deploy 自己读,crow 读不到。但运维图省事,把 deploy 的密码写死在了一个世界可读的部署脚本注释里。

在网页终端(TARGET 终端(启动 Lab 后显示))里找出那个密码,su - deploy 切过去,读出 ~/secret/deploy.token 里的令牌并提交。

提交令牌原文(形如 tok_************)。

加载会话状态…

提交 coin

题解 Hint