Bash

  • ​​破壳漏洞 解析漏洞​​

破壳漏洞 解析漏洞

Bash漏洞起因

curl -A "() { :; }; /bin/cat /etc/passwd" http://192.168.0.1/poc.cgi

curl是linux下用于http请求的一个工具,
-A是将User-Agent设置为() { :; }; /bin/cat /etc/passwd字符串

后面的http://192.168.0.1/poc.cgi是
位于服务器192.168.0.1的一个cgi脚本,为什么cat /etc/passwd可以在192.168.0.1执行成功
poc.cgi的源代码

#!/bin/bash

echo "Content-type: text/html"

echo ""

echo '<html>'

echo '<head>'

echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'

echo '<title>PoC</title>'

echo '</head>'

echo '<body>'

echo '<pre>'

/usr/bin/env

/* 这里存在一个BASH的调用,输出环境信息*/

echo '</pre>'

echo '</body>'

echo '</html>'

exit 0


poc.cgi
允许我们远程访问http://192.168.0.1/poc.cgi时
使用HTTP方式对/usr/bin/env进行调用

访问http://192.168.0.1/poc.cgi时可以设置任意的HTTP Header
比如User-Agent、Refer、cookie以及自定义等参数

而 Bash CGI会将客户端发送的HTTP数据包的HTTP头部的字段
作为ENV的参数传入环境变量的设置函数中,
也就是说Bash CGI默认将HTTP头部参数作为环境变量设置源。

“() { :; }; /bin/cat /etc/passwd”

User-Agent : () <-- 作为函数

{ :;}; <-- 函数体

/bin/cat /etc/passwd <-- 注入的代码

当我们的() { :; }; /bin/cat /etc/passwd被传入Bash的环境设置函数之后,
由于Bash使用的环境变量是通过函数名称来调用的,
因此以“(){”开头定义的环境变量在命令ENV中解析成函数后,
Bash会将这段代码这样解释:

“()”当做User-Agent()函数、而“{ :;};” 作为一个空的函数体。
这一Bash对环境进行设置的过程中,“
() { :; }; /bin/cat /etc/passwd”会被当做代码进行“代码执行(可以想象成php的eval)”。

注入的代码被成功解析执行后会以”环境变量”的形式保存在环境变量中,
然后CGI返回的HTTP数据包中会将环境变量一并发送回客户端,
也就是你看到的/bin/cat /etc/passwd执行了的结果。

问题产生的地方就在于Bash对环境进行设置的过程中对传入的参数在未检查其合法性的情况下,即进行了代码执行。

Bash 3.2中对此功能的实现:

evalstring.c

else if (command = global_command)

{ struct fd_bitmap *bitmap;

/*

这里没有对传入的command进行正确的边界检查,引入了代码注入的可能性

*/

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;

}

variables.c

/*

Initialize the shell variables from the current environment. If PRIVMODE is nonzero, don't import functions from

ENV

or

parse $SHELLOPTS.

*/

void initialize_shell_variables (env, privmode) char **env; int privmode;

{

...

create_variable_tables ();

/*

从ENV环境变量中获取参数

*/

for (string_index = 0; string = env[string_index++]; )

{

char_index = 0;

name = string;

while ((c = *string++) && c != '=') ;

if (string[-1] == '=')

char_index = string - name - 1;

/* If there are weird things in the environment, like `=xxx' or a

string without an `=', just skip them. */

if (char_index == 0)

continue;

/* ASSERT(name[char_index] == '=') */

name[char_index] = '\0';

/*

Now, name = env variable name, string = env variable value, and char_index == strlen (name)

*/

/*

If exported function, define it now. Don't import functions from the environment in privileged mode.

解析环境变量设置中的函数定义

*/

if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))

{

string_length = strlen (string);

temp_string = (char *)xmalloc (3 + string_length + char_index);

strcpy (temp_string, name);

temp_string[char_index] = ' ';

strcpy (temp_string + char_index + 1, string);

/*

这句是关键,initialize_shell_variables对环境变量中的代码进行了执行,由于它错误的信任的外部发送的数据,形成了和SQL注入类似的场景,这句代码和PHP中的eval是类似的,黑客只要满足2个条件

1. 控制发送的参数,并在其中拼接payload

2. 黑客发送的包含payload的参数会被无条件的执行,而执行方不进行任何的边界检查

这就是典型的数据和代码没有进行正确区分导致的漏洞

*/

parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);

// Ancient backwards compatibility. Old versions of bash exported functions like name()=() {...}

if (name[char_index - 1] == ')' && name[char_index - 2] == '(')

name[char_index - 2] = '\0';

if (temp_var = find_function (name))

{

VSETATTR (temp_var, (att_exported|att_imported));

array_needs_making = 1;

}

else

report_error (_("error importing function definition for `%s'"), name);

/* ( */

if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')

name[char_index - 2] = '('; /* ) */

}

}

Bash漏洞的影响范围
Bash漏洞迄今为止影响的系统或应用包括如下:
1 . 调用了Bash并对提交的http参数未作处理的cgi脚本

2 . gitlab (SSH) 对于git、rsync这类远程shell来说,
常常会对用户可以执行的指令进行严格限制,但是这个BASH解析漏洞提供了一个bypass的向量

3.DHCP 客户端
动态主机配置协议客户端被用来通过DHCP自动获取网络配置信息。
该客户端使用不同的环境变量和运行bash来配置网络接口。
连接到一个恶意的DHCP服务器可能允许攻击者在客户机上运行任意代码。

黑客通过在域中的DHCP服务器中对DHCP的回送包进行特定的修改(控制hostname、 domainname等参数),
可以达到污染dhcpclient的环境变量参数的目的,从而进行远程代码执行。
4. Qmail
5. F5
6. SIP
7. Pure-ftpd
8. tmnt