我在检查Shellshock漏洞时得到了这个:
host1:~$ env x='(){ :;}; echo vulnerable' bash -c "echo hello"
hello
host1:~$ env x='() { :;}; echo vulnerable' bash -c "echo hello"
vulnerable
hello
host1:~$
很奇怪吧?
我在检查Shellshock漏洞时得到了这个:
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
;中定义函数时使用的语法。在内部,bash
将以标准化形式存储函数的字符串表示形式。如果函数被导出(带有export -f function_name
),那么规范化的形式会被添加到环境中,并且子bash
进程会将其识别为函数定义。
“shellshock”错误来自bash
处理识别功能的方式;有缺陷的版本bash
(可以追溯到很久以前)只是将环境中的字符串评估为函数定义(通过将变量的名称作为函数名称的前缀),这会受到漏洞测试中所示的注入攻击.
手动创建看起来像bash
函数定义的字符串以便在子bash
进程中定义函数是一种已知技术。导出函数并重新导入它们是很常见的,甚至常常不会被用户注意到。(例如,此技术用于将 bash 函数传递到以xargs bash -c
和开头的子shell find ... -exec bash -c
。)
bash
对它认为环境中的嵌入式函数定义有点挑剔。在第一
env x='(){ :;}; echo vulnerable' bash -c "echo hello"}
()
和之间没有空格{
足以防止bash
将其识别为导出函数,因此它仍然是一个简单的 shell 变量;看,尝试运行
env x='(){ :;}; echo vulnerable' bash -c 'echo $x'
在第二个示例中x
,带有空格的 的值被正确地制作以模仿导出的函数,因此孩子bash
评估整个值x
以“导入”函数,但也执行函数定义之后的代码。