在阅读了最新的bash
漏洞后,我想知道 Tavis Ormandy 的漏洞是如何工作的。怎样(a)=>\
运作?
他发帖称:
bash 补丁对我来说似乎不完整,函数解析仍然很脆弱。例如
$ env X='() { (a)=>\' sh -c "echo date"; cat echo
答案1
GNU Bash 导出外壳函数在包含函数定义的环境变量中:
$ function foo { echo bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() { echo bar
}
当生成新的 Bash 实例时,它会查找与特定模式匹配的环境变量。这些变量的内容是自动地作为 shell 函数导入。作为斯蒂芬·查泽拉斯解释道=
,由于此功能是在 Bash 1.03 中引入的,因此只需将相应条目中的替换即可完成函数的导入环境变量数组,并将结果解释为函数定义。之前补丁那个固定的CVE-2014-6271,环境变量被完整解释,包括跟随实际函数体的任何命令。该补丁为该parse_and_execute()
功能引入了两种特殊模式,SEVAL_FUNCDEF
和SEVAL_ONECMD
。当使用 调用该函数时SEVAL_FUNCDEF
,应该阻止解释除函数定义之外的命令。该SEVAL_ONECMD
标志应该防止函数评估多个命令。
Tavis Ormandy 特制的环境变量做了一些微妙的不同的事情。它旨在混淆解析器并破坏用于存储要评估的命令的缓冲区。缓冲区中环境变量的残余部分更改后续命令的解释。此相关问题已收到 CVE 标识符CVE-2014-7169。
环境变量定义的组成部分X='() { (a)=>\'
是:
() {
解析器将其解释为函数定义的开头(a)=
旨在迷惑解析器并导致其在缓冲区中留下环境变量的残余部分>\
是留在缓冲区中的实际有效负载
有效负载的目的是更改在 调用的子 shell 中执行的命令的解释sh -c "echo date";
。当然,这假设这/bin/sh
是到 的符号链接bash
。当指定为操作数的命令字符串-c
放入缓冲区时,缓冲区的内容为:
>\[0xA]echo date
是[0xA]
一个 ASCII 换行符,通常用作命令分隔符,但现在由\
有效负载中的 转义。结果,缓冲区的内容被解释为
>echo date
因为Bash 允许重定向运算符位于命令之前,这相当于
date > echo
这只会导致date
命令执行时其标准输出重定向到名为echo
.剩下的cat echo
不是漏洞利用的一部分,它只是表明现在存在一个名为echo
包含输出的文件date
。
至于为什么(a)=
在这种情况下字符串会混淆解析器,它似乎与它作为(格式错误的)嵌套函数定义出现有关。这该漏洞利用的简化变体更清楚地证明了这一点:
$ X='() { function a a>\' bash -c echo
$ ls echo
echo