检查 shellshock 的命令说明

检查 shellshock 的命令说明

下面是我用来检查 bash shell 中是否存在 Shellshock 错误的命令:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

有人可以详细解释一下这个命令吗?

答案1

这个答案是原文刊登于 Fedora Magazine作者:Matthew Miller,许可:知识共享署名-相同方式共享 4.0执照。

让我解释:

env x='() { :;}; echo OOPS' bash -c :

这将在易受攻击的系统上打印“OOPS”,但如果 bash 已修补,则会默默退出。

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

这将在易受攻击的系统上打印“OOPS”,但“this is a test”如果 bash 已被修补,则会打印。

您可能听说过它与环境变量有关。但是,为什么环境变量中的代码会被执行呢?嗯,它不应该被执行——但是,由于一个我认为有点过于聪明的功能,它存在一些缺陷。Bash 就是您所看到的终端提示符,但它也是一种脚本语言,并且能够定义函数。您可以像这样执行此操作:

$ Ubuntu()  { echo "Ubuntu is awesome."; }

然后你就有了一个新命令。请记住,这里echo实际上还没有运行;它只是保存了我们运行新命令时将发生的情况。这在一分钟后会很重要!

$ Ubuntu
 Ubuntu is awesome.

有用!但是,假设出于某种原因,我们需要执行一个新的 bash 实例作为子进程,并希望在该实例下运行我出色的新命令。该语句的bash -c somecommand作用正是:在新 shell 中运行给定的命令:

$ bash -c Ubuntu
  bash: Ubuntu: command not found

哦,真可惜。子进程没有继承函数定义。但是,它继承了环境——从 shell 导出的键值对集合。(这是一个全新的概念;如果你不熟悉这个概念,现在请相信我。)而且,事实证明,bash 也可以导出函数。所以:

$ export -f Ubuntu
$ bash -c Ubuntu
  Ubuntu is awesome.

这一切都很好——只是实现这一点的机制是有点不可靠。基本上,由于 Linux/Unix 没有在环境变量中执行函数的魔法,因此导出函数实际上只是创建一个包含函数定义的常规环境变量。然后,当第二个 shell 读取“传入”环境并遇到内容看起来像函数的变量时,它会对其进行评估。

从理论上来说,这是万无一失因为,记住,定义一个函数实际上并不执行它。除了——这也是我们来这里的原因——代码中有一个错误,当到达函数定义的末尾时,求值并没有停止。它只是继续下去。

当存储在环境变量中的函数合法地创建时,这种情况永远不会发生export -f。但是,为什么要合法呢?攻击者可以编写任何旧的环境变量,如果它看起来像一个函数,新的 bash shell 就会认为它是!

因此,在我们的第一个例子中:

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

env命令使用给定的变量集运行命令。在本例中,我们将其设置x为看起来像函数的东西。该函数只是一个:,实际上是一个简单的命令,它被定义为不执行任何操作。但是,在semi-colon表示函数定义结束的后面,有一个echo命令。它不应该在那里,但没有什么可以阻止我们这样做。

然后,在这个新环境中运行的命令是一个新的 bash shell,再次带有“ echo this is a test”或“不执行任何操作:”命令,之后它将退出,完全无害。

但是 — 哎呀!当新 shell 启动并读取环境时,它会获取变量x,由于它看起来像一个函数,因此它会对其进行求值。函数定义被无害地加载 — 然后我们的恶意负载也会被触发。因此,如果您在易受攻击的系统上运行上述代码,您将收到“OOPS”打印结果。或者,攻击者可以做的比打印结果更糟糕。

答案2

未打补丁的版本bash它将导出的函数定义存储为环境变量。

将函数存储x为,

$ x() { bar; }
$ export -f x

并检查其定义如下,

$ env | grep -A1 x
x=() {  bar
}

因此,人们可以通过定义自己的环境变量来利用这一点,并将它们解释为函数定义。例如,env x='() { :;}'将被视为

x() { :;
}

检查 shellshock 的命令有什么作用,

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

man env

  1. env- 在修改后的环境中运行程序。

  2. :不执行任何操作,仅以退出状态退出0。请参阅更多的

  3. 当未打补丁的 bash 的新实例以 启动时bash -c "echo this is a test",精心设计的环境变量将被视为函数并加载。因此,可以得到输出

    易受伤害的
    这是一个测试

笔记:在 bash 启动期间,函数定义之外的 echo 被意外执行。函数定义只是使求值和利用发生的一个步骤,函数定义本身和使用的环境变量都是任意的。shell 查看环境变量,看到 x,它看起来符合它所知道的函数定义的约束,并且它求值该行,无意中也执行了 echo(可能是任何命令,无论是否恶意)。另请参阅

相关内容