普通用户可以修改 root 拥有的文件

普通用户可以修改 root 拥有的文件

如果该文件是 root 使用以下命令创建的纯文本文件:

echo 'foo' > ./file.txt

你的ls -l是:

-rw-r--r-- root root ./file.txt

但作为普通用户,我可以更改此设置维姆保存与:w!或与sed命令,当这种情况发生时用户和组拥有该文件的人更改为:

-rw-r--r-- user user ./file.txt

我注意到,当删除其他人的读取权限后,chmod o-r ./file.txt我无法再进行更改,但是当恢复时,chmod o+r ./file.txt我可以再次进行更改。

这里发生了什么?为什么“其他”读取权限使我能够更改 root 拥有的文件并更改用户和组所有权?

为什么会发生这种情况?

PS:我使用的是Debian SID。

答案1

发生这种情况是因为两件事:

  • vim(至少在这种情况下)并且sed,在进行现场编辑时,实际上会删除原始文件,然后创建一个同名的新文件。

  • 删除文件的能力取决于包含该文件的目录的权限,而不是文件本身的权限。

因此,这里发生的情况是您对该目录具有写权限,这意味着您可以更改目录的内容,包括删除和创建文件。因此,当您运行sed -i或保存时:w!,您将删除原始文件,然后创建一个新文件。这也是所有权发生变化的原因:这实际上是一个不同的文件。

您可以通过检查文件的索引节点编辑前和编辑后:

$ ls -ld foo/
drwxr-xr-x 2 terdon terdon 266240 Nov 16 13:43 foo/
$ cd foo
$ sudo sh -c 'echo foo > file'
$ ls -l 
total 4
-rw-r--r-- 1 root root 4 Nov 16 13:43 file

在这些命令之后,我的普通用户在具有写入权限的file目录中拥有 root 拥有的。foo/现在,让我们使用ls -i检查 inode,然后进行更改sed并再次检查:

$ ls -li file 
26610890 -rw-r--r-- 1 root root 4 Nov 16 13:43 file
$ sed -i 's/foo/bar/' file
$ ls -li file 
26610859 -rw-r--r-- 1 terdon terdon 4 Nov 16 15:40 file

您还可以vim通过运行看到做同样的事情

strace vim file 2> strace.out

然后编辑文件并保存为:w!.在您的 中strace.out,您将看到:

    unlink("file")                           = 0
    open("file", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
    write(4, "bar\n", 11)            = 11

因此,该文件首先被删除 ( unlink("file")),然后创建一个同名的新文件 ( open("file", O_WRONLY|O_CREAT|O_TRUNC, 0644)),并将我所做的修改写入其中 ( write(4, "bar\n", 11))。

正如您在上面看到的,inode 发生了变化:这是一个同名的新文件。所以你实际上并没有改变一个你没有写访问权限的文件,你改变了一个目录通过删除该目录中的文件,然后在该目录中创建一个与旧文件同名的新文件,您确实具有写入权限。

我在这里回答过类似的问题:https://askubuntu.com/a/815849/85695

答案2

vim无法修改该文件,但如果它对文件链接到的目录具有写访问权限,并且您拥有该目录或未t设置其权限中的位,则它可以删除该文件并将其替换为您拥有的新副本。

为了防止这种情况,root可以

  • 在文件上设置immutable( chattr +i) 或append-only( ) 标志(然后甚至无法删除它)chattr +aroot
  • 确保仅对root父目录具有写入权限(仅由用户拥有root和位; ,)wchown root:chmod u=rwx,go=rx
  • 拥有 的目录root,可能由其他人写入,但在权限中具有t(限制删除²)位 ( chmod o+t)(因此用户只能删除/重命名他们拥有的文件)。

/a/b/file¹ 请注意,对于名为if的文件user具有对 的写访问权限/a,则 then 也可以重命名/a/b/a/b.old并在其中重新创建自己的/a/b和。/a/b/file

² 你可能听说过粘滞位该位的术语,但当应用于常规可执行文件时(并且仅在非常旧的系统上),指示(用于指示)系统将可执行文件的文本保留在内存中。当应用于目录时,该位具有不同的不相关含义。

相关内容