用户如何在未经许可的情况下执行文件?

The*_*lis 11 command-line bash users permissions executable

我创建了一个 Bash 脚本,它与"Hello World"相呼应。我还创建了一个测试用户bob,使用adduser.

没有人有权执行该文件,如下所示ls

$ ls -l hello.sh 
-rw-r--r-- 1 george george 19 Mai 29 13:06 hello.sh
Run Code Online (Sandbox Code Playgroud)

正如我们从上面看到的,文件的所有者是乔治,他只有读写访问权限,但没有执行访问权限。但是以乔治身份登录我可以直接执行脚本:

$ . hello.sh 
Hello World
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,我以bob身份登录,我只有读取权限,但我仍然可以执行该文件:

$ su bob
Password: 
$ . /home/george/testdir/hello.sh 
Hello World
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

Adm*_*Bee 27

在您的示例中,您不是在执行文件,而是在采购它们。

执行将通过

$ ./hello.sh
Run Code Online (Sandbox Code Playgroud)

为此,需要执行权限。在这种情况下,会打开一个子 shell,在其中执行脚本文件的命令。

采购,即

$ . hello.sh
Run Code Online (Sandbox Code Playgroud)

(中间有一个空格)只读取文件,然后您从中调用. hello.sh命令的外壳程序直接以读取方式执行命令,即不打开子外壳程序。由于文件是只读的,读权限足以进行操作。(另请注意,像这样声明脚本文件名会调用PATH搜索,因此如果hello.sh您的文件PATH 有另一个将被获取!使用显式路径,如. ./hello.sh确保您获取“正确的”。

如果您想防止这种情况发生,您还必须为不应该使用该脚本的任何用户删除读取权限。如果您真的担心未经授权使用脚本,这无论如何都是合理的,因为

  • 非授权用户可以通过简单地将脚本内容复制并粘贴到他们可以赋予自己执行权限的新文件中来轻松绕过缺少的执行权限,并且
  • 正如 Kusalananda 所指出的那样,否则未经授权的用户仍然可以通过调用它来舒适地使用脚本
    sh ./hello.sh
    
    Run Code Online (Sandbox Code Playgroud) 代替
    ./hello.sh
    
    Run Code Online (Sandbox Code Playgroud) 因为这也只需要对脚本文件的读取权限(例如,请参阅此答案)。

作为一般说明,请记住,采购和执行脚本之间存在细微差别(例如,请参阅此问题)。


ter*_*don 12

执行权限仅表示可以执行该文件。但是,当您获取它 ( . hello.shor source hello.sh) 或将它作为参数传递给 shell 解释器 ( sh hello.sh) 时,您不是在执行文件,而是在执行另一个命令 ( .or sh) 并将文件作为参数传递给那个命令。

因此,为了回答您的问题,您可以“执行”文件. hello.sh的原因与您可以运行的原因相同cat hello.sh:您只是在读取文件,而不是执行它。

为了显示:

$ ls -l
total 4.0K
-r--r--r-- 1 terdon terdon 21 May 29 12:29 foo.sh

$ cat ./foo.sh 
#!/bin/sh
echo Hello

$ ./foo.sh
bash: ./foo.sh: Permission denied

$ sh ./foo.sh
Hello
Run Code Online (Sandbox Code Playgroud)

如您所见,我实际上无法执行脚本,但我可以阅读它——无论是使用cat还是使用.——都非常好。

  • 另请注意,如果用户对脚本具有读取权限,则他们可以复制它,然后由于他们拥有副本,因此可以在副本上设置他们想要的任何权限(包括执行访问权限)。 (4认同)

Jör*_*tag 6

非常简短的版本是:您没有执行该文件。您正在将其入 shell,然后 shell 执行它。

请注意,某些语言解释器会检查他们被要求执行的文件的执行权限,如果用户没有适当的权限,则会拒绝这样做。但这是该特定解释器的作者完全自行决定的检查,并且不受操作系统强制执行。

让我们做一个小小的思想实验。

我想我们都同意,如果一个程序有可执行权限,我应该被允许执行这个程序。我想我们也同意应该允许这个程序将字符串“Hello World”打印到控制台。

此外,我们可能也同意,只要该文件具有读取权限,程序就应该能够读取该文件。并且该文件的内容是什么并不重要,只要该文件设置了读取权限位,就应该允许程序读取它。

好的,既然我们已经同意应该允许程序向控制台打印“Hello World”,并且我们已经同意应该允许程序读取文件,那么您必须在逻辑上也同意程序应该被允许读取文件并将“Hello World”打印到控制台。而且我们也说过,程序是否被允许读取文件取决于权限,而不是内容,所以也应该允许程序读取文件并在内容中打印“Hello World”到控制台文件是echo Hello World.

现在,您是否也同意,既然允许程序读取文件并且允许程序将“Hello World”打印到控制台,那么它也允许检查文件的内容并且打印“Hello World” " 到控制台,如果文件的内容是echo Hello World

好吧,但它“解释”,换句话说就是执行文件,您刚刚同意我应该允许这样做的每一步!

而这正是这里发生的事情。shell 只是读取一个文本文件,它被允许这样做,因为该文本文件具有读取权限。并且外壳正在执行其被允许这样做,因为在文本文件中的说明,外壳具有执行权限。