TL; DR
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显示较旧的版本,则您的OS供应商可能仍然已经对其进行了修补,因此最好检查一下。
如果:
env xx='() { echo vulnerable; }' bash -c xx
显示“易受攻击”,则您仍然处于脆弱状态。那是唯一相关的测试(bash解析器是否仍暴露于任何环境变量中的代码)。
细节。
该错误是由Brian Fox在1989年8月5 日引入的功能导出/导入的最初实现中实现的,并于大约一个月后在bash尚未得到广泛使用的时候首次发布于bash-1.03中,此后才被安全使用。这是一个令人担忧的问题,甚至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.
那个时候在gnu.bash.bug和comp.unix.questions中的一些讨论也提到了该功能。
很容易理解它是如何到达那里的。
bash导出env vars中的函数,例如
foo=() {
code
}
而在导入时,它所要做的就是=
用空格代替来解释它,只是不要盲目地解释它。
它也被打破了bash
(与Bourne外壳相反),标量变量和函数具有不同的名称空间。其实如果你有
foo() { echo bar; }; export -f foo
export foo=bar
bash
会很高兴将它们都放入环境中(是的,具有相同的变量名),但是许多工具(包括许多shell)不会传播它们。
还会有人争辩说bash应该BASH_
为此使用名称空间前缀,因为env vars仅与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})(请注意,大多数外壳在解析器中一定会遇到一些极端情况的错误,如果该解析器没有该漏洞,则不必担心不会暴露给不受信任的数据)。
虽然所有3个bug 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中的漏洞,那么他们很可能会找到它。
例如,如果我是安全研究员,那么我的方法可能是:
- 查看从何处
bash
获取输入以及它如何处理输入。环境是显而易见的。
- 查看
bash
解释器在什么地方被调用以及在什么数据上。再次,它将脱颖而出。
- 使用setuid / setgid时,导入功能的导入是禁用的功能之一
bash
,这使它看起来更加明显。
现在,我怀疑没有人考虑将bash
(解释器)视为威胁,或者威胁可能以这种方式发生。
该bash
解释并不意味着处理不可信的输入。
Shell 脚本(而非解释器)通常从安全角度进行仔细研究。shell语法太笨拙,编写可靠脚本的警告很多(我见过别人或其他人提到过split + glob运算符,或者为什么要引用变量吗?),在处理该脚本的安全漏洞中很常见不可信数据。
这就是为什么您经常听到不应该编写CGI Shell脚本或在大多数Unices上禁用setuid脚本的原因。否则在处理可在世界各地写入的目录中的文件时,您应该格外小心(例如,请参阅CVE-2011-0441)。
重点是shell脚本,而不是解释器。
您可以通过eval
或.
在用户提供的文件上调用外壳解释程序,使外壳解释程序暴露于不受信任的数据(将外部数据作为外壳程序代码进行解释),但是您不需要任何漏洞bash
即可加以利用。很明显,如果您将未经处理的数据传递给Shell进行解释,它将解释它。
因此,在受信任的上下文中调用外壳。它提供了固定的脚本来解释,并且经常(因为很难编写可靠的脚本)来处理固定的数据。
例如,在Web上下文中,可以通过以下方式调用Shell:
popen("sendmail -oi -t", "w");
那可能出什么毛病?如果设想有问题,那是关于送入该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
做清洁的环境:全部由除白名单默认情况下,如果配置不,至少黑名单已知的几个影响一个壳或其他(如PS4
,BASH_ENV
,SHELLOPTS
...)。它还会将内容以其开头的环境变量列入黑名单()
(这就是CVE-2014-6271不允许通过进行权限提升的原因sudo
)。
但这又是针对无法信任环境的上下文:恶意用户可以在该上下文中设置具有任何名称和值的任何变量。这不适用于Web服务器/ ssh或利用CVE-2014-6271的所有媒介,在这些媒介中控制了环境(至少控制了环境变量的名称...)
重要的是,禁止阻塞类似的变量echo="() { evil; }"
,但不能阻塞HTTP_FOO="() { evil; }"
,因为HTTP_FOO
任何shell脚本或命令行都不会将其作为命令调用。而apache2永远不会设置echo
or或BASH_ENV
变量。
很明显,某些环境变量应在某些上下文中根据其名称被列入黑名单,但没有人认为应根据其内容将其列入黑名单(除外sudo
)。换句话说,没有人认为任意的环境变量可以作为代码注入的载体。
至于添加该功能时是否进行了广泛的测试,我想这不太可能。
在测试功能时,您在测试功能。功能正常。如果在一个bash
调用中导出函数,则在另一个调用中导入。当导出具有相同名称的变量和函数时,或者当导入的函数与导出时所使用的语言环境不同时,进行彻底的测试可能会发现问题。
但是要发现此漏洞,这不是您必须要做的功能测试。安全方面将不得不成为主要重点,并且您不会测试功能,而是测试机制以及如何滥用它。
开发人员(尤其是在1989年)常常没有这件事,而壳开发人员可能会以为自己的软件不太可能被网络利用而被原谅。