`env X='() { (a)=>\' sh -c "echo date"` 是如何工作的?

`env X='() { (a)=>\' sh -c "echo date"` 是如何工作的?

在阅读了最新的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_FUNCDEFSEVAL_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

相关内容