最近的一个漏洞,CVE-2014-6271 ,如何Bash解释环境变量 was disclosed .该漏洞利用依赖于 Bash 将一些环境变量声明解析为函数定义,然后继续按照定义执行代码:
$ x='() { echo i do nothing; }; echo vulnerable' bash -c ':'
vulnerable
但是我不明白。我在 Bash 手册中找不到任何关于将环境变量解释为函数的内容(除了继承函数,这是不同的)。事实上,一个正确的命名函数定义只是被当作一个值:
$ x='y() { :; }' bash -c 'echo $x'
y() { :; }
但是一个损坏的不打印任何东西:
$ x='() { :; }' bash -c 'echo $x'
$ # Nothing but newline
损坏的函数未命名,所以我不能直接调用它。这个漏洞是纯粹的实现错误,还是这里有我看不到的预期功能?
更新
根据 Barmar 的评论,我假设函数的名称是参数名称:
$ n='() { echo wat; }' bash -c 'n'
wat
我可以发誓我以前尝试过,但我想我尝试得还不够努力。现在可以重复了。这里还有一些测试:
$ env n='() { echo wat; }; echo vuln' bash -c 'n'
vuln
wat
$ env n='() { echo wat; }; echo $1' bash -c 'n 2' 3 -- 4
wat
...很明显,在执行漏洞利用时未设置 args。
无论如何,我的问题的基本答案是,是的,这就是 Bash 实现继承函数的方式。
最佳答案
这似乎是一个实现错误。
显然,导出函数在 bash
中的工作方式是它们使用特殊格式的环境变量。如果导出函数:
f() { ... }
它定义了一个环境变量,例如:
f='() { ... }'
可能发生的情况是,当新的 shell 发现一个值以 ()
开头的环境变量时,它会在变量名前添加并执行结果字符串。错误在于,这还包括在函数定义之后执行任何操作。
所描述的修复显然是为了解析结果以查看它是否是有效的函数定义。如果不是,它会打印有关无效函数定义尝试的警告。
This article证实了我对错误原因的解释。它还详细介绍了修复程序如何解决它:它们不仅更仔细地解析值,而且用于传递导出函数的变量遵循特殊的命名约定。此命名约定与为 CGI 脚本创建的环境变量所使用的命名约定不同,因此 HTTP 客户端永远不能涉足这扇门。
关于bash - Bash 中的 Shellshock 漏洞背后的行为是记录在案还是完全是故意的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26022248/