shellshock (CVE-2014-6271/7169) 错误是什么时候引入的,完全修复它的补丁是什么?

Dee*_*ter 122 security bash shellshock

关于该错误的一些上下文:CVE-2014-6271

Bash 不仅支持将 shell 变量导出,还支持将 shell 函数导出到其他 bash 实例,通过进程环境到(间接)子进程。当前的 bash 版本使用由函数名称命名的环境变量,以及变量值中以“() {”开头的函数定义,以通过环境传播函数定义。该漏洞的出现是因为bash在处理函数定义后没有停止;它会按照函数定义继续解析和执行 shell 命令。例如,环境变量设置

  VAR=() { ignored; }; /bin/id
Run Code Online (Sandbox Code Playgroud)

将环境导入 bash 进程时执行 /bin/id 。

资料来源:http : //seclists.org/oss-sec/2014/q3/650

该错误是什么时候引入的,完全修复它的补丁是什么?(参见CVE-2014-7169

除了 CVE(最初)(3.{0..2} 和 4.{0..3})中提到的易受攻击版本之外,还有哪些易受攻击的版本?

有问题的源代码是否在其他项目中重用?

需要额外的信息。


相关:什么是 env x='() { :;}; 命令' bash 做,为什么不安全?

Sté*_*las 205

TL; 博士

shellshock 漏洞已完全修复

  • 在 bash-2.05b 分支上:2.05b.10 及更高版本(包括补丁 10)
  • 在 bash-3.0 分支上:3.0.19 及更高版本(包括补丁 19)
  • 在 bash-3.1 分支上:3.1.20 及更高版本(包括补丁 20)
  • 在 bash-3.2 分支上:3.2.54 及更高版本(包括补丁 54)
  • 在 bash-4.0 分支上:4.0.41 及更高版本(包括补丁 41)
  • 在 bash-4.1 分支上:4.1.14 及更高版本(包括补丁 14)
  • 在 bash-4.2 分支上:4.2.50 及更高版本(包括补丁 50)
  • 在 bash-4.3 分支上:4.3.27 及更高版本(包括补丁 27)

如果您的 bash 显示旧版本,您的操作系统供应商可能仍然自己修补了它,所以最好检查一下。

如果:

env xx='() { echo vulnerable; }' bash -c xx
Run Code Online (Sandbox Code Playgroud)

显示“脆弱”,你仍然脆弱。这是唯一相关的测试(bash 解析器是否仍然暴露于任何环境变量中的代码)。

细节。

该错误出现在1989 年 8 月5由 Brian Fox引入的导出/导入函数的初始实现中,并在大约一个月后首次在 bash-1.03 中发布,当时 bash 在安全之前没有得到如此广泛的使用这是一个非常重要的问题,HTTP 和 Web 或 Linux 甚至存在。

1.05 中ChangeLog

Fri Sep  1 18:52:08 1989  Brian Fox  (bfox at aurel)

       * readline.c: rl_insert ().  Optimized for large amounts
         of typeahead.  Insert all insertable characters at once.

       * I update this too irregularly.
         Released 1.03.
[...]
Sat Aug  5 08:32:05 1989  Brian Fox  (bfox at aurel)

       * variables.c: make_var_array (), initialize_shell_variables ()
         Added exporting of functions.
Run Code Online (Sandbox Code Playgroud)

当时 gnu.bash.bugcomp.unix.questions 中的一些讨论也提到了该功能。

很容易理解它是如何到达那里的。

bash 导出环境变量中的函数,如

foo=() {
  code
}
Run Code Online (Sandbox Code Playgroud)

在导入时,它所要做的就是=用空格替换来解释它......除了它不应该盲目地解释它。

它也被破坏了bash(与 Bourne shell 相反),标量变量和函数具有不同的名称空间。其实如果你有

foo() { echo bar; }; export -f foo
export foo=bar
Run Code Online (Sandbox Code Playgroud)

bash 会很乐意将两者都放在环境中(是的,具有相同变量名的条目),但许多工具(包括许多外壳)不会传播它们。

有人还会争辩说 bash 应该BASH_为此使用命名空间前缀,因为那是仅与 bash 相关的 env vars 到 bash。为类似的功能rc使用fn_前缀。

实现它的更好方法是将所有导出变量的定义放在一个变量中,例如:

BASH_FUNCDEFS='f1() { echo foo;}
  f2() { echo bar;}...'
Run Code Online (Sandbox Code Playgroud)

这仍然需要清理,但至少不能比$BASH_ENV$SHELLOPTS......

有一个补丁可以防止bash解释除函数定义之外的任何内容(https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html),这就是具有已应用于各种 Linux 发行版的所有安全更新。

但是,bash 仍然会解释那里的代码,并且解释器中的任何错误都可能被利用。已经发现了一个这样的错误(CVE-2014-7169),尽管它的影响要小得多。所以很快就会有另一个补丁。

在防止 bash 解释任何变量中的代码的强化修复(如使用上述BASH_FUNCDEFS方法)之前,我们无法确定我们是否不会受到 bash 解析器中的错误的影响。而且我相信迟早会发布这样的强化修复程序。

编辑 2014-09-28

已发现解析器中的另外两个错误 (CVE-2014-718{6,7})(请注意,对于极端情况,大多数 shell 的解析器中必然存在错误,如果该解析器没有,则不会有问题' 没有接触到不受信任的数据)。

虽然所有 3 个错误 7169、7186 和 7187 都已在以下补丁中修复,但 Red Hat 推动了强化修复。在他们的补丁中,他们改变了行为,以便将函数导出到称为BASH_FUNC_myfunc()或多或少抢占 Chet 设计决策的变量中。

Chet 后来将该修复作为官方上游 bash 补丁发布

该强化补丁或其变体现在可用于大多数主要 Linux 发行版,并最终适用于 Apple OS/X。

现在解决了对任何通过该向量利用解析器的任意 env var 的担忧,包括解析器中的另外两个漏洞 (CVE-2014-627{7,8}),后来Micha披露了这些漏洞?Zalewski(CVE-2014-6278 几乎和 CVE-2014-6271 一样糟糕)幸运的是,在大多数人有时间安装加固补丁之后

解析器中的错误也将得到修复,但由于解析器不再那么容易暴露于不受信任的输入,因此它们不再是一个大问题。

请注意,虽然安全漏洞已得到修复,但我们很可能会在该领域看到一些变化。CVE-2014-6271 的初始修复破坏了向后兼容性,因为它停止导入带有.:/名称的函数。这些仍然可以由 bash 声明,尽管这会导致不一致的行为。因为名称中带有.和 的函数:是常用的,所以补丁很可能会恢复至少接受来自环境的函数。

为什么没有早点发现?

这也是我疑惑的地方。我可以提供一些解释。

首先,我认为如果安全研究人员(我不是专业安全研究人员)专门寻找 bash 中的漏洞,他们很可能会找到它。

例如,如果我是一名安全研究员,我的方法可能是:

  1. 看看从哪里bash获取输入以及它用它做什么。环境是显而易见的。
  2. 查看bash调用解释器的位置和数据。再次,它会脱颖而出。
  3. 导出函数的导入bash是 setuid/setgid时禁用的功能之一,这使它成为一个更明显的地方。

现在,我怀疑没有人想过将bash(口译员)视为威胁,或者威胁可能以这种方式出现。

bash解释并不意味着处理不可信的输入。

Shell脚本(不是解释器)经常从安全的角度被仔细研究。shell 语法非常笨拙,并且在编写可靠的脚本时有很多警告(有没有见过我或其他人提到 split+glob 运算符,或者为什么要引用变量?),因此在处理脚本的脚本中发现安全漏洞是很常见的不受信任的数据。

这就是为什么你经常听到你不应该编写 CGI shell 脚本,或者在大多数 Unices 上禁用 setuid 脚本的原因。或者在处理世界可写目录中的文件时应该格外小心(例如,参见CVE-2011-0441)。

重点是 shell 脚本,而不是解释器。

您可以公开一个shell解释器不可信数据通过(喂国外数据作为shell代码来解释)eval.或调用它的用户提供的文件,但你并不需要一个漏洞bash利用它。很明显,如果您将未经处理的数据传递给 shell 进行解释,它会解释它。

所以 shell 在受信任的上下文中被调用。它被赋予了固定的脚本来解释,而且通常(因为编写可靠的脚本是如此困难)固定的数据来处理。

例如,在 web 上下文中,shell 可能会以如下方式调用:

popen("sendmail -oi -t", "w");
Run Code Online (Sandbox Code Playgroud)

那可能会出什么问题?如果出现错误,那是关于馈送到该 sendmail 的数据,而不是该 shell 命令行本身是如何解析的,或者是什么额外的数据馈送到该 shell。您没有理由要考虑传递给该 shell 的环境变量。如果你这样做,你会发现这一切都ENV乏的名字开始与“HTTP_”或者是众所周知的CGI ENV瓦尔像SERVER_PROTOCOL或者QUERYSTRING其中没有外壳或sendmail,有什么生意做。

在特权提升上下文中,例如运行 setuid/setgid 或通过 sudo 时,通常会考虑环境,并且过去存在大量漏洞,同样不是针对 shell 本身,而是针对提升特权的事物,例如sudo(参见CVE -2011-3628)。

例如,bash当 setuid 或由 setuid 命令mount调用时不信任环境(例如调用帮助程序)。特别是,它会忽略导出的函数。

sudo确实清理了环境:默认情况下,除了白名单之外,所有的都是,如果配置不这样做,至少会列出一些已知会影响 shell 或其他的黑名单(如PS4, BASH_ENV, SHELLOPTS...)。它还会将内容以 开头的环境变量列入黑名单()(这就是 CVE-2014-6271 不允许通过 进行权限提升的原因sudo)。

但同样,这适用于无法信任环境的上下文:恶意用户可以在该上下文中设置具有任何名称和值的任何变量。这不适用于 web 服务器/ssh 或所有利用 CVE-2014-6271 的向量,其中环境受控制(至少环境变量的名称是受控制的......)

阻止像 一样的变量很重要echo="() { evil; }",但不是HTTP_FOO="() { evil; }",因为HTTP_FOO它不会被任何 shell 脚本或命令行作为命令调用。apache2 永远不会设置一个echoBASH_ENV变量。

很明显,某些环境变量在某些上下文中应该根据名称列入黑名单,但没有人认为应该根据其内容将其列入黑名单(除了sudo)。或者换句话说,没有人认为任意 env vars 可以成为代码注入的向量。

至于在添加该功能时是否进行了广泛的测试可以发现它,我认为不太可能。

测试功能时,就是测试功能。该功能运行良好。如果您在一次bash调用中导出该函数,则在另一次调用中可以正常导入。当导出具有相同名称的变量和函数时,或者当函数导入的区域设置与导出时的区域设置不同时,非常彻底的测试可能会发现问题。

但是为了能够发现漏洞,您不必进行功能测试。安全方面必须是主要关注点,您不会测试功能,而是测试机制以及如何滥用它。

这不是开发人员(尤其是在 1989 年)经常想到的事情,并且 shell 开发人员可以有理由认为他的软件不太可能被网络利用。

  • PS:这个答案来自最初发现错误的人:) (128认同)
  • 请问……您是无意中发现了这个错误,还是您在 Bash 中积极寻找错误? (32认同)
  • @gerrit 因为该错误在正常情况下不会导致任何不良行为。由于没有任何问题,除了安全研究人员和黑帽子之外,没有人会查看代码。 (7认同)
  • @Ben 这不是相反问题的答案吗? (6认同)
  • @JacekSzymanski 是真的,但其他标题呢?特别是自定义标题?(攻击者可以添加一个应该设置为 HTTP_X_EXPORT_PAYLOAD 的 X-Exploit-Payload 标头) (4认同)
  • 1993 年... 怎么可能需要*超过 20 年* 才能发现如此接近功能核心的如此巨大的错误? (3认同)
  • 因为很多眼睛让所有的虫子都变浅了。这就是 HeartBleed 也能如此迅速地被发现的原因。 (3认同)
  • 在 94 Chet Ramey 将其描述为 [* 早于指定导出函数的旧 POSIX 2 规范,无论如何*](http://www.linuxmisc.com/12-unix-shell/e3f174655d75a48b.htm)。或者,至少,他将 *`bash` 机制* 描述为这样做 - 我不知道它当时是否像现在一样有缺陷。他还在该线程中讨论了 `rc` 的函数导出。 (3认同)
  • 在这里让我印象深刻的不是 bash 的不当行为,而是首先允许任何未经消毒的不受信任的数据到达 shell。 (3认同)

Dee*_*ter 19

根据 NIST 的 NVD 数据库 ( http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271 ),从 1.14.0 开始的所有版本的 bash 都是易受攻击的。

RedHat 于9 月 14 日获悉该漏洞。

Mr.Ramey(bash 维护者)于 2014 年 9 月 26 日发布的补丁修复了CVE-2014-7169 错误

将这些和所有以前的补丁应用到相应的 bash 源:


bash 中的额外漏洞


关于错误历史的更多信息(由mikeserv 提供

来源:http : //www.linuxmisc.com/12-unix-shell/e3f174655d75a48b.htm

1994 年,Chet Ramey 将其描述为早于指定导出函数的旧 POSIX 2 规范。或者,至少,他将 bash 机制描述为这样做 - 我不知道它当时是否像现在一样有缺陷。他还在该线程中讨论了 rc 的函数导出。