在阅读了最新的bash漏洞后,我想知道 Tavis Ormandy 的漏洞利用是如何工作的。如何(a)=>\工作?
他发帖说:
bash 补丁对我来说似乎不完整,函数解析仍然很脆弱。例如
Run Code Online (Sandbox Code Playgroud)$ env X='() { (a)=>\' sh -c "echo date"; cat echo
GNU Bash在环境变量中导出shell 函数,其中包括函数定义:
$ function foo { echo bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() { echo bar
}
Run Code Online (Sandbox Code Playgroud)
当一个新的 Bash 实例产生时,它会寻找匹配特定模式的环境变量。这些变量的内容会自动导入为 shell 函数。正如Stéphane Chazelas 解释的那样,由于此功能是在 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
Run Code Online (Sandbox Code Playgroud)
的[0xA]是一个ASCII换行字符,这将通常作为命令分隔符,但现在由逃脱\从有效载荷。结果,缓冲区的内容被解释为
>echo date
Run Code Online (Sandbox Code Playgroud)
因为Bash 允许重定向运算符位于命令之前,所以这等效于
date > echo
Run Code Online (Sandbox Code Playgroud)
这只会导致执行date命令并将其标准输出重定向到名为echo. 剩下cat echo的不是漏洞利用的一部分,它只是表明现在一个echo包含输出的名为的文件date存在。
至于为什么(a)=在这种情况下字符串会混淆解析器,它似乎与它显示为(格式错误的)嵌套函数定义有关。漏洞利用的简化变体更清楚地展示了这一点:
$ X='() { function a a>\' bash -c echo
$ ls echo
echo
Run Code Online (Sandbox Code Playgroud)