洞察权限


Linux 启明道场.

本模块将带你认识 Linux 权限。它控制不同用户对文件的访问,是你接下来学习过程中最重要的内容之一。

在 Linux 中,文件具有不同的权限,也称文件模式。 你可以用 ls -l 查看文件或目录的权限。 先创建一些文件,看看它们的权限:

hacker@dojo:~$ mkdir pwn_directory
hacker@dojo:~$ touch college_file
hacker@dojo:~$ ls -l
total 4
-rw-r--r-- 1 hacker hacker    0 May 22 13:42 college_file
drwxr-xr-x 2 hacker hacker 4096 May 22 13:42 pwn_directory
hacker@dojo:~$

这里的信息不少,本模块将介绍其中的许多内容! 现在,先从整体上看看上面的输出:

文件类型

每行的第一个字符表示文件类型。 对于 pwn_directory,d 表示它是目录;对于 college_file,- 表示它是普通文件。 此外还有其他类型,在后续的 pwn.college 学习中,你会遇到其中一些。

权限

接下来的九个字符表示文件或目录的实际访问权限,分成三组,每组三个字符:第一组表示拥有该文件的用户(称为“所有者”)的权限,第二组表示文件所属的组(称为“所属组”)的权限,第三组表示其他所有访问者(例如其他用户和其他组)的权限。 本模块稍后会详细介绍这些权限。

所有权信息

后面两列分别显示拥有该文件的用户(本例中为 hacker 用户),以及文件所属的组(本例中也为 hacker 组)。 你将在这里练习修改这些信息!


在本模块中,你将练习理解和操作权限。 开始吧!


视频字幕(七牛云直连)

视频字幕(七牛云直连)

视频字幕(七牛云直连)

视频字幕(七牛云直连)

首先,我们来了解文件所有权。 在 Linux 中,每个文件都归系统中的某个用户所有。 在日常使用中,这个用户通常就是你每天登录时使用的用户。

在共享系统中(例如计算机实验室),可能有许多人使用不同的用户账号,各自在自己的主目录中存放文件。 但即使在非共享系统中(例如你的个人电脑),Linux 仍然有许多用于执行不同任务的“服务”用户账号。

其中最重要的两个用户账号是:

  1. 你的用户账号!在 pwn.college 中,无论你注册的用户名是什么,使用的都是 hacker 用户。
  2. root。这是管理员账号,在大多数安全场景中,也是最终目标。如果你控制了 root 用户,几乎就可以说已经达成了入侵目标!

这有什么关系呢? 我们之所以能阻止你直接执行 cat /flag,是因为我们让 /flag 归 root 用户所有,并设置权限,使其他用户无法读取它(稍后你会学到如何操作);同时,我们让挑战程序以 root 用户身份运行(稍后也会介绍)。 因此,当你执行 cat /flag 时,会得到:

hacker@dojo:~$ ls -l /flag
-r-------- 1 root root 53 Jul  4 04:47 /flag
hacker@dojo:~$ cat /flag
cat: /flag: Permission denied
hacker@dojo:~$

这里可以看到,flag 文件归 root 用户(该行中第一个 root)和 root 组(该行中第二个 root)所有。 以 hacker 用户身份尝试读取时,访问被拒绝。 但如果我们是 root(攻击者梦寐以求的身份!),读取这个文件就毫无问题:

root@dojo:~# cat /flag
pwn.college{demo_flag}
root@dojo:~#

有意思的是,文件所有者是可以更改的! 使用 chown 命令即可,它的名称来自 change owner(更改所有者)中的 ch 和 own:

chown [username] [file]

通常,只有 root 用户才能调用 chown。 让我们再次假设自己是 root(这种感觉总是令人兴奋!),看看 chown 的典型用法:

root@dojo:~# mkdir pwn_directory
root@dojo:~# touch college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root root    0 May 22 13:42 college_file
drwxr-xr-x 2 root root 4096 May 22 13:42 pwn_directory
root@dojo:~# chown hacker college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 hacker root    0 May 22 13:42 college_file
drwxr-xr-x 2 root   root 4096 May 22 13:42 pwn_directory
root@dojo:~#

college_file 的所有者已经改为 hacker 用户,现在 hacker 可以对它执行之前 root 作为所有者能够执行的操作了! 如果这就是 /flag 文件,那就意味着 hacker 用户可以读取它!

在这一关中,我们将练习把 /flag 文件的所有者改为 hacker 用户,然后读取 flag。 仅在本关中,我们允许你以 hacker 用户身份随意使用 chown(再次提醒,通常这需要你是 root)。 善用这个能力,动手更改所有者吧!

共享体现协作,而 Linux 的设计本身就支持共享。 文件既有所属的用户,也有所属的组。 一个组可以包含多个用户,一个用户也可以属于多个组。

你可以使用 id 命令,查看自己属于哪些组:

hacker@dojo:~$ id
uid=1000(hacker) gid=1000(hacker) groups=1000(hacker)
hacker@dojo:~$

这里,hacker 用户只属于 hacker 组。 用户组最常见的用途,是控制对不同系统资源的访问。 例如,pwn.college 的“特权模式”会给你 root 权限,方便调试等操作。 它的实现方式是:在特权模式下启动时,将你加入一个额外的组:

hacker@dojo:~$ id
uid=1000(hacker) gid=1000(hacker) groups=1000(hacker),27(sudo)
hacker@dojo:~$

典型 Linux 桌面系统的主要用户通常属于很多组。 例如,下面是 zardus 的桌面系统:

zardus@yourcomputer:~$ id
uid=1000(zardus) gid=1000(zardus) groups=1000(zardus),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),106(netdev),114(bluetooth),117(lpadmin),120(scanner),995(docker)
zardus@yourcomputer:~$

这些组让 zardus 能够读取光盘和软盘(现在还有谁用软盘呢?)、管理系统、播放音乐、向显示器输出图像、使用蓝牙等。 这种访问控制通常通过文件系统中的组所有权来实现! 例如,可以通过特殊文件 /dev/fb0 输出图像:

zardus@yourcomputer:~$ ls -l /dev/fb0
crw-rw---- 1 root video 29, 0 Jun 30 23:42 /dev/fb0
zardus@yourcomputer:~$

这是一个特殊的设备文件(类型 c 表示“字符设备”)。与它交互会改变显示输出,而不是像普通文件那样改变磁盘中的存储内容! zardus 在自己机器上的用户账号能与这个文件交互,是因为文件的所属组为 video,而 zardus 是 video 组的成员。

不过,在 dojo 环境中,面对 /flag 文件,就没有这么幸运了! 看看下面的情况:

hacker@dojo:~$ id
uid=1000(hacker) gid=1000(hacker) groups=1000(hacker)
hacker@dojo:~$ ls -l /flag
-r--r----- 1 root root ... /flag
hacker@dojo:~$ cat /flag
cat: /flag: Permission denied
hacker@dojo:~$

这里,flag 文件归 root 用户和 root 组所有,而 hacker 用户既不是 root 用户,也不是 root 组的成员,所以无法访问该文件。 好在可以使用 chgrp 命令更改文件的所属组!它的名称来自 change group(更改组)中的 ch、gr 和 p。 除非你既是文件所有者,又是新组的成员,否则通常需要 root 权限。我们以 root 身份来看看:

root@dojo:~# mkdir pwn_directory
root@dojo:~# touch college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root root    0 May 22 13:42 college_file
drwxr-xr-x 2 root root 4096 May 22 13:42 pwn_directory
root@dojo:~# chgrp hacker college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root hacker    0 May 22 13:42 college_file
drwxr-xr-x 2 root root   4096 May 22 13:42 pwn_directory
root@dojo:~#

在这一关中,我们将 flag 设置为所属组可读,但它当前的所属组是 root。 好在我们也允许你以 hacker 用户身份调用 chgrp! 更改 flag 文件的所属组,然后读取 flag 吧!

在前面的关卡中,你可能注意到了:hacker 用户属于 hacker 组,而 zardus 属于 zardus 组。 Linux 中有一个惯例,即每个用户都有自己的同名组,但并非必须如此。 例如,许多计算机实验室会将所有用户加入同一个共享的 users 组。

关键在于,你之前使用 hacker 作为组名,但在这一关中,这样就行不通了。 我们仍然允许你使用 chgrp,但已经将你所在组的名称随机化。 你需要用 id 命令找出这个名称,再用 chgrp 完成挑战!

现在,我们已经熟悉文件所有权了。 接下来看看另一个方面:文件权限。 回顾一下之前的例子:

hacker@dojo:~$ mkdir pwn_directory
hacker@dojo:~$ touch college_file
hacker@dojo:~$ ls -l
total 4
-rw-r--r-- 1 hacker hacker    0 May 22 13:42 college_file
drwxr-xr-x 2 hacker hacker 4096 May 22 13:42 pwn_directory
hacker@dojo:~$

再提醒一下,第一个字符表示文件类型。 接下来的九个字符表示文件或目录的实际访问权限,分成三组:前三个字符表示所有者用户的权限(现在你已经理解了!),中间三个字符表示所属组的权限(这一点你也理解了!),最后三个字符表示其他所有访问者(例如其他用户和其他组)的权限。

每组三个字符分别表示不同类型的权限:

r - 用户/组/其他用户可以读取文件(或列出目录内容)
w - 用户/组/其他用户可以修改文件(或在目录中创建/删除文件)
x - 用户/组/其他用户可以将文件作为程序执行(或进入目录,例如使用 `cd`)
- - 无相应权限 

对于上面的 college_file,权限字符串 rw-r--r-- 的含义是:

  • r:文件所有者(hacker 用户)可以读取文件
  • w:文件所有者(hacker 用户)可以写入文件
  • -:文件所有者(hacker 用户)不能执行文件
  • r:文件所属组(hacker 组)的成员可以读取文件
  • -:文件所属组(hacker 组)的成员不能写入文件
  • -:文件所属组(hacker 组)的成员不能执行文件
  • r:所有其他用户可以读取文件
  • -:所有其他用户不能写入文件
  • -:所有其他用户不能执行文件

现在,看看 /flag 的默认权限:

hacker@dojo:~$ ls -l /flag
-r-------- 1 root root 53 Jul  4 04:47 /flag
hacker@dojo:~$

这里仅设置了一个权限位:所有者用户(本例中为 root)具有读取权限,读取对应 read 的首字母 r。 所属组(root 组)的成员和所有其他用户都无权访问该文件。

你可能会疑惑:如果所属组无权访问文件,前面的 chgrp 关卡是怎么实现的? 其实,在那些关卡中,我们设置了不同的权限:

hacker@dojo:~$ ls -l /flag
-r--r----- 1 root root 53 Jul  4 04:47 /flag
hacker@dojo:~$

所属组可以访问文件! 所以用 chgrp 更改文件的所属组后,你就能读取它了。

好了! 和所有权一样,文件权限也可以更改。 这需要使用 chmod 命令,它的名称来自 change mode(更改模式)中的 ch 和 mod。 chmod 的基本用法是:

chmod [OPTIONS] MODE FILE

指定 MODE 有两种方式:修改现有的权限模式,或者设置全新的模式来覆盖旧模式。

本关介绍第一种方式:修改现有模式。 chmod 允许你使用 WHO+/-WHAT 这种模式格式调整权限,其中 WHO 表示用户、组或其他用户,WHAT 表示读取、写入或执行。 例如,要为所有者用户添加读取权限,就指定模式 u+r。 写入权限用 write 的 w,执行权限用 execute 的 x;所属组用 group 的 g,其他用户用 other 的 o,所有类别则用 all 的 a,指定方法相同。 再看几个例子:

  • u+r:如上所述,为所有者用户添加读取权限
  • g+wx:为所属组添加写入和执行权限
  • o-w:移除其他用户的写入权限
  • a-rwx:移除所有者、所属组和其他用户的全部权限

例如:

root@dojo:~# mkdir pwn_directory
root@dojo:~# touch college_file
root@dojo:~# ls -l
total 4
-rw-r--r-- 1 root root    0 May 22 13:42 college_file
drwxr-xr-x 2 root root 4096 May 22 13:42 pwn_directory
root@dojo:~# chmod go-rwx *
root@dojo:~# ls -l
total 4
-rw------- 1 hacker root    0 May 22 13:42 college_file
drwx------ 2 root   root 4096 May 22 13:42 pwn_directory
root@dojo:~#

在这一关中,你必须更改 /flag 文件的权限,才能读取它! 通常,只有文件所有者才能更改文件权限,但本关中的 chmod 命令拥有额外的能力:即使你是 hacker 用户,也可以对任何文件执行 chmod。 这是非常强大的权限。 /flag 文件归 root 所有,你无法改变这一点,但你可以让它变得可读。 去完成挑战吧!

目前为止,你处理的大多是读取权限。 这是因为你一直在让 /flag 文件变得可读,以便读取它。 本关将探索执行权限。

调用一个程序时,例如 /challenge/run,只有当你对程序文件具有执行权限,Linux 才会真正执行它。 看看下面的例子:

hacker@dojo:~$ ls -l /challenge/run
-rwxr-xr-x 1 root root    0 May 22 13:42 /challenge/run
hacker@dojo:~$ /challenge/run
Successfully ran the challenge!
hacker@dojo:~$

这里,/challenge/run 能运行,是因为 hacker 用户对它具有执行权限。 由于文件归 root 用户和 root 组所有,因此必须在 other(其他用户)的权限中设置执行位。 如果移除这个权限,执行就会失败!

hacker@dojo:~$ chmod o-x /challenge/run
hacker@dojo:~$ ls -l /challenge/run
-rwxr-xr-- 1 root root    0 May 22 13:42 /challenge/run
hacker@dojo:~$ /challenge/run
bash: /challenge/run: Permission denied
hacker@dojo:~$

在这一关中,/challenge/run 程序会给你 flag,但你必须先让它变得可执行! 运用学过的 chmod,让 /challenge/run 告诉你 flag 吧!

觉得自己已经会用 chmod 了吗? 来练习一下吧!

本关会连续多次要求你按指定方式更改 /challenge/pwn 文件的权限。 如果权限设置错误,游戏就会重置,你可以重新尝试。 如果连续八次设置正确,挑战就会允许你使用 chmod 调整 /flag,让自己能够读取它 :-) 运行 /challenge/run,开始吧!

除了像上一关那样添加和移除权限,chmod 还可以直接设置整组权限,覆盖原来的权限。 只需使用 =,代替 - 或 +。 例如:

  • u=rw:将所有者用户的权限设置为读取和写入,并清除执行权限
  • o=x:将其他用户的权限设置为仅可执行,并清除读取和写入权限
  • a=rwx:为所有者、所属组和其他用户都设置读取、写入和执行权限!

如果你希望为所有者用户和所属组设置不同的权限呢? 例如,为所有者用户设置 rw,但为所属组只设置 r? 你可以在 chmod 中使用 , 串联多个模式来实现!

  • chmod u=rw,g=r /challenge/pwn:将所有者用户的权限设置为读取和写入,将所属组的权限设置为只读
  • chmod a=r,u=rw /challenge/pwn:将所有者用户的权限设置为读取和写入,将所属组和其他用户的权限设置为只读

此外,可以用 - 清空权限:

  • chmod u=rw,g=r,o=- /challenge/pwn:将所有者用户的权限设置为读取和写入,将所属组的权限设置为只读,并移除其他用户的全部权限

请注意,- 出现在 = 后面时,与直接出现在 u、g 或 o 后面的含义不同;后一种情况下,它会移除指定的权限位,而不是全部权限。

本关在上一关的基础上,要求进行更大幅度的权限更改。你需要使用 =,并通过 , 串联多个模式来完成。 祝你好运!

正如上一模块中所学,非 root 用户在许多情况下也需要提升权限,才能执行某些系统任务。 每当用户想执行只有 root 或 sudoers 中授权用户才能完成的任务时,系统管理员不可能都在旁边提供密码。 为此,“Set User ID”(设置用户 ID,简称 SUID)权限位允许用户以程序文件所有者的身份运行程序。

这正是你运行的挑战程序能够读取 flag 的机制。在 pwn.college 之外,su、sudo 等系统管理工具也是通过这一机制工作的。 设置了 SUID 的文件,其权限看起来是这样的:

hacker@dojo:~$ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 232416 Dec 1 11:45 /usr/bin/sudo
hacker@dojo:~$

执行位位置上的 s 表示该程序可执行,并且设置了 SUID。 这意味着,无论哪个用户运行程序(只要具有执行权限),程序都会以文件所有者的身份运行(本例中为 root 用户)。

作为文件所有者,你可以使用 chmod 设置文件的 SUID 位:

chmod u+s [program]

但要小心! 为归 root 所有的可执行文件设置 SUID 位,可能为攻击者提供提权到 root 的攻击途径。 你将在程序滥用模块中进一步学习相关内容。

现在,我们将允许你为 /challenge/getroot 程序添加 SUID 位,让它为你启动一个 root shell,然后你就能自己用 cat 读取 flag 了!


30天排行榜:

此排行榜反映本模块在道场上线后各挑战的解出情况。

排名 黑客 徽章 得分
暂无解题排行数据 —— 注册账号并完成挑战即可登上榜单!