有关该错误的一些背景信息:CVE-2014-6271
Bash 不仅支持将 shell 变量导出,还支持将 shell 函数导出到其他 bash 实例,通过进程环境导出到(间接)子进程。当前的 bash 版本使用由函数名称命名的环境变量,以及变量值中以“() {”开头的函数定义,以在环境中传播函数定义。该漏洞的发生是因为 bash 在处理函数定义后没有停止;它继续解析并执行函数定义后的 shell 命令。例如,环境变量设置为
VAR=() { ignored; }; /bin/id
当环境导入bash进程时会执行/bin/id。
来源:http://seclists.org/oss-sec/2014/q3/650
该错误是什么时候引入的?完全修复该错误的补丁是什么?(看CVE-2014-7169)
CVE(最初)中未注明的易受攻击的版本是什么(3.{0..2} 和 4.{0..3})?
有缺陷的源代码是否已在其他项目中重用?
需要额外的信息。
答案1
长话短说
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
显示“脆弱”,你仍然很脆弱。这是唯一相关的测试(bash 解析器是否仍然暴露于任何环境变量)。
细节。
该错误存在于 Brian Fox 于 1989 年 8 月 5日引入的导出/导入函数的初始实现中,大约一个月后在 bash-1.03 中首次发布,当时 bash 在安全性之前还没有得到如此广泛的使用。这是人们非常关心的问题,HTTP 和 Web 或 Linux 甚至都存在。
来自1.05 中的变更日志:
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.
中的一些讨论gnu bash 错误和comp.unix.问题大约在那个时候也提到了这个功能。
很容易理解它是如何到达那里的。
bash 导出环境变量中的函数,例如
foo=() {
code
}
在导入时,它所要做的就是用=
空格替换它来解释它......除了它不应该盲目地解释它。
它的另一个问题是bash
(与 Bourne shell 相反),标量变量和函数具有不同的名称空间。其实如果你有
foo() { echo bar; }; export -f foo
export foo=bar
bash
会很乐意将两者放入环境中(是的,具有相同变量名的条目),但许多工具(包括许多 shell)不会传播它们。
有人还认为 bash 应该BASH_
为此使用命名空间前缀,因为环境变量仅与 bash 之间相关。rc
使用fn_
类似功能的前缀。
更好的实现方法是将所有导出变量的定义放在一个变量中,例如:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
这仍然需要清理,但至少不能比$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 已在后续补丁中得到修复,但红帽仍在推动强化修复。在他们的补丁中,他们改变了行为,以便将函数导出到称为BASH_FUNC_myfunc()
或多或少抢占 Chet 设计决策的变量中。
切特稍后将该修复发布为官方上游 bash 补丁。
该强化补丁或其变体现在可用于大多数主要 Linux 发行版,并最终进入 Apple OS/X。
现在,这消除了对通过该向量利用解析器的任意环境变量的担忧,包括解析器中的另外两个漏洞 (CVE-2014-627{7,8})后来被披露作者:Michał Zalewski(CVE-2014-6278 几乎与 CVE-2014-6271 一样糟糕),幸好大多数人都有时间安装强化补丁
解析器中的错误也将得到修复,但由于解析器不再那么容易暴露于不受信任的输入,因此它们不再是一个大问题。
请注意,虽然安全漏洞已得到修复,但我们很可能会看到该领域的一些变化。 CVE-2014-6271 的初始修复破坏了向后兼容性,因为它停止导入名称中带有.
或:
的函数。/
这些仍然可以由 bash 声明,但这会导致行为不一致。由于其名称中带有.
和 的函数:
很常用,因此补丁很可能会恢复至少接受来自环境的函数。
为什么不早点发现呢?
这也是我想知道的事情。我可以提供一些解释。
首先,我认为如果安全研究人员(我不是专业的安全研究人员)专门寻找 bash 中的漏洞,他们很可能会找到它。
例如,如果我是一名安全研究员,我的方法可能是:
- 看看
bash
从哪里获取输入以及它如何处理它。而环境也是一目了然的。 - 查看
bash
解释器在哪些位置被调用以及在哪些数据上被调用。再次,它会脱颖而出。 - 的进口导出函数是 setuid/setgid 时禁用的功能之一
bash
,这使得它成为一个更明显的地方。
现在,我怀疑没有人认为bash
(口译员)是一种威胁,或者威胁可能是这样产生的。
解释器bash
并不意味着处理不受信任的输入。
壳脚本(而不是解释器)经常从安全角度受到密切关注。 shell 语法非常尴尬,而且编写可靠的脚本有很多警告(见过我或其他人提到过 split+glob 运算符,或者为什么你应该引用变量?),因此在处理脚本的过程中发现安全漏洞是很常见的。不可信的数据。
这就是为什么您经常听说您不应该编写 CGI shell 脚本,或者 setuid 脚本在大多数 Unices 上被禁用。或者,在处理全局可写目录中的文件时应该格外小心(请参阅CVE-2011-0441例如)。
重点是 shell 脚本,而不是解释器。
eval
您可以通过或在用户提供的文件上调用它,将 shell 解释器暴露给不受信任的数据(将外部数据作为 shell 代码提供以进行解释).
,但是您不需要漏洞来bash
利用它。很明显,如果您将未经处理的数据传递给 shell 进行解释,它就会解释它。
因此 shell 是在可信上下文中调用的。它给出了固定的脚本来解释,并且通常(因为编写可靠的脚本非常困难)固定的数据来处理。
例如,在 Web 上下文中,可能会以如下方式调用 shell:
popen("sendmail -oi -t", "w");
这可能会出什么问题呢?如果设想出现问题,那是关于馈送到 sendmail 的数据,而不是 shell 命令行本身如何解析或向该 shell 馈送哪些额外数据。您没有理由考虑传递给该 shell 的环境变量。如果您这样做,您会意识到所有环境变量的名称都以“HTTP_”开头,或者是众所周知的 CGI 环境变量,SERVER_PROTOCOL
或者QUERYSTRING
与 shell 或 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 永远不会设置echo
orBASH_ENV
变量。
这是很明显的一些在某些情况下,环境变量应根据其情况被列入黑名单姓名,但没有人认为他们应该根据他们的情况被列入黑名单内容(除了sudo
)。或者换句话说,没有人认为任意环境变量可以成为代码注入的向量。
至于添加该功能时进行的广泛测试是否可以捕获它,我认为不太可能。
当您测试特征,您测试功能。该功能运行良好。如果您在一次调用中导出该函数bash
,那么它可以在另一次调用中导入。当导出同名的变量和函数时,或者在与导出时不同的语言环境中导入函数时,非常彻底的测试可能会发现问题。
但为了能够发现漏洞,您不必进行功能测试。安全方面必须成为主要焦点,并且您不会测试功能,而是测试机制以及如何滥用它。
这并不是开发人员(尤其是在 1989 年)经常会想到的事情,而且 shell 开发人员可能会认为他的软件不太可能被网络利用。
答案2
根据 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 源:
- http://ftp.gnu.org/pub/gnu/bash/bash-2.05b-patches/bash205b-010
- http://ftp.gnu.org/pub/gnu/bash/bash-3.0-patches/bash30-019
- http://ftp.gnu.org/pub/gnu/bash/bash-3.1-patches/bash31-020
- http://ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-054
- http://ftp.gnu.org/pub/gnu/bash/bash-4.0-patches/bash40-041
- http://ftp.gnu.org/pub/gnu/bash/bash-4.1-patches/bash41-014
- http://ftp.gnu.org/pub/gnu/bash/bash-4.2-patches/bash42-050
- http://ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-027
bash 中的额外漏洞
- https://access.redhat.com/security/cve/CVE-2014-7186
- https://access.redhat.com/security/cve/CVE-2014-7187
有关该错误历史的更多信息(由麦克塞夫)
来源:http://www.linuxmisc.com/12-unix-shell/e3f174655d75a48b.htm
1994 年,Chet Ramey 将其描述为早于指定导出函数的旧 POSIX 2 规范。或者,至少,他描述了 bash 机制是这样做的——我不知道它当时是否和现在一样有缺陷。他还在该线程中讨论了 rc 的函数导出。