一、什么是命令注入?
即 Command Injection,是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。
此攻击与代码注入不同,因为代码注入允许攻击者添加自己的代码,然后由应用程序执行。 在命令注入中,攻击者扩展了执行系统命令的应用程序的默认功能,而无需注入代码。
注入原理:
黑客将构造好的命令发送给web服务器,服务器根据拼接命令执行注入的命令,最后将结果显示给黑客。
在Web应用中,有时候会用到一些命令执行的函数,如php中system、exec、shell_exec、passthru等,当对用户输入的命令没有进行限制或者过滤不严导致用户可以执行任意命令时,就会造成命令执行漏洞。
1.1、system()
执行外部程序,并且显示输出
test.php内容如下:
<?php
$whoami=system('whoami',$retval);
echo $retval; //外部命令执行后的返回状态
?>
访问test.php,输出如下:
test.php内容如下:
<?php
$host= $argv[1];
system("ping ".$host);
?>
使用PHP执行php test.php www.baidu.com
如果恶意攻击者输入以下命令php test1.php '|ls',则会造成任意命令执行:
1.2、 exec()
执行一个外部程序
test.php内容如下:
<?php
//输出运行中的php/httpd进程的创建者用户名
//(在可以执行"whoami"命令的系统上)
echo exec('whoami');
?>
访问test.php,输出如下:
1.3、 shell_exec()
通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
test.php内容如下:
<?php
$output=shell_exec('ls');
echo"<pre>$output</pre>";
?>
访问test.php,输出如下:
1.4、 passthru()
passthru() 函数与 exec() 函数类似,执行外部程序并且显示原始输出。
1.5、 popen()
打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
popen ( string $command , string $mode ) : resource
参数:
command:命令。
mode:模式。
二、命令注入的防御措施
采用白名单,或使用正则表达式进行过滤。
对输入不要让用户可以直接控制eval()、system、exec、shell_exec等函数的参数。
在进入执行命令函数和方法前,对变量进行过滤,对敏感字符进行转义。
三、绕过及技巧
3.1、命令拼接符
|:管道符,将一条命令的标准输出作为另一条命令的标准输入
&:后台任务符,命令从左到右执行,无论执行成功或失败,使命令在后台执行
&&: 逻辑与,只有前面的命令执行成功了,才会执行下一条命令
||: 逻辑或,只有前面的命令执行失败了,才会执行下一条命令
;: 分号,linux特有,从左到右按顺序执行命令(linux)
反斜杠:c\at fl\ag
3.2、特殊技巧
`: 反引号,当命令被解析时,会先执行反引号里的命令(linux),例如ping -c 4 127.0.0.1`sleep 6`
$(command): 命令替换(linux)
$IFS: 特殊变量,默认值为:空白(包括:空格,tab, 和新行)。并不是所有shell都支持
*/?: 通配符,可以利用通配符cat */passwd
[]/{}: 正则的范围,cat e[a-z]c/passwd 、cat e{t,c}c/passwd
利用变量:a=ca;b=t;c=/etc/passwd $a$b $c
使用编码:echo "base64" | base64 -d | bash
%1a - 一个神奇的角色,作为.bat文件中的命令分隔符
拼接:(sy.(st).em)(whoami)
四、dvwa中演示Command Injection
环境:
dvwa: 192.168.11.135 dvwa版本: Version 1.9 (Release date: 2015-09-19)
kail机器:192.168.11.156
4.1、LOW级别
代码:
输入:127.0.0.1,返回如下
若是出现乱码,修改/var/www/html/dvwa/includes/dvwaPage.inc.php,将 utf-8 全部替换成 gb2312。
输入:127.0.0.1&ifconfig,返回如下
输入:127.0.0.1 && dir,返回如下
4.2、Medium级别
代码:设置了黑名单 将 && 和 ;进行了转义。可以用 & 或 | 绕过
输入:127.0.0.1&ifconfig 或者 127.0.0.1 & ifconfig 或者 127.0.0.1 & dir
4.3、High级别
代码:设置的黑名单更详细,但是仔细看上面转义的字符 发现 | 后面有个空格
输入:127.0.0.1|ifconfig 或者 127.0.0.1 || ifconfig