Translated message

A translation of this page exists in English.

缓解 shellshock 漏洞 (CVE-2014-6271 和 CVE-2014-7169)

已更新 -

Warning

这些缓解措施会涉及到如果没有正常执行会导致意外后果的操作。因为我们建议,只有完全了解这些更改影响的、经验丰富的系统管理员才这些本文中介绍的缓解方案。红帽只对这些缓解措施进行了有限的测试。

重要:鉴于用于修复相关安全漏洞的软件包更新已可用,这里所介绍的缓解方案只应在特殊情况下使用,它并不是安装相关的更新软件包的替代方案。红帽建议所有 Bash 用户尽快升级到更新的软件包。

基于网络的缓解方案

网络缓解 1: mod_security 规则

以下 mod_security 规则可用于拒绝包含了可以倍 Bash 解释为是一个函数定义的数据的 HTTP 请求(如果在其环境中设置)。这些规则可用于阻止对 Web 服务的攻击,如对 CGI 应用程序的攻击。
请求标头值:

SecRule REQUEST_HEADERS "^\(\s*\)\s+{" "phase:1,deny,id:1000000,t:urlDecode,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

SERVER_PROTOCOL 值:

SecRule REQUEST_LINE "^\(\s*\)\s+{" "phase:1,deny,id:1000001,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

GET/POST 名称:

SecRule ARGS_NAMES "^\(\s*\)\s+{" "phase:2,deny,id:1000002,t:urlDecode,t:urlDecodeUni,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

GET/POST 值:

SecRule ARGS "^\(\s*\)\s+{" "phase:2,deny,id:1000003,t:urlDecode,t:urlDecodeUni,status:400,log,msg:'CVE-2014-6271 - Bash Attack'"

上传的文件名:

SecRule FILES_NAMES "^\(\s*\)\s+{"  "phase:2,deny,id:1000004,t:urlDecode,t:urlDecodeUni,status:400,log,msg:'CVE-2014-6271  - Bash Attack'"

这里存在(但不太可能发生)这些规则导致假正(false positive)的情况。这些假正,以及实际的尝试,可能会导致日志文件包括大量数据。

网络缓解 2:IPTables 规则

可以使用 IPTables 字符串匹配功能来尝试丢弃可能属于攻击的数据包,例如:

# iptables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP
# ip6tables -A INPUT -m string --algo bm --hex-string '|28 29 20 7B|' -j DROP

请注意,这是一个非常弱的临时解决方案,因为攻击者可以在每个数据包中只发送一两个字符,这样就可避免与这个签名检查匹配的情况。通过这个方法以及检查日志记录,可以大致了解利用此安全漏洞自动进行尝试的概况。

基于系统的缓解方案

shellshock 漏洞的基础是,在调用 Bash shell 前可以创建带有特殊设计值的环境变量。这些变量可以包含代码,这些代码在调用 shell 后会立即执行。针对 CVE-2014-6271 发布的初始补丁并不完善。针对 CVE-2014-7169 的补丁可以解决这个问题,但它并没有完全删除存在安全漏洞的功能。如果您从 Bash 中完全删除了存在安全漏洞的功能,则所有可能的攻击变体都将会被缓解。

基于系统的缓解方案 1: LD_PRELOAD

LD_PRELOAD 是一个环境变量,它被运行时使用,用于连接进程(在一个替代的位置搜索共享库,并强制加载和链接要使用的库)。这会强制加载一些符号/函数,并使它们比程序中内建的函数有更高的优先级。这个代码会创建一个新的 "strip_env" 函数,它带有 gcc "constructor" 属性设置。具有此属性设置的函数将在进入 main() 前执行。详情请查看 https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

$ sha256sum bash_ld_preload.c
28cb0ab767a95dc2f50a515106f6a9be0f4167f9e5dbc47db9b7788798eef153
bash_ld_preload.c
  • 编译它:
$ gcc bash_ld_preload.c -fPIC -shared -Wl,-soname,bash_ld_preload.so.1 \
-o bash_ld_preload.so
  • 将 bash_ld_preload.so 复制到 /lib :
# cp bash_ld_preload.so /lib/

如果要在整个系统中应用这个临时解决方案:

  • 在 /etc/ld.so.preload 中添加以下内容(它需要自己占据一行):
/lib/bash_ld_preload.so
  • 重启所有相关服务或重启系统。

请注意,这可能存在潜在的风险。建议您只针对可能会倍攻击的系统中的特定服务使用这个临时解决方案。这可以通过将 bash_ld_preload.so 添加到用于初始相关服务的脚本中的 LD_PRELOAD 环境变量来实现。但是,这不适用于使用 SUID 二进制的服务(例如,使用 SUEXEC 的 httpd),因为 LD_PRELOAD 命令在 SUID 二进制中无效。

  • 在 /etc/init.d/httpd 的顶部(shebang 行以后)添加以下两行:
LD_PRELOAD=/lib/bash_ld_preload.so
export LD_PRELOAD
  • 编辑 httpd.conf 并添加以下指令并保存配置文件:
PassEnv LD_PRELOAD
  • 然后重启 httpd:
# service httpd restart

基于系统的缓解方案 2: systemtap

强制 bash 使用特权模式可以缓解这个问题。

安装 bash debuginfo

$ sudo debuginfo-install bash

安装 systemtap

$ sudo yum install systemtap

运行这个命令:

$ nohup sudo stap -g -e '  probe process("/bin/bash").function("initialize_shell_variables") { $privmode=1 }  '

这样可确保始终启用 bash 特权模式(等同于 bash -p)。要验证,测试原始漏洞 (CVE-2014-6271):

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

上面是一个不受影响的示例。最后,测试安全漏洞 (CVE-2014-7169):

$  env X='() { (a)=>\' sh -c "echo date"; cat echo
date
cat: echo: No such file or directory

上面是一个不受影响的示例。

强制启用特权模式会有一些副作用,某些系统管理员可能需要加以注意。下面是 bash man page 中的相关内容。

  -p  Turn on privileged mode.  In this mode, the $ENV and $BASH_ENV files
are not processed, shell functions are not inherited from the
environment, and the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE
variables, if they appear in the environment, are ignored. If the
shell is started with the effective user (group) id not equal to the
real user (group) id, and the -p option is not supplied, these
actions are taken and the effective user id is set to the real user
id. If the -p option is supplied at startup, the effective user id
is not reset. Turning this option off causes the effective user and
group ids to be set to the real user and group ids.

以上脚本是一个临时缓解方案,重启后将不再有效。

Comments