Linux I';我很难理解Shellshock漏洞验证

Linux I';我很难理解Shellshock漏洞验证,linux,bash,security,shellshock-bash-bug,Linux,Bash,Security,Shellshock Bash Bug,我在检查漏洞时得到了以下信息: host1:~$ env x='(){ :;}; echo vulnerable' bash -c "echo hello" hello host1:~$ env x='() { :;}; echo vulnerable' bash -c "echo hello" vulnerable hello host1:~$ 奇怪吧?bash对环境中的嵌入式函数定义有点挑剔。首先 env x='(){ :;}; echo vulnerable' bash -c "echo

我在检查漏洞时得到了以下信息:

host1:~$ env x='(){ :;}; echo vulnerable' bash -c "echo hello"
hello
host1:~$ env x='() { :;}; echo vulnerable' bash -c "echo hello"
vulnerable
hello
host1:~$

奇怪吧?

bash
对环境中的嵌入式函数定义有点挑剔。首先

env x='(){ :;}; echo vulnerable' bash -c "echo hello"}
()
{
之间缺少空格足以阻止
bash
将其识别为导出函数,因此它仍然是一个简单的shell变量;要查看,请尝试运行

env x='(){ :;}; echo vulnerable' bash -c 'echo $x'

在第二个示例中,带空格的
x
值被正确地构造以模拟导出的函数,因此子
bash
x
的整个值计算为“导入”函数,但也要按照函数定义执行代码。

Bash将环境变量识别为函数,如果它恰好以四个字符开头,包括空格。因此
env x='(){:;};echo vulnerable'
不计算在内

这与您在
bash
中定义函数时使用的语法不完全一致;在内部,
bash
将以规范化形式存储函数的字符串表示形式。如果导出函数(使用
export-f function_name
),然后将规范化表单添加到环境中,子
bash
进程将其识别为函数定义

“shellshock”bug来自
bash
处理已识别函数的方式;
bash
的bug版本(可以追溯到很久以前)只是将环境中的字符串作为函数定义进行评估(通过将变量名作为函数名进行前置),它会受到漏洞测试中演示的注入攻击


手动创建类似于
bash
函数定义的字符串,以便在子
bash
进程中定义函数,这是一种已知的技术。导出函数并重新导入它们是非常常见的,用户通常甚至没有注意到。(例如,此技术用于将bash函数传递到由
xargs bash-c
find…-exec bash-c
启动的子shell)

您是否正在运行cgi bash脚本?我想不是吧?我只是想理解为什么第二条语句会显示“易受攻击”而第一个没有。有趣的是,我从没想过像
foo()(echo-bar)
这样的东西是如何导出的;它是
foo=(){(echo-bar)
。是的,我清楚地看到了这种特殊性。但是我认为当你有带分隔符的块声明时,空格不会有太多的作用。我的意思是,通常在bash脚本中,我会让
foo()\n{do\u something}
毫无问题地工作…@chepner:The
{…}
是由bash隐式添加的。Posix允许任何复合命令,但
bash
将所有函数定义转换为大括号包围的形式。@Marcel:您不需要在
{
前面键入带空格的函数定义(而且换行符是空格)但是bash在内部对文本进行了规范化。我正在查看
env | grep foo
的输出,它当然省略了包含尾随大括号的第二行输出。